Implement SET LEADZERO.
[pspp.git] / src / data / settings.c
blob7d7934af9240ccaaff1df4ce0ed0270647882cdc
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/>. */
17 #include <config.h>
19 #include "data/settings.h"
21 #include <assert.h>
22 #include <stdlib.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"
34 #include "gettext.h"
35 #define _(msgid) gettext (msgid)
37 struct settings
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;
51 /* MATRIX...END MATRIX settings. */
52 enum settings_mdisplay mdisplay;
54 int viewlength;
55 int viewwidth;
56 bool safer_mode;
57 bool include;
58 bool route_errors_to_terminal;
59 bool route_errors_to_listing;
60 bool scompress;
61 bool undefined;
62 double blanks;
63 int max_messages[MSG_N_SEVERITIES];
64 bool printback;
66 /* Macro settings. */
67 bool mexpand; /* Expand macros? */
68 bool mprint; /* Print macro expansions? */
69 int miterate; /* Maximum iterations of !FOR. */
70 int mnest; /* Maximum nested macro expansion levels. */
72 int mxloops;
73 size_t workspace;
74 struct fmt_spec default_format;
75 bool testing_mode;
76 int fuzzbits;
78 int cmd_algorithm;
79 int global_algorithm;
80 int syntax;
82 struct fmt_settings styles;
83 double small;
85 enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
87 enum settings_value_show show_values;
88 enum settings_value_show show_variables;
91 static struct settings the_settings = {
92 .input_integer_format = INTEGER_NATIVE,
93 .input_float_format = FLOAT_NATIVE_DOUBLE,
94 .output_integer_format = INTEGER_NATIVE,
95 .output_float_format = FLOAT_NATIVE_DOUBLE,
96 .mdisplay = SETTINGS_MDISPLAY_TEXT,
97 .viewlength = 24,
98 .viewwidth = 79,
99 .safer_mode = false,
100 .include = true,
101 .route_errors_to_terminal = true,
102 .route_errors_to_listing = true,
103 .scompress = true,
104 .undefined = true,
105 .blanks = SYSMIS,
107 .max_messages = {
108 [MSG_S_ERROR] = 100,
109 [MSG_S_WARNING] = 100,
110 [MSG_S_NOTE] = 100
113 .printback = true,
115 .mexpand = true,
116 .mprint = false,
117 .miterate = 1000,
118 .mnest = 50,
120 .mxloops = 40,
121 .workspace = 64L * 1024 * 1024,
122 .default_format = { .type = FMT_F, .w = 8, .d = 2 },
123 .testing_mode = false,
124 .fuzzbits = 6,
125 .cmd_algorithm = ENHANCED,
126 .global_algorithm = ENHANCED,
127 .syntax = ENHANCED,
128 .styles = FMT_SETTINGS_INIT,
129 .small = .0001,
131 /* output_routing */
132 .output_routing = {
133 #define LT (SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL)
134 [SETTINGS_OUTPUT_ERROR] = LT,
135 [SETTINGS_OUTPUT_NOTE] = LT,
136 [SETTINGS_OUTPUT_SYNTAX] = 0,
137 [SETTINGS_OUTPUT_RESULT] = LT
138 #undef LT
141 .show_values = SETTINGS_VALUE_SHOW_LABEL,
142 .show_variables = SETTINGS_VALUE_SHOW_LABEL,
145 /* Initializes the settings module. */
146 void
147 settings_init (void)
149 settings_set_decimal_char (get_system_decimal ());
152 /* Cleans up the settings module. */
153 void
154 settings_done (void)
156 settings_destroy (&the_settings);
159 static void
160 settings_copy (struct settings *dst, const struct settings *src)
162 *dst = *src;
163 dst->styles = fmt_settings_copy (&src->styles);
166 /* Returns a copy of the current settings. */
167 struct settings *
168 settings_get (void)
170 struct settings *s = xmalloc (sizeof *s);
171 settings_copy (s, &the_settings);
172 return s;
175 /* Replaces the current settings by those in S. The caller retains ownership
176 of S. */
177 void
178 settings_set (const struct settings *s)
180 settings_destroy (&the_settings);
181 settings_copy (&the_settings, s);
184 /* Destroys S. */
185 void
186 settings_destroy (struct settings *s)
188 if (s != NULL)
190 fmt_settings_uninit (&s->styles);
191 if (s != &the_settings)
192 free (s);
196 /* Returns the floating-point format used for RB and RBHEX
197 input. */
198 enum float_format
199 settings_get_input_float_format (void)
201 return the_settings.input_float_format;
204 /* Sets the floating-point format used for RB and RBHEX input to
205 FORMAT. */
206 void
207 settings_set_input_float_format (enum float_format format)
209 the_settings.input_float_format = format;
212 /* Returns the integer format used for IB and PIB input. */
213 enum integer_format
214 settings_get_input_integer_format (void)
216 return the_settings.input_integer_format;
219 /* Sets the integer format used for IB and PIB input to
220 FORMAT. */
221 void
222 settings_set_input_integer_format (enum integer_format format)
224 the_settings.input_integer_format = format;
227 /* Returns the current output integer format. */
228 enum integer_format
229 settings_get_output_integer_format (void)
231 return the_settings.output_integer_format;
234 /* Sets the output integer format to INTEGER_FORMAT. */
235 void
236 settings_set_output_integer_format (
237 enum integer_format integer_format)
239 the_settings.output_integer_format = integer_format;
242 /* Returns the current output float format. */
243 enum float_format
244 settings_get_output_float_format (void)
246 return the_settings.output_float_format;
249 /* Sets the output float format to FLOAT_FORMAT. */
250 void
251 settings_set_output_float_format (enum float_format float_format)
253 the_settings.output_float_format = float_format;
256 /* Screen length in lines. */
258 settings_get_viewlength (void)
260 return the_settings.viewlength;
263 /* Sets the view length. */
264 void
265 settings_set_viewlength (int viewlength_)
267 the_settings.viewlength = viewlength_;
270 /* Screen width. */
272 settings_get_viewwidth(void)
274 return the_settings.viewwidth;
277 /* Sets the screen width. */
278 void
279 settings_set_viewwidth (int viewwidth_)
281 the_settings.viewwidth = viewwidth_;
284 /* Whether PSPP can erase and overwrite files. */
285 bool
286 settings_get_safer_mode (void)
288 return the_settings.safer_mode;
291 /* Set safer mode. */
292 void
293 settings_set_safer_mode (void)
295 the_settings.safer_mode = true;
298 /* If echo is on, whether commands from include files are echoed. */
299 bool
300 settings_get_include (void)
302 return the_settings.include;
305 /* Set include file echo. */
306 void
307 settings_set_include (bool include)
309 the_settings.include = include;
312 /* Returns the year that starts the epoch. */
314 settings_get_epoch (void)
316 return the_settings.styles.epoch;
319 /* Sets the year that starts the epoch. */
320 void
321 settings_set_epoch (int epoch)
323 the_settings.styles.epoch = epoch;
326 /* Compress system files by default? */
327 bool
328 settings_get_scompression (void)
330 return the_settings.scompress;
333 /* Set system file default compression. */
334 void
335 settings_set_scompression (bool scompress)
337 the_settings.scompress = scompress;
340 /* Whether to warn on undefined values in numeric data. */
341 bool
342 settings_get_undefined (void)
344 return the_settings.undefined;
347 /* Set whether to warn on undefined values. */
348 void
349 settings_set_undefined (bool undefined)
351 the_settings.undefined = undefined;
354 /* The value that blank numeric fields are set to when read in. */
355 double
356 settings_get_blanks (void)
358 return the_settings.blanks;
361 /* Set the value that blank numeric fields are set to when read
362 in. */
363 void
364 settings_set_blanks (double blanks)
366 the_settings.blanks = blanks;
369 /* Returns the maximum number of messages to show of the given SEVERITY before
370 aborting. (The value for MSG_S_WARNING is interpreted as maximum number of
371 warnings and errors combined.) */
373 settings_get_max_messages (enum msg_severity severity)
375 assert (severity < MSG_N_SEVERITIES);
376 return the_settings.max_messages[severity];
379 /* Sets the maximum number of messages to show of the given SEVERITY before
380 aborting to MAX. (The value for MSG_S_WARNING is interpreted as maximum
381 number of warnings and errors combined.) In addition, in the case of
382 warnings the special value of zero indicates that no warnings are to be
383 issued.
385 void
386 settings_set_max_messages (enum msg_severity severity, int max)
388 assert (severity < MSG_N_SEVERITIES);
390 if (severity == MSG_S_WARNING)
392 if (max == 0)
394 msg (MW,
395 _("MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered."));
396 msg_ui_disable_warnings (true);
398 else if (the_settings.max_messages [MSG_S_WARNING] == 0)
400 msg_ui_disable_warnings (false);
401 the_settings.max_messages[MSG_S_WARNING] = max;
402 msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
406 the_settings.max_messages[severity] = max;
409 /* Returns whether to expand macro invocations. */
410 bool
411 settings_get_mexpand (void)
413 return the_settings.mexpand;
416 /* Sets whether to expand macro invocations. */
417 void
418 settings_set_mexpand (bool mexpand)
420 the_settings.mexpand = mexpand;
423 /* Independent of get_printback, controls whether the commands
424 generated by macro invocations are displayed. */
425 bool
426 settings_get_mprint (void)
428 return the_settings.mprint;
431 /* Sets whether the commands generated by macro invocations are
432 displayed. */
433 void
434 settings_set_mprint (bool mprint)
436 the_settings.mprint = mprint;
439 /* Returns the limit for loop iterations within a macro. */
441 settings_get_miterate (void)
443 return the_settings.miterate;
446 /* Sets the limit for loop iterations within a macro. */
447 void
448 settings_set_miterate (int miterate)
450 the_settings.miterate = miterate;
453 /* Returns the limit for recursion macro expansions. */
454 int settings_get_mnest (void)
456 return the_settings.mnest;
459 /* Sets the limit for recursion macro expansions. */
460 void
461 settings_set_mnest (int mnest)
463 the_settings.mnest = mnest;
466 int settings_get_mxloops (void);
467 void settings_set_mxloops (int);
468 /* Implied limit of unbounded loop. */
470 settings_get_mxloops (void)
472 return the_settings.mxloops;
475 /* Set implied limit of unbounded loop. */
476 void
477 settings_set_mxloops (int mxloops)
479 the_settings.mxloops = mxloops;
482 /* Approximate maximum amount of memory to use for cases, in
483 bytes. */
484 size_t
485 settings_get_workspace (void)
487 return the_settings.workspace;
490 /* Approximate maximum number of cases to allocate in-core, given
491 that each case has the format given in PROTO. */
492 size_t
493 settings_get_workspace_cases (const struct caseproto *proto)
495 size_t n_cases = settings_get_workspace () / case_get_cost (proto);
496 return MAX (n_cases, 4);
499 /* Set approximate maximum amount of memory to use for cases, in
500 bytes. */
502 void
503 settings_set_workspace (size_t workspace)
505 the_settings.workspace = workspace;
508 /* Default format for variables created by transformations and by
509 DATA LIST {FREE,LIST}. */
510 const struct fmt_spec *
511 settings_get_format (void)
513 return &the_settings.default_format;
516 /* Set default format for variables created by transformations
517 and by DATA LIST {FREE,LIST}. */
518 void
519 settings_set_format (const struct fmt_spec *default_format)
521 the_settings.default_format = *default_format;
524 /* Are we in testing mode? (e.g. --testing-mode command line
525 option) */
526 bool
527 settings_get_testing_mode (void)
529 return the_settings.testing_mode;
532 /* Set testing mode. */
533 void
534 settings_set_testing_mode (bool testing_mode)
536 the_settings.testing_mode = testing_mode;
540 settings_get_fuzzbits (void)
542 return the_settings.fuzzbits;
545 void
546 settings_set_fuzzbits (int fuzzbits)
548 the_settings.fuzzbits = fuzzbits;
551 /* Return the current algorithm setting */
552 enum behavior_mode
553 settings_get_algorithm (void)
555 return the_settings.cmd_algorithm;
558 /* Set the algorithm option globally. */
559 void
560 settings_set_algorithm (enum behavior_mode mode)
562 the_settings.global_algorithm = the_settings.cmd_algorithm = mode;
565 /* Set the algorithm option for this command only */
566 void
567 settings_set_cmd_algorithm (enum behavior_mode mode)
569 the_settings.cmd_algorithm = mode;
572 /* Unset the algorithm option for this command */
573 void
574 unset_cmd_algorithm (void)
576 the_settings.cmd_algorithm = the_settings.global_algorithm;
579 /* Get the current syntax setting */
580 enum behavior_mode
581 settings_get_syntax (void)
583 return the_settings.syntax;
586 /* Set the syntax option */
587 void
588 settings_set_syntax (enum behavior_mode mode)
590 the_settings.syntax = mode;
594 /* Sets custom currency specifier CC having name CC_NAME ('A' through
595 'E') to correspond to the settings in CC_STRING. */
596 bool
597 settings_set_cc (const char *cc_string, enum fmt_type type)
599 struct fmt_number_style *style = fmt_number_style_from_string (cc_string);
600 if (!style)
602 msg (SE, _("%s: Custom currency string `%s' does not contain "
603 "exactly three periods or commas (or it contains both)."),
604 fmt_name (type), cc_string);
605 return false;
608 fmt_settings_set_cc (&the_settings.styles, type, style);
609 return true;
612 void
613 settings_set_decimal_char (char decimal)
615 the_settings.styles.decimal = decimal;
618 void
619 settings_set_include_leading_zero (bool include_leading_zero)
621 the_settings.styles.include_leading_zero = include_leading_zero;
624 const struct fmt_settings *
625 settings_get_fmt_settings (void)
627 return &the_settings.styles;
630 double
631 settings_get_small (void)
633 return the_settings.small;
636 void
637 settings_set_small (double small)
639 the_settings.small = small;
642 /* Returns a string of the form "$#,###.##" according to FMT,
643 which must be of type FMT_DOLLAR. The caller must free the
644 string. */
645 char *
646 settings_dollar_template (const struct fmt_spec *fmt)
648 struct string str = DS_EMPTY_INITIALIZER;
649 int c;
650 const struct fmt_number_style *fns ;
652 assert (fmt->type == FMT_DOLLAR);
654 fns = fmt_settings_get_style (&the_settings.styles, fmt->type);
656 ds_put_byte (&str, '$');
657 for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0;)
659 ds_put_byte (&str, '#');
660 if (--c % 4 == 0 && c > 0)
662 ds_put_byte (&str, fns->grouping);
663 --c;
666 if (fmt->d > 0)
668 ds_put_byte (&str, fns->decimal);
669 ds_put_byte_multiple (&str, '#', fmt->d);
672 return ds_cstr (&str);
675 void
676 settings_set_output_routing (enum settings_output_type type,
677 enum settings_output_devices devices)
679 assert (type < SETTINGS_N_OUTPUT_TYPES);
680 the_settings.output_routing[type] = devices;
683 enum settings_output_devices
684 settings_get_output_routing (enum settings_output_type type)
686 assert (type < SETTINGS_N_OUTPUT_TYPES);
687 return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;
690 enum settings_value_show
691 settings_get_show_values (void)
693 return the_settings.show_values;
696 void
697 settings_set_show_values (enum settings_value_show s)
699 the_settings.show_values = s;
703 enum settings_value_show
704 settings_get_show_variables (void)
706 return the_settings.show_variables;
709 void
710 settings_set_show_variables (enum settings_value_show s)
712 the_settings.show_variables = s;
715 enum settings_mdisplay
716 settings_get_mdisplay (void)
718 return the_settings.mdisplay;
721 void
722 settings_set_mdisplay (enum settings_mdisplay mdisplay)
724 the_settings.mdisplay = mdisplay;