+void
+settings_set_syntax ( enum behavior_mode mode)
+{
+ the_settings.syntax = mode;
+}
+
+\f
+
+/* Find the grouping characters in CC_STRING and set CC's
+ grouping and decimal members appropriately. Returns true if
+ successful, false otherwise. */
+static bool
+find_cc_separators (const char *cc_string, struct fmt_number_style *cc)
+{
+ const char *sp;
+ int comma_cnt, dot_cnt;
+
+ /* Count commas and periods. There must be exactly three of
+ one or the other, except that an apostrophe escapes a
+ following comma or period. */
+ comma_cnt = dot_cnt = 0;
+ for (sp = cc_string; *sp; sp++)
+ if (*sp == ',')
+ comma_cnt++;
+ else if (*sp == '.')
+ dot_cnt++;
+ else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
+ sp++;
+
+ if ((comma_cnt == 3) == (dot_cnt == 3))
+ return false;
+
+ if (comma_cnt == 3)
+ {
+ cc->decimal = '.';
+ cc->grouping = ',';
+ }
+ else
+ {
+ cc->decimal = ',';
+ cc->grouping = '.';
+ }
+ return true;
+}
+
+/* Extracts a token from IN into AFFIX, using BUFFER for storage. BUFFER must
+ have at least FMT_STYLE_AFFIX_MAX + 1 bytes of space. Tokens are delimited
+ by GROUPING. The token is truncated to at most FMT_STYLE_AFFIX_MAX bytes,
+ followed by a null terminator. Returns the first character following the
+ token. */
+static const char *
+extract_cc_token (const char *in, int grouping, struct substring *affix,
+ char buffer[FMT_STYLE_AFFIX_MAX + 1])
+{
+ size_t ofs = 0;
+
+ for (; *in != '\0' && *in != grouping; in++)
+ {
+ if (*in == '\'' && in[1] == grouping)
+ in++;
+ if (ofs < FMT_STYLE_AFFIX_MAX)
+ buffer[ofs++] = *in;
+ }
+ *affix = ss_buffer (buffer, ofs);
+
+ if (*in == grouping)
+ in++;
+ return in;
+}
+
+/* Sets custom currency specifier CC having name CC_NAME ('A' through
+ 'E') to correspond to the settings in CC_STRING. */
+bool
+settings_set_cc (const char *cc_string, enum fmt_type type)
+{
+ char a[FMT_STYLE_AFFIX_MAX + 1];
+ char b[FMT_STYLE_AFFIX_MAX + 1];
+ char c[FMT_STYLE_AFFIX_MAX + 1];
+ char d[FMT_STYLE_AFFIX_MAX + 1];
+ struct fmt_number_style cc;
+
+ assert (fmt_get_category (type) == FMT_CAT_CUSTOM);
+
+ /* Determine separators. */
+ if (!find_cc_separators (cc_string, &cc))
+ {
+ msg (SE, _("%s: Custom currency string `%s' does not contain "
+ "exactly three periods or commas (or it contains both)."),
+ fmt_name (type), cc_string);
+ return false;
+ }
+
+ cc_string = extract_cc_token (cc_string, cc.grouping, &cc.neg_prefix, a);
+ cc_string = extract_cc_token (cc_string, cc.grouping, &cc.prefix, b);
+ cc_string = extract_cc_token (cc_string, cc.grouping, &cc.suffix, c);
+ cc_string = extract_cc_token (cc_string, cc.grouping, &cc.neg_suffix, d);
+
+ fmt_settings_set_style (the_settings.styles, type, &cc);
+
+ return true;
+}
+
+/* Returns the decimal point character for TYPE. */
+int
+settings_get_decimal_char (enum fmt_type type)
+{
+ return fmt_settings_get_style (the_settings.styles, type)->decimal;
+}
+
+void
+settings_set_decimal_char (char decimal)
+{
+ fmt_settings_set_decimal (the_settings.styles, decimal);
+}
+
+/* Returns the number formatting style associated with the given
+ format TYPE. */
+const struct fmt_number_style *
+settings_get_style (enum fmt_type type)
+{
+ assert (is_fmt_type (type));
+ return fmt_settings_get_style (the_settings.styles, type);
+}
+
+/* Returns a string of the form "$#,###.##" according to FMT,
+ which must be of type FMT_DOLLAR. The caller must free the
+ string. */
+char *
+settings_dollar_template (const struct fmt_spec *fmt)
+{
+ struct string str = DS_EMPTY_INITIALIZER;
+ int c;
+ const struct fmt_number_style *fns ;
+
+ assert (fmt->type == FMT_DOLLAR);
+
+ fns = fmt_settings_get_style (the_settings.styles, fmt->type);
+
+ ds_put_char (&str, '$');
+ for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0; )
+ {
+ ds_put_char (&str, '#');
+ if (--c % 4 == 0 && c > 0)
+ {
+ ds_put_char (&str, fns->grouping);
+ --c;
+ }
+ }
+ if (fmt->d > 0)
+ {
+ ds_put_char (&str, fns->decimal);
+ ds_put_char_multiple (&str, '#', fmt->d);
+ }
+
+ return ds_cstr (&str);
+}
+
+void
+settings_set_output_routing (enum settings_output_type type,
+ enum settings_output_devices devices)
+{
+ assert (type < SETTINGS_N_OUTPUT_TYPES);
+ the_settings.output_routing[type] = devices;
+}
+
+enum settings_output_devices
+settings_get_output_routing (enum settings_output_type type)