1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2015 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/>. */
19 #include "data/settings.h"
24 #include "data/case.h"
25 #include "data/format.h"
26 #include "data/value.h"
27 #include "libpspp/i18n.h"
28 #include "libpspp/integer-format.h"
29 #include "libpspp/message.h"
31 #include "gl/minmax.h"
32 #include "gl/xalloc.h"
35 #define _(msgid) gettext (msgid)
39 /* Integer format used for IB and PIB input. */
40 enum integer_format input_integer_format;
42 /* Floating-point format used for RB and RBHEX input. */
43 enum float_format input_float_format;
45 /* Format of integers in output (SET WIB). */
46 enum integer_format output_integer_format;
48 /* Format of reals in output (SET WRB). */
49 enum float_format output_float_format;
55 bool route_errors_to_terminal;
56 bool route_errors_to_listing;
60 int max_messages[MSG_N_SEVERITIES];
64 bool mexpand; /* Expand macros? */
65 bool mprint; /* Print macro expansions? */
66 int miterate; /* Maximum iterations of !FOR. */
67 int mnest; /* Maximum nested macro expansion levels. */
71 struct fmt_spec default_format;
79 struct fmt_settings styles;
82 enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
84 enum settings_value_show show_values;
85 enum settings_value_show show_variables;
88 static struct settings the_settings = {
89 .input_integer_format = INTEGER_NATIVE,
90 .input_float_format = FLOAT_NATIVE_DOUBLE,
91 .output_integer_format = INTEGER_NATIVE,
92 .output_float_format = FLOAT_NATIVE_DOUBLE,
97 .route_errors_to_terminal = true,
98 .route_errors_to_listing = true,
105 [MSG_S_WARNING] = 100,
117 .workspace = 64L * 1024 * 1024,
118 .default_format = { .type = FMT_F, .w = 8, .d = 2 },
119 .testing_mode = false,
121 .cmd_algorithm = ENHANCED,
122 .global_algorithm = ENHANCED,
124 .styles = FMT_SETTINGS_INIT,
129 #define LT (SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL)
130 [SETTINGS_OUTPUT_ERROR] = LT,
131 [SETTINGS_OUTPUT_NOTE] = LT,
132 [SETTINGS_OUTPUT_SYNTAX] = 0,
133 [SETTINGS_OUTPUT_RESULT] = LT
137 .show_values = SETTINGS_VALUE_SHOW_LABEL,
138 .show_variables = SETTINGS_VALUE_SHOW_LABEL,
141 /* Initializes the settings module. */
145 settings_set_decimal_char (get_system_decimal ());
148 /* Cleans up the settings module. */
152 settings_destroy (&the_settings);
156 settings_copy (struct settings *dst, const struct settings *src)
159 dst->styles = fmt_settings_copy (&src->styles);
162 /* Returns a copy of the current settings. */
166 struct settings *s = xmalloc (sizeof *s);
167 settings_copy (s, &the_settings);
171 /* Replaces the current settings by those in S. The caller retains ownership
174 settings_set (const struct settings *s)
176 settings_destroy (&the_settings);
177 settings_copy (&the_settings, s);
182 settings_destroy (struct settings *s)
186 fmt_settings_uninit (&s->styles);
187 if (s != &the_settings)
192 /* Returns the floating-point format used for RB and RBHEX
195 settings_get_input_float_format (void)
197 return the_settings.input_float_format;
200 /* Sets the floating-point format used for RB and RBHEX input to
203 settings_set_input_float_format (enum float_format format)
205 the_settings.input_float_format = format;
208 /* Returns the integer format used for IB and PIB input. */
210 settings_get_input_integer_format (void)
212 return the_settings.input_integer_format;
215 /* Sets the integer format used for IB and PIB input to
218 settings_set_input_integer_format (enum integer_format format)
220 the_settings.input_integer_format = format;
223 /* Returns the current output integer format. */
225 settings_get_output_integer_format (void)
227 return the_settings.output_integer_format;
230 /* Sets the output integer format to INTEGER_FORMAT. */
232 settings_set_output_integer_format (
233 enum integer_format integer_format)
235 the_settings.output_integer_format = integer_format;
238 /* Returns the current output float format. */
240 settings_get_output_float_format (void)
242 return the_settings.output_float_format;
245 /* Sets the output float format to FLOAT_FORMAT. */
247 settings_set_output_float_format (enum float_format float_format)
249 the_settings.output_float_format = float_format;
252 /* Screen length in lines. */
254 settings_get_viewlength (void)
256 return the_settings.viewlength;
259 /* Sets the view length. */
261 settings_set_viewlength (int viewlength_)
263 the_settings.viewlength = viewlength_;
268 settings_get_viewwidth(void)
270 return the_settings.viewwidth;
273 /* Sets the screen width. */
275 settings_set_viewwidth (int viewwidth_)
277 the_settings.viewwidth = viewwidth_;
280 /* Whether PSPP can erase and overwrite files. */
282 settings_get_safer_mode (void)
284 return the_settings.safer_mode;
287 /* Set safer mode. */
289 settings_set_safer_mode (void)
291 the_settings.safer_mode = true;
294 /* If echo is on, whether commands from include files are echoed. */
296 settings_get_include (void)
298 return the_settings.include;
301 /* Set include file echo. */
303 settings_set_include (bool include)
305 the_settings.include = include;
308 /* Returns the year that starts the epoch. */
310 settings_get_epoch (void)
312 return the_settings.styles.epoch;
315 /* Sets the year that starts the epoch. */
317 settings_set_epoch (int epoch)
319 the_settings.styles.epoch = epoch;
322 /* Compress system files by default? */
324 settings_get_scompression (void)
326 return the_settings.scompress;
329 /* Set system file default compression. */
331 settings_set_scompression (bool scompress)
333 the_settings.scompress = scompress;
336 /* Whether to warn on undefined values in numeric data. */
338 settings_get_undefined (void)
340 return the_settings.undefined;
343 /* Set whether to warn on undefined values. */
345 settings_set_undefined (bool undefined)
347 the_settings.undefined = undefined;
350 /* The value that blank numeric fields are set to when read in. */
352 settings_get_blanks (void)
354 return the_settings.blanks;
357 /* Set the value that blank numeric fields are set to when read
360 settings_set_blanks (double blanks)
362 the_settings.blanks = blanks;
365 /* Returns the maximum number of messages to show of the given SEVERITY before
366 aborting. (The value for MSG_S_WARNING is interpreted as maximum number of
367 warnings and errors combined.) */
369 settings_get_max_messages (enum msg_severity severity)
371 assert (severity < MSG_N_SEVERITIES);
372 return the_settings.max_messages[severity];
375 /* Sets the maximum number of messages to show of the given SEVERITY before
376 aborting to MAX. (The value for MSG_S_WARNING is interpreted as maximum
377 number of warnings and errors combined.) In addition, in the case of
378 warnings the special value of zero indicates that no warnings are to be
382 settings_set_max_messages (enum msg_severity severity, int max)
384 assert (severity < MSG_N_SEVERITIES);
386 if (severity == MSG_S_WARNING)
391 _("MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered."));
392 msg_ui_disable_warnings (true);
394 else if (the_settings.max_messages [MSG_S_WARNING] == 0)
396 msg_ui_disable_warnings (false);
397 the_settings.max_messages[MSG_S_WARNING] = max;
398 msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
402 the_settings.max_messages[severity] = max;
405 /* Returns whether to expand macro invocations. */
407 settings_get_mexpand (void)
409 return the_settings.mexpand;
412 /* Sets whether to expand macro invocations. */
414 settings_set_mexpand (bool mexpand)
416 the_settings.mexpand = mexpand;
419 /* Independent of get_printback, controls whether the commands
420 generated by macro invocations are displayed. */
422 settings_get_mprint (void)
424 return the_settings.mprint;
427 /* Sets whether the commands generated by macro invocations are
430 settings_set_mprint (bool mprint)
432 the_settings.mprint = mprint;
435 /* Returns the limit for loop iterations within a macro. */
437 settings_get_miterate (void)
439 return the_settings.miterate;
442 /* Sets the limit for loop iterations within a macro. */
444 settings_set_miterate (int miterate)
446 the_settings.miterate = miterate;
449 /* Returns the limit for recursion macro expansions. */
450 int settings_get_mnest (void)
452 return the_settings.mnest;
455 /* Sets the limit for recursion macro expansions. */
457 settings_set_mnest (int mnest)
459 the_settings.mnest = mnest;
462 int settings_get_mxloops (void);
463 void settings_set_mxloops (int);
464 /* Implied limit of unbounded loop. */
466 settings_get_mxloops (void)
468 return the_settings.mxloops;
471 /* Set implied limit of unbounded loop. */
473 settings_set_mxloops (int mxloops)
475 the_settings.mxloops = mxloops;
478 /* Approximate maximum amount of memory to use for cases, in
481 settings_get_workspace (void)
483 return the_settings.workspace;
486 /* Approximate maximum number of cases to allocate in-core, given
487 that each case has the format given in PROTO. */
489 settings_get_workspace_cases (const struct caseproto *proto)
491 size_t n_cases = settings_get_workspace () / case_get_cost (proto);
492 return MAX (n_cases, 4);
495 /* Set approximate maximum amount of memory to use for cases, in
499 settings_set_workspace (size_t workspace)
501 the_settings.workspace = workspace;
504 /* Default format for variables created by transformations and by
505 DATA LIST {FREE,LIST}. */
506 const struct fmt_spec *
507 settings_get_format (void)
509 return &the_settings.default_format;
512 /* Set default format for variables created by transformations
513 and by DATA LIST {FREE,LIST}. */
515 settings_set_format (const struct fmt_spec *default_format)
517 the_settings.default_format = *default_format;
520 /* Are we in testing mode? (e.g. --testing-mode command line
523 settings_get_testing_mode (void)
525 return the_settings.testing_mode;
528 /* Set testing mode. */
530 settings_set_testing_mode (bool testing_mode)
532 the_settings.testing_mode = testing_mode;
536 settings_get_fuzzbits (void)
538 return the_settings.fuzzbits;
542 settings_set_fuzzbits (int fuzzbits)
544 the_settings.fuzzbits = fuzzbits;
547 /* Return the current algorithm setting */
549 settings_get_algorithm (void)
551 return the_settings.cmd_algorithm;
554 /* Set the algorithm option globally. */
556 settings_set_algorithm (enum behavior_mode mode)
558 the_settings.global_algorithm = the_settings.cmd_algorithm = mode;
561 /* Set the algorithm option for this command only */
563 settings_set_cmd_algorithm (enum behavior_mode mode)
565 the_settings.cmd_algorithm = mode;
568 /* Unset the algorithm option for this command */
570 unset_cmd_algorithm (void)
572 the_settings.cmd_algorithm = the_settings.global_algorithm;
575 /* Get the current syntax setting */
577 settings_get_syntax (void)
579 return the_settings.syntax;
582 /* Set the syntax option */
584 settings_set_syntax (enum behavior_mode mode)
586 the_settings.syntax = mode;
590 /* Sets custom currency specifier CC having name CC_NAME ('A' through
591 'E') to correspond to the settings in CC_STRING. */
593 settings_set_cc (const char *cc_string, enum fmt_type type)
595 struct fmt_number_style *style = fmt_number_style_from_string (cc_string);
598 msg (SE, _("%s: Custom currency string `%s' does not contain "
599 "exactly three periods or commas (or it contains both)."),
600 fmt_name (type), cc_string);
604 fmt_settings_set_cc (&the_settings.styles, type, style);
609 settings_set_decimal_char (char decimal)
611 the_settings.styles.decimal = decimal;
614 const struct fmt_settings *
615 settings_get_fmt_settings (void)
617 return &the_settings.styles;
621 settings_get_small (void)
623 return the_settings.small;
627 settings_set_small (double small)
629 the_settings.small = small;
632 /* Returns a string of the form "$#,###.##" according to FMT,
633 which must be of type FMT_DOLLAR. The caller must free the
636 settings_dollar_template (const struct fmt_spec *fmt)
638 struct string str = DS_EMPTY_INITIALIZER;
640 const struct fmt_number_style *fns ;
642 assert (fmt->type == FMT_DOLLAR);
644 fns = fmt_settings_get_style (&the_settings.styles, fmt->type);
646 ds_put_byte (&str, '$');
647 for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0;)
649 ds_put_byte (&str, '#');
650 if (--c % 4 == 0 && c > 0)
652 ds_put_byte (&str, fns->grouping);
658 ds_put_byte (&str, fns->decimal);
659 ds_put_byte_multiple (&str, '#', fmt->d);
662 return ds_cstr (&str);
666 settings_set_output_routing (enum settings_output_type type,
667 enum settings_output_devices devices)
669 assert (type < SETTINGS_N_OUTPUT_TYPES);
670 the_settings.output_routing[type] = devices;
673 enum settings_output_devices
674 settings_get_output_routing (enum settings_output_type type)
676 assert (type < SETTINGS_N_OUTPUT_TYPES);
677 return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;
680 enum settings_value_show
681 settings_get_show_values (void)
683 return the_settings.show_values;
687 settings_set_show_values (enum settings_value_show s)
689 the_settings.show_values = s;
693 enum settings_value_show
694 settings_get_show_variables (void)
696 return the_settings.show_variables;
700 settings_set_show_variables (enum settings_value_show s)
702 the_settings.show_variables = s;