1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 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"
25 #include "data/case.h"
26 #include "data/format.h"
27 #include "data/value.h"
28 #include "libpspp/i18n.h"
29 #include "libpspp/integer-format.h"
30 #include "libpspp/message.h"
33 #include "gl/minmax.h"
34 #include "gl/xalloc.h"
37 #define _(msgid) gettext (msgid)
41 /* Integer format used for IB and PIB input. */
42 enum integer_format input_integer_format;
44 /* Floating-point format used for RB and RBHEX input. */
45 enum float_format input_float_format;
47 /* Format of integers in output (SET WIB). */
48 enum integer_format output_integer_format;
50 /* Format of reals in output (SET WRB). */
51 enum float_format output_float_format;
58 bool route_errors_to_terminal;
59 bool route_errors_to_listing;
63 int max_messages[MSG_N_SEVERITIES];
68 struct fmt_spec default_format;
75 struct fmt_settings *styles;
77 enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
79 enum settings_var_style var_output_style;
80 enum settings_value_style value_output_style;
83 static struct settings the_settings = {
84 INTEGER_NATIVE, /* input_integer_format */
85 FLOAT_NATIVE_DOUBLE, /* input_float_format */
86 INTEGER_NATIVE, /* output_integer_format */
87 FLOAT_NATIVE_DOUBLE, /* output_float_format */
90 false, /* safer_mode */
93 true, /* route_errors_to_terminal */
94 true, /* route_errors_to_listing */
101 100, /* MSG_S_ERROR */
102 100, /* MSG_S_WARNING */
106 true, /* printback */
109 64L * 1024 * 1024, /* workspace */
110 {FMT_F, 8, 2}, /* default_format */
111 false, /* testing_mode */
112 ENHANCED, /* cmd_algorithm */
113 ENHANCED, /* global_algorithm */
114 ENHANCED, /* syntax */
118 {SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
119 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
121 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL},
123 SETTINGS_VAR_STYLE_LABELS,
124 SETTINGS_VAL_STYLE_LABELS
127 /* Initializes the settings module. */
131 settings_set_epoch (-1);
132 the_settings.styles = fmt_settings_create ();
134 settings_set_decimal_char (get_system_decimal ());
137 /* Cleans up the settings module. */
141 settings_destroy (&the_settings);
145 settings_copy (struct settings *dst, const struct settings *src)
148 dst->styles = fmt_settings_clone (src->styles);
151 /* Returns a copy of the current settings. */
155 struct settings *s = xmalloc (sizeof *s);
156 settings_copy (s, &the_settings);
160 /* Replaces the current settings by those in S. The caller retains ownership
163 settings_set (const struct settings *s)
165 settings_destroy (&the_settings);
166 settings_copy (&the_settings, s);
171 settings_destroy (struct settings *s)
175 fmt_settings_destroy (s->styles);
176 if (s != &the_settings)
181 /* Returns the floating-point format used for RB and RBHEX
184 settings_get_input_float_format (void)
186 return the_settings.input_float_format;
189 /* Sets the floating-point format used for RB and RBHEX input to
192 settings_set_input_float_format ( enum float_format format)
194 the_settings.input_float_format = format;
197 /* Returns the integer format used for IB and PIB input. */
199 settings_get_input_integer_format (void)
201 return the_settings.input_integer_format;
204 /* Sets the integer format used for IB and PIB input to
207 settings_set_input_integer_format ( enum integer_format format)
209 the_settings.input_integer_format = format;
212 /* Returns the current output integer format. */
214 settings_get_output_integer_format (void)
216 return the_settings.output_integer_format;
219 /* Sets the output integer format to INTEGER_FORMAT. */
221 settings_set_output_integer_format (
222 enum integer_format integer_format)
224 the_settings.output_integer_format = integer_format;
227 /* Returns the current output float format. */
229 settings_get_output_float_format (void)
231 return the_settings.output_float_format;
234 /* Sets the output float format to FLOAT_FORMAT. */
236 settings_set_output_float_format ( enum float_format float_format)
238 the_settings.output_float_format = float_format;
241 /* Screen length in lines. */
243 settings_get_viewlength (void)
245 return the_settings.viewlength;
248 /* Sets the view length. */
250 settings_set_viewlength ( int viewlength_)
252 the_settings.viewlength = viewlength_;
257 settings_get_viewwidth(void)
259 return the_settings.viewwidth;
262 /* Sets the screen width. */
264 settings_set_viewwidth ( int viewwidth_)
266 the_settings.viewwidth = viewwidth_;
269 /* Whether PSPP can erase and overwrite files. */
271 settings_get_safer_mode (void)
273 return the_settings.safer_mode;
276 /* Set safer mode. */
278 settings_set_safer_mode (void)
280 the_settings.safer_mode = true;
283 /* If echo is on, whether commands from include files are echoed. */
285 settings_get_include (void)
287 return the_settings.include;
290 /* Set include file echo. */
292 settings_set_include ( bool include)
294 the_settings.include = include;
297 /* What year to use as the start of the epoch. */
299 settings_get_epoch (void)
301 assert (the_settings.epoch >= 0);
303 return the_settings.epoch;
306 /* Sets the year that starts the epoch. */
308 settings_set_epoch ( int epoch)
313 struct tm *tm = localtime (&t);
314 epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
317 the_settings.epoch = epoch;
318 assert (the_settings.epoch >= 0);
321 /* Compress system files by default? */
323 settings_get_scompression (void)
325 return the_settings.scompress;
328 /* Set system file default compression. */
330 settings_set_scompression ( bool scompress)
332 the_settings.scompress = scompress;
335 /* Whether to warn on undefined values in numeric data. */
337 settings_get_undefined (void)
339 return the_settings.undefined;
342 /* Set whether to warn on undefined values. */
344 settings_set_undefined ( bool undefined)
346 the_settings.undefined = undefined;
349 /* The value that blank numeric fields are set to when read in. */
351 settings_get_blanks (void)
353 return the_settings.blanks;
356 /* Set the value that blank numeric fields are set to when read
359 settings_set_blanks ( double blanks)
361 the_settings.blanks = blanks;
364 /* Returns the maximum number of messages to show of the given SEVERITY before
365 aborting. (The value for MSG_S_WARNING is interpreted as maximum number of
366 warnings and errors combined.) */
368 settings_get_max_messages (enum msg_severity severity)
370 assert (severity < MSG_N_SEVERITIES);
371 return the_settings.max_messages[severity];
374 /* Sets the maximum number of messages to show of the given SEVERITY before
375 aborting to MAX. (The value for MSG_S_WARNING is interpreted as maximum
376 number of warnings and errors combined.) In addition, in the case of
377 warnings the special value of zero indicates that no warnings are to be
381 settings_set_max_messages (enum msg_severity severity, int max)
383 assert (severity < MSG_N_SEVERITIES);
385 if (severity == MSG_S_WARNING)
390 _("MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered."));
391 msg_ui_disable_warnings (true);
393 else if ( the_settings.max_messages [MSG_S_WARNING] == 0)
395 msg_ui_disable_warnings (false);
396 the_settings.max_messages[MSG_S_WARNING] = max;
397 msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
401 the_settings.max_messages[severity] = max;
404 /* Independent of get_printback, controls whether the commands
405 generated by macro invocations are displayed. */
407 settings_get_mprint (void)
409 return the_settings.mprint;
412 /* Sets whether the commands generated by macro invocations are
415 settings_set_mprint ( bool mprint)
417 the_settings.mprint = mprint;
420 /* Implied limit of unbounded loop. */
422 settings_get_mxloops (void)
424 return the_settings.mxloops;
427 /* Set implied limit of unbounded loop. */
429 settings_set_mxloops ( int mxloops)
431 the_settings.mxloops = mxloops;
434 /* Approximate maximum amount of memory to use for cases, in
437 settings_get_workspace (void)
439 return the_settings.workspace;
442 /* Approximate maximum number of cases to allocate in-core, given
443 that each case has the format given in PROTO. */
445 settings_get_workspace_cases (const struct caseproto *proto)
447 size_t n_cases = settings_get_workspace () / case_get_cost (proto);
448 return MAX (n_cases, 4);
451 /* Set approximate maximum amount of memory to use for cases, in
455 settings_set_workspace ( size_t workspace)
457 the_settings.workspace = workspace;
460 /* Default format for variables created by transformations and by
461 DATA LIST {FREE,LIST}. */
462 const struct fmt_spec *
463 settings_get_format (void)
465 return &the_settings.default_format;
468 /* Set default format for variables created by transformations
469 and by DATA LIST {FREE,LIST}. */
471 settings_set_format ( const struct fmt_spec *default_format)
473 the_settings.default_format = *default_format;
476 /* Are we in testing mode? (e.g. --testing-mode command line
479 settings_get_testing_mode (void)
481 return the_settings.testing_mode;
484 /* Set testing mode. */
486 settings_set_testing_mode ( bool testing_mode)
488 the_settings.testing_mode = testing_mode;
491 /* Return the current algorithm setting */
493 settings_get_algorithm (void)
495 return the_settings.cmd_algorithm;
498 /* Set the algorithm option globally. */
500 settings_set_algorithm (enum behavior_mode mode)
502 the_settings.global_algorithm = the_settings.cmd_algorithm = mode;
505 /* Set the algorithm option for this command only */
507 settings_set_cmd_algorithm ( enum behavior_mode mode)
509 the_settings.cmd_algorithm = mode;
512 /* Unset the algorithm option for this command */
514 unset_cmd_algorithm (void)
516 the_settings.cmd_algorithm = the_settings.global_algorithm;
519 /* Get the current syntax setting */
521 settings_get_syntax (void)
523 return the_settings.syntax;
526 /* Set the syntax option */
528 settings_set_syntax ( enum behavior_mode mode)
530 the_settings.syntax = mode;
535 /* Find the grouping characters in CC_STRING and sets *GROUPING and *DECIMAL
536 appropriately. Returns true if successful, false otherwise. */
538 find_cc_separators (const char *cc_string, char *decimal, char *grouping)
541 int comma_cnt, dot_cnt;
543 /* Count commas and periods. There must be exactly three of
544 one or the other, except that an apostrophe escapes a
545 following comma or period. */
546 comma_cnt = dot_cnt = 0;
547 for (sp = cc_string; *sp; sp++)
552 else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
555 if ((comma_cnt == 3) == (dot_cnt == 3))
571 /* Extracts a token from IN into a newly allocated string AFFIXP. Tokens are
572 delimited by GROUPING. Returns the first character following the token. */
574 extract_cc_token (const char *in, int grouping, char **affixp)
578 out = *affixp = xmalloc (strlen (in) + 1);
579 for (; *in != '\0' && *in != grouping; in++)
581 if (*in == '\'' && in[1] == grouping)
592 /* Sets custom currency specifier CC having name CC_NAME ('A' through
593 'E') to correspond to the settings in CC_STRING. */
595 settings_set_cc (const char *cc_string, enum fmt_type type)
597 char *neg_prefix, *prefix, *suffix, *neg_suffix;
598 char decimal, grouping;
600 assert (fmt_get_category (type) == FMT_CAT_CUSTOM);
602 /* Determine separators. */
603 if (!find_cc_separators (cc_string, &decimal, &grouping))
605 msg (SE, _("%s: Custom currency string `%s' does not contain "
606 "exactly three periods or commas (or it contains both)."),
607 fmt_name (type), cc_string);
611 cc_string = extract_cc_token (cc_string, grouping, &neg_prefix);
612 cc_string = extract_cc_token (cc_string, grouping, &prefix);
613 cc_string = extract_cc_token (cc_string, grouping, &suffix);
614 cc_string = extract_cc_token (cc_string, grouping, &neg_suffix);
616 fmt_settings_set_style (the_settings.styles, type, decimal, grouping,
617 neg_prefix, prefix, suffix, neg_suffix);
627 /* Returns the decimal point character for TYPE. */
629 settings_get_decimal_char (enum fmt_type type)
631 return fmt_settings_get_style (the_settings.styles, type)->decimal;
635 settings_set_decimal_char (char decimal)
637 fmt_settings_set_decimal (the_settings.styles, decimal);
640 /* Returns the number formatting style associated with the given
642 const struct fmt_number_style *
643 settings_get_style (enum fmt_type type)
645 assert (is_fmt_type (type));
646 return fmt_settings_get_style (the_settings.styles, type);
649 /* Returns a string of the form "$#,###.##" according to FMT,
650 which must be of type FMT_DOLLAR. The caller must free the
653 settings_dollar_template (const struct fmt_spec *fmt)
655 struct string str = DS_EMPTY_INITIALIZER;
657 const struct fmt_number_style *fns ;
659 assert (fmt->type == FMT_DOLLAR);
661 fns = fmt_settings_get_style (the_settings.styles, fmt->type);
663 ds_put_byte (&str, '$');
664 for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0; )
666 ds_put_byte (&str, '#');
667 if (--c % 4 == 0 && c > 0)
669 ds_put_byte (&str, fns->grouping);
675 ds_put_byte (&str, fns->decimal);
676 ds_put_byte_multiple (&str, '#', fmt->d);
679 return ds_cstr (&str);
683 settings_set_output_routing (enum settings_output_type type,
684 enum settings_output_devices devices)
686 assert (type < SETTINGS_N_OUTPUT_TYPES);
687 the_settings.output_routing[type] = devices;
690 enum settings_output_devices
691 settings_get_output_routing (enum settings_output_type type)
693 assert (type < SETTINGS_N_OUTPUT_TYPES);
694 return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;
697 enum settings_value_style
698 settings_get_value_style (void)
700 return the_settings.value_output_style;
704 settings_set_value_style (enum settings_value_style s)
706 the_settings.value_output_style = s;
711 enum settings_var_style
712 settings_get_var_style (void)
714 return the_settings.var_output_style;