1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include <data/case.h>
26 #include <libpspp/i18n.h>
27 #include <libpspp/integer-format.h>
28 #include <libpspp/message.h>
34 #define _(msgid) gettext (msgid)
36 static int global_algorithm = ENHANCED;
40 /* Integer format used for IB and PIB input. */
41 enum integer_format input_integer_format;
43 /* Floating-point format used for RB and RBHEX input. */
44 enum float_format input_float_format;
46 /* Format of integers in output (SET WIB). */
47 enum integer_format output_integer_format;
49 /* Format of reals in output (SET WRB). */
50 enum float_format output_float_format;
57 bool route_errors_to_terminal;
58 bool route_errors_to_listing;
62 int max_messages[MSG_N_SEVERITIES];
69 struct fmt_spec default_format;
76 struct fmt_number_style *styles;
78 enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
81 static struct settings the_settings = {
82 /* input_integer_format */
84 /* input_float_format */
86 /* output_integer_format */
88 /* output_float_format */
100 /* route_errors_to_terminal */
102 /* route_errors_to_listing */
112 100, /* MSG_S_ERROR */
113 100, /* MSG_S_WARNING */
141 {SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
142 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
144 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL}
147 static void init_viewport ( int *, int *);
150 settings_init (int *width, int *length)
152 init_viewport (width, length);
153 settings_set_epoch (-1);
154 the_settings.styles = fmt_create ();
156 settings_set_decimal_char (get_system_decimal ());
162 fmt_done (the_settings.styles);
165 /* Returns the floating-point format used for RB and RBHEX
168 settings_get_input_float_format (void)
170 return the_settings.input_float_format;
173 /* Sets the floating-point format used for RB and RBHEX input to
176 settings_set_input_float_format ( enum float_format format)
178 the_settings.input_float_format = format;
181 /* Returns the integer format used for IB and PIB input. */
183 settings_get_input_integer_format (void)
185 return the_settings.input_integer_format;
188 /* Sets the integer format used for IB and PIB input to
191 settings_set_input_integer_format ( enum integer_format format)
193 the_settings.input_integer_format = format;
196 /* Returns the current output integer format. */
198 settings_get_output_integer_format (void)
200 return the_settings.output_integer_format;
203 /* Sets the output integer format to INTEGER_FORMAT. */
205 settings_set_output_integer_format (
206 enum integer_format integer_format)
208 the_settings.output_integer_format = integer_format;
211 /* Returns the current output float format. */
213 settings_get_output_float_format (void)
215 return the_settings.output_float_format;
218 /* Sets the output float format to FLOAT_FORMAT. */
220 settings_set_output_float_format ( enum float_format float_format)
222 the_settings.output_float_format = float_format;
225 /* Screen length in lines. */
227 settings_get_viewlength (void)
229 return *the_settings.viewlength;
232 /* Sets the view length. */
234 settings_set_viewlength ( int viewlength_)
236 *the_settings.viewlength = viewlength_;
241 settings_get_viewwidth(void)
243 return *the_settings.viewwidth;
246 /* Sets the screen width. */
248 settings_set_viewwidth ( int viewwidth_)
250 *the_settings.viewwidth = viewwidth_;
254 init_viewport ( int *width, int *length)
256 the_settings.viewwidth = width;
257 the_settings.viewlength = length;
260 /* Whether PSPP can erase and overwrite files. */
262 settings_get_safer_mode (void)
264 return the_settings.safer_mode;
267 /* Set safer mode. */
269 settings_set_safer_mode (void)
271 the_settings.safer_mode = true;
274 /* If echo is on, whether commands from include files are echoed. */
276 settings_get_include (void)
278 return the_settings.include;
281 /* Set include file echo. */
283 settings_set_include ( bool include)
285 the_settings.include = include;
288 /* What year to use as the start of the epoch. */
290 settings_get_epoch (void)
292 assert (the_settings.epoch >= 0);
294 return the_settings.epoch;
297 /* Sets the year that starts the epoch. */
299 settings_set_epoch ( int epoch)
304 struct tm *tm = localtime (&t);
305 epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
308 the_settings.epoch = epoch;
309 assert (the_settings.epoch >= 0);
312 /* Compress system files by default? */
314 settings_get_scompression (void)
316 return the_settings.scompress;
319 /* Set system file default compression. */
321 settings_set_scompression ( bool scompress)
323 the_settings.scompress = scompress;
326 /* Whether to warn on undefined values in numeric data. */
328 settings_get_undefined (void)
330 return the_settings.undefined;
333 /* Set whether to warn on undefined values. */
335 settings_set_undefined ( bool undefined)
337 the_settings.undefined = undefined;
340 /* The value that blank numeric fields are set to when read in. */
342 settings_get_blanks (void)
344 return the_settings.blanks;
347 /* Set the value that blank numeric fields are set to when read
350 settings_set_blanks ( double blanks)
352 the_settings.blanks = blanks;
355 /* Returns the maximum number of messages to show of the given SEVERITY before
356 aborting. (The value for MSG_S_WARNING is interpreted as maximum number of
357 warnings and errors combined.) */
359 settings_get_max_messages (enum msg_severity severity)
361 assert (severity < MSG_N_SEVERITIES);
362 return the_settings.max_messages[severity];
365 /* Sets the maximum number of messages to show of the given SEVERITY before
366 aborting to MAX. (The value for MSG_S_WARNING is interpreted as maximum
367 number of warnings and errors combined.) In addition, in the case of
368 warnings the special value of zero indicates that no warnings are to be
372 settings_set_max_messages (enum msg_severity severity, int max)
374 assert (severity < MSG_N_SEVERITIES);
376 if (severity == MSG_S_WARNING)
381 _("MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered."));
382 msg_ui_disable_warnings (true);
384 else if ( the_settings.max_messages [MSG_S_WARNING] == 0)
386 msg_ui_disable_warnings (false);
387 the_settings.max_messages[MSG_S_WARNING] = max;
388 msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
392 the_settings.max_messages[severity] = max;
395 /* Independent of get_printback, controls whether the commands
396 generated by macro invocations are displayed. */
398 settings_get_mprint (void)
400 return the_settings.mprint;
403 /* Sets whether the commands generated by macro invocations are
406 settings_set_mprint ( bool mprint)
408 the_settings.mprint = mprint;
411 /* Implied limit of unbounded loop. */
413 settings_get_mxloops (void)
415 return the_settings.mxloops;
418 /* Set implied limit of unbounded loop. */
420 settings_set_mxloops ( int mxloops)
422 the_settings.mxloops = mxloops;
425 /* Whether a blank line is a command terminator. */
427 settings_get_nulline (void)
429 return the_settings.nulline;
432 /* Set whether a blank line is a command terminator. */
434 settings_set_nulline ( bool nulline)
436 the_settings.nulline = nulline;
439 /* The character used to terminate commands. */
441 settings_get_endcmd (void)
443 return the_settings.endcmd;
446 /* Set the character used to terminate commands. */
448 settings_set_endcmd ( char endcmd)
450 the_settings.endcmd = endcmd;
453 /* Approximate maximum amount of memory to use for cases, in
456 settings_get_workspace (void)
458 return the_settings.workspace;
461 /* Approximate maximum number of cases to allocate in-core, given
462 that each case has the format given in PROTO. */
464 settings_get_workspace_cases (const struct caseproto *proto)
466 size_t n_cases = settings_get_workspace () / case_get_cost (proto);
467 return MAX (n_cases, 4);
470 /* Set approximate maximum amount of memory to use for cases, in
474 settings_set_workspace ( size_t workspace)
476 the_settings.workspace = workspace;
479 /* Default format for variables created by transformations and by
480 DATA LIST {FREE,LIST}. */
481 const struct fmt_spec *
482 settings_get_format (void)
484 return &the_settings.default_format;
487 /* Set default format for variables created by transformations
488 and by DATA LIST {FREE,LIST}. */
490 settings_set_format ( const struct fmt_spec *default_format)
492 the_settings.default_format = *default_format;
495 /* Are we in testing mode? (e.g. --testing-mode command line
498 settings_get_testing_mode (void)
500 return the_settings.testing_mode;
503 /* Set testing mode. */
505 settings_set_testing_mode ( bool testing_mode)
507 the_settings.testing_mode = testing_mode;
510 /* Return the current algorithm setting */
512 settings_get_algorithm (void)
514 return *the_settings.algorithm;
517 /* Set the algorithm option globally. */
519 settings_set_algorithm (enum behavior_mode mode)
521 global_algorithm = mode;
524 /* Set the algorithm option for this command only */
526 settings_set_cmd_algorithm ( enum behavior_mode mode)
528 the_settings.cmd_algorithm = mode;
529 the_settings.algorithm = &the_settings.cmd_algorithm;
532 /* Unset the algorithm option for this command */
534 unset_cmd_algorithm (void)
536 the_settings.algorithm = &global_algorithm;
539 /* Get the current syntax setting */
541 settings_get_syntax (void)
543 return the_settings.syntax;
546 /* Set the syntax option */
548 settings_set_syntax ( enum behavior_mode mode)
550 the_settings.syntax = mode;
555 /* Find the grouping characters in CC_STRING and set CC's
556 grouping and decimal members appropriately. Returns true if
557 successful, false otherwise. */
559 find_cc_separators (const char *cc_string, struct fmt_number_style *cc)
562 int comma_cnt, dot_cnt;
564 /* Count commas and periods. There must be exactly three of
565 one or the other, except that an apostrophe escapes a
566 following comma or period. */
567 comma_cnt = dot_cnt = 0;
568 for (sp = cc_string; *sp; sp++)
573 else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
576 if ((comma_cnt == 3) == (dot_cnt == 3))
592 /* Extracts a token from IN into a newly allocated AFFIX. Tokens
593 are delimited by GROUPING. The token is truncated to at most
594 FMT_STYLE_AFFIX_MAX characters. Returns the first character
595 following the token. */
597 extract_cc_token (const char *in, int grouping, struct substring *affix)
600 ss_alloc_uninit (affix, FMT_STYLE_AFFIX_MAX);
601 for (; *in != '\0' && *in != grouping; in++)
603 if (*in == '\'' && in[1] == grouping)
605 if (ofs < FMT_STYLE_AFFIX_MAX)
606 ss_data (*affix)[ofs++] = *in;
616 /* Sets custom currency specifier CC having name CC_NAME ('A' through
617 'E') to correspond to the settings in CC_STRING. */
619 settings_set_cc (const char *cc_string, enum fmt_type type)
621 struct fmt_number_style *cc = &the_settings.styles[type];
623 assert (fmt_get_category (type) == FMT_CAT_CUSTOM);
625 /* Determine separators. */
626 if (!find_cc_separators (cc_string, cc))
628 msg (SE, _("%s: Custom currency string `%s' does not contain "
629 "exactly three periods or commas (or it contains both)."),
630 fmt_name (type), cc_string);
634 cc_string = extract_cc_token (cc_string, cc->grouping, &cc->neg_prefix);
635 cc_string = extract_cc_token (cc_string, cc->grouping, &cc->prefix);
636 cc_string = extract_cc_token (cc_string, cc->grouping, &cc->suffix);
637 cc_string = extract_cc_token (cc_string, cc->grouping, &cc->neg_suffix);
639 fmt_check_style (cc);
644 /* Returns the decimal point character for TYPE. */
646 settings_get_decimal_char (enum fmt_type type)
648 return fmt_get_style (the_settings.styles, type)->decimal;
652 settings_set_decimal_char (char decimal)
654 fmt_set_decimal (the_settings.styles, decimal);
659 /* Returns the number formatting style associated with the given
661 const struct fmt_number_style *
662 settings_get_style (enum fmt_type type)
664 assert (is_fmt_type (type));
665 return &the_settings.styles[type];
669 /* Returns a string of the form "$#,###.##" according to FMT,
670 which must be of type FMT_DOLLAR. The caller must free the
673 settings_dollar_template (const struct fmt_spec *fmt)
675 const struct fmt_number_style *styles = the_settings.styles;
676 struct string str = DS_EMPTY_INITIALIZER;
678 const struct fmt_number_style *fns ;
680 assert (fmt->type == FMT_DOLLAR);
682 fns = fmt_get_style (styles, fmt->type);
684 ds_put_char (&str, '$');
685 for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0; )
687 ds_put_char (&str, '#');
688 if (--c % 4 == 0 && c > 0)
690 ds_put_char (&str, fns->grouping);
696 ds_put_char (&str, fns->decimal);
697 ds_put_char_multiple (&str, '#', fmt->d);
700 return ds_cstr (&str);
704 settings_set_output_routing (enum settings_output_type type,
705 enum settings_output_devices devices)
707 assert (type < SETTINGS_N_OUTPUT_TYPES);
708 the_settings.output_routing[type] = devices;
711 enum settings_output_devices
712 settings_get_output_routing (enum settings_output_type type)
714 assert (type < SETTINGS_N_OUTPUT_TYPES);
715 return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;