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)
38 /* Integer format used for IB and PIB input. */
39 enum integer_format input_integer_format;
41 /* Floating-point format used for RB and RBHEX input. */
42 enum float_format input_float_format;
44 /* Format of integers in output (SET WIB). */
45 enum integer_format output_integer_format;
47 /* Format of reals in output (SET WRB). */
48 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];
67 struct fmt_spec default_format;
74 struct fmt_settings *styles;
76 enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
79 static struct settings the_settings = {
80 INTEGER_NATIVE, /* input_integer_format */
81 FLOAT_NATIVE_DOUBLE, /* input_float_format */
82 INTEGER_NATIVE, /* output_integer_format */
83 FLOAT_NATIVE_DOUBLE, /* output_float_format */
86 false, /* safer_mode */
89 true, /* route_errors_to_terminal */
90 true, /* route_errors_to_listing */
97 100, /* MSG_S_ERROR */
98 100, /* MSG_S_WARNING */
102 true, /* printback */
107 64L * 1024 * 1024, /* workspace */
108 {FMT_F, 8, 2}, /* default_format */
109 false, /* testing_mode */
110 ENHANCED, /* cmd_algorithm */
111 ENHANCED, /* global_algorithm */
112 ENHANCED, /* syntax */
116 {SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
117 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
119 SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL}
125 settings_set_epoch (-1);
126 the_settings.styles = fmt_settings_create ();
128 settings_set_decimal_char (get_system_decimal ());
134 fmt_settings_destroy (the_settings.styles);
137 /* Returns the floating-point format used for RB and RBHEX
140 settings_get_input_float_format (void)
142 return the_settings.input_float_format;
145 /* Sets the floating-point format used for RB and RBHEX input to
148 settings_set_input_float_format ( enum float_format format)
150 the_settings.input_float_format = format;
153 /* Returns the integer format used for IB and PIB input. */
155 settings_get_input_integer_format (void)
157 return the_settings.input_integer_format;
160 /* Sets the integer format used for IB and PIB input to
163 settings_set_input_integer_format ( enum integer_format format)
165 the_settings.input_integer_format = format;
168 /* Returns the current output integer format. */
170 settings_get_output_integer_format (void)
172 return the_settings.output_integer_format;
175 /* Sets the output integer format to INTEGER_FORMAT. */
177 settings_set_output_integer_format (
178 enum integer_format integer_format)
180 the_settings.output_integer_format = integer_format;
183 /* Returns the current output float format. */
185 settings_get_output_float_format (void)
187 return the_settings.output_float_format;
190 /* Sets the output float format to FLOAT_FORMAT. */
192 settings_set_output_float_format ( enum float_format float_format)
194 the_settings.output_float_format = float_format;
197 /* Screen length in lines. */
199 settings_get_viewlength (void)
201 return the_settings.viewlength;
204 /* Sets the view length. */
206 settings_set_viewlength ( int viewlength_)
208 the_settings.viewlength = viewlength_;
213 settings_get_viewwidth(void)
215 return the_settings.viewwidth;
218 /* Sets the screen width. */
220 settings_set_viewwidth ( int viewwidth_)
222 the_settings.viewwidth = viewwidth_;
225 /* Whether PSPP can erase and overwrite files. */
227 settings_get_safer_mode (void)
229 return the_settings.safer_mode;
232 /* Set safer mode. */
234 settings_set_safer_mode (void)
236 the_settings.safer_mode = true;
239 /* If echo is on, whether commands from include files are echoed. */
241 settings_get_include (void)
243 return the_settings.include;
246 /* Set include file echo. */
248 settings_set_include ( bool include)
250 the_settings.include = include;
253 /* What year to use as the start of the epoch. */
255 settings_get_epoch (void)
257 assert (the_settings.epoch >= 0);
259 return the_settings.epoch;
262 /* Sets the year that starts the epoch. */
264 settings_set_epoch ( int epoch)
269 struct tm *tm = localtime (&t);
270 epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
273 the_settings.epoch = epoch;
274 assert (the_settings.epoch >= 0);
277 /* Compress system files by default? */
279 settings_get_scompression (void)
281 return the_settings.scompress;
284 /* Set system file default compression. */
286 settings_set_scompression ( bool scompress)
288 the_settings.scompress = scompress;
291 /* Whether to warn on undefined values in numeric data. */
293 settings_get_undefined (void)
295 return the_settings.undefined;
298 /* Set whether to warn on undefined values. */
300 settings_set_undefined ( bool undefined)
302 the_settings.undefined = undefined;
305 /* The value that blank numeric fields are set to when read in. */
307 settings_get_blanks (void)
309 return the_settings.blanks;
312 /* Set the value that blank numeric fields are set to when read
315 settings_set_blanks ( double blanks)
317 the_settings.blanks = blanks;
320 /* Returns the maximum number of messages to show of the given SEVERITY before
321 aborting. (The value for MSG_S_WARNING is interpreted as maximum number of
322 warnings and errors combined.) */
324 settings_get_max_messages (enum msg_severity severity)
326 assert (severity < MSG_N_SEVERITIES);
327 return the_settings.max_messages[severity];
330 /* Sets the maximum number of messages to show of the given SEVERITY before
331 aborting to MAX. (The value for MSG_S_WARNING is interpreted as maximum
332 number of warnings and errors combined.) In addition, in the case of
333 warnings the special value of zero indicates that no warnings are to be
337 settings_set_max_messages (enum msg_severity severity, int max)
339 assert (severity < MSG_N_SEVERITIES);
341 if (severity == MSG_S_WARNING)
346 _("MXWARNS set to zero. No further warnings will be given even when potentially problematic situations are encountered."));
347 msg_ui_disable_warnings (true);
349 else if ( the_settings.max_messages [MSG_S_WARNING] == 0)
351 msg_ui_disable_warnings (false);
352 the_settings.max_messages[MSG_S_WARNING] = max;
353 msg (MW, _("Warnings re-enabled. %d warnings will be issued before aborting syntax processing."), max);
357 the_settings.max_messages[severity] = max;
360 /* Independent of get_printback, controls whether the commands
361 generated by macro invocations are displayed. */
363 settings_get_mprint (void)
365 return the_settings.mprint;
368 /* Sets whether the commands generated by macro invocations are
371 settings_set_mprint ( bool mprint)
373 the_settings.mprint = mprint;
376 /* Implied limit of unbounded loop. */
378 settings_get_mxloops (void)
380 return the_settings.mxloops;
383 /* Set implied limit of unbounded loop. */
385 settings_set_mxloops ( int mxloops)
387 the_settings.mxloops = mxloops;
390 /* Whether a blank line is a command terminator. */
392 settings_get_nulline (void)
394 return the_settings.nulline;
397 /* Set whether a blank line is a command terminator. */
399 settings_set_nulline ( bool nulline)
401 the_settings.nulline = nulline;
404 /* The character used to terminate commands. */
406 settings_get_endcmd (void)
408 return the_settings.endcmd;
411 /* Set the character used to terminate commands. */
413 settings_set_endcmd ( char endcmd)
415 the_settings.endcmd = endcmd;
418 /* Approximate maximum amount of memory to use for cases, in
421 settings_get_workspace (void)
423 return the_settings.workspace;
426 /* Approximate maximum number of cases to allocate in-core, given
427 that each case has the format given in PROTO. */
429 settings_get_workspace_cases (const struct caseproto *proto)
431 size_t n_cases = settings_get_workspace () / case_get_cost (proto);
432 return MAX (n_cases, 4);
435 /* Set approximate maximum amount of memory to use for cases, in
439 settings_set_workspace ( size_t workspace)
441 the_settings.workspace = workspace;
444 /* Default format for variables created by transformations and by
445 DATA LIST {FREE,LIST}. */
446 const struct fmt_spec *
447 settings_get_format (void)
449 return &the_settings.default_format;
452 /* Set default format for variables created by transformations
453 and by DATA LIST {FREE,LIST}. */
455 settings_set_format ( const struct fmt_spec *default_format)
457 the_settings.default_format = *default_format;
460 /* Are we in testing mode? (e.g. --testing-mode command line
463 settings_get_testing_mode (void)
465 return the_settings.testing_mode;
468 /* Set testing mode. */
470 settings_set_testing_mode ( bool testing_mode)
472 the_settings.testing_mode = testing_mode;
475 /* Return the current algorithm setting */
477 settings_get_algorithm (void)
479 return the_settings.cmd_algorithm;
482 /* Set the algorithm option globally. */
484 settings_set_algorithm (enum behavior_mode mode)
486 the_settings.global_algorithm = the_settings.cmd_algorithm = mode;
489 /* Set the algorithm option for this command only */
491 settings_set_cmd_algorithm ( enum behavior_mode mode)
493 the_settings.cmd_algorithm = mode;
496 /* Unset the algorithm option for this command */
498 unset_cmd_algorithm (void)
500 the_settings.cmd_algorithm = the_settings.global_algorithm;
503 /* Get the current syntax setting */
505 settings_get_syntax (void)
507 return the_settings.syntax;
510 /* Set the syntax option */
512 settings_set_syntax ( enum behavior_mode mode)
514 the_settings.syntax = mode;
519 /* Find the grouping characters in CC_STRING and set CC's
520 grouping and decimal members appropriately. Returns true if
521 successful, false otherwise. */
523 find_cc_separators (const char *cc_string, struct fmt_number_style *cc)
526 int comma_cnt, dot_cnt;
528 /* Count commas and periods. There must be exactly three of
529 one or the other, except that an apostrophe escapes a
530 following comma or period. */
531 comma_cnt = dot_cnt = 0;
532 for (sp = cc_string; *sp; sp++)
537 else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
540 if ((comma_cnt == 3) == (dot_cnt == 3))
556 /* Extracts a token from IN into AFFIX, using BUFFER for storage. BUFFER must
557 have at least FMT_STYLE_AFFIX_MAX + 1 bytes of space. Tokens are delimited
558 by GROUPING. The token is truncated to at most FMT_STYLE_AFFIX_MAX bytes,
559 followed by a null terminator. Returns the first character following the
562 extract_cc_token (const char *in, int grouping, struct substring *affix,
563 char buffer[FMT_STYLE_AFFIX_MAX + 1])
567 for (; *in != '\0' && *in != grouping; in++)
569 if (*in == '\'' && in[1] == grouping)
571 if (ofs < FMT_STYLE_AFFIX_MAX)
574 *affix = ss_buffer (buffer, ofs);
581 /* Sets custom currency specifier CC having name CC_NAME ('A' through
582 'E') to correspond to the settings in CC_STRING. */
584 settings_set_cc (const char *cc_string, enum fmt_type type)
586 char a[FMT_STYLE_AFFIX_MAX + 1];
587 char b[FMT_STYLE_AFFIX_MAX + 1];
588 char c[FMT_STYLE_AFFIX_MAX + 1];
589 char d[FMT_STYLE_AFFIX_MAX + 1];
590 struct fmt_number_style cc;
592 assert (fmt_get_category (type) == FMT_CAT_CUSTOM);
594 /* Determine separators. */
595 if (!find_cc_separators (cc_string, &cc))
597 msg (SE, _("%s: Custom currency string `%s' does not contain "
598 "exactly three periods or commas (or it contains both)."),
599 fmt_name (type), cc_string);
603 cc_string = extract_cc_token (cc_string, cc.grouping, &cc.neg_prefix, a);
604 cc_string = extract_cc_token (cc_string, cc.grouping, &cc.prefix, b);
605 cc_string = extract_cc_token (cc_string, cc.grouping, &cc.suffix, c);
606 cc_string = extract_cc_token (cc_string, cc.grouping, &cc.neg_suffix, d);
608 fmt_settings_set_style (the_settings.styles, type, &cc);
613 /* Returns the decimal point character for TYPE. */
615 settings_get_decimal_char (enum fmt_type type)
617 return fmt_settings_get_style (the_settings.styles, type)->decimal;
621 settings_set_decimal_char (char decimal)
623 fmt_settings_set_decimal (the_settings.styles, decimal);
626 /* Returns the number formatting style associated with the given
628 const struct fmt_number_style *
629 settings_get_style (enum fmt_type type)
631 assert (is_fmt_type (type));
632 return fmt_settings_get_style (the_settings.styles, type);
635 /* Returns a string of the form "$#,###.##" according to FMT,
636 which must be of type FMT_DOLLAR. The caller must free the
639 settings_dollar_template (const struct fmt_spec *fmt)
641 struct string str = DS_EMPTY_INITIALIZER;
643 const struct fmt_number_style *fns ;
645 assert (fmt->type == FMT_DOLLAR);
647 fns = fmt_settings_get_style (the_settings.styles, fmt->type);
649 ds_put_char (&str, '$');
650 for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0; )
652 ds_put_char (&str, '#');
653 if (--c % 4 == 0 && c > 0)
655 ds_put_char (&str, fns->grouping);
661 ds_put_char (&str, fns->decimal);
662 ds_put_char_multiple (&str, '#', fmt->d);
665 return ds_cstr (&str);
669 settings_set_output_routing (enum settings_output_type type,
670 enum settings_output_devices devices)
672 assert (type < SETTINGS_N_OUTPUT_TYPES);
673 the_settings.output_routing[type] = devices;
676 enum settings_output_devices
677 settings_get_output_routing (enum settings_output_type type)
679 assert (type < SETTINGS_N_OUTPUT_TYPES);
680 return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;