43adaf6da3c7fb6c6240895425808107494b8d4f
[pspp] / src / language / utilities / set.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17 #include <config.h>
18
19 #include <float.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #include <unistd.h>
25
26 #include "data/casereader.h"
27 #include "data/data-in.h"
28 #include "data/data-out.h"
29 #include "data/dataset.h"
30 #include "data/dictionary.h"
31 #include "data/format.h"
32 #include "data/settings.h"
33 #include "data/value.h"
34 #include "data/variable.h"
35 #include "language/command.h"
36 #include "language/lexer/format-parser.h"
37 #include "language/lexer/lexer.h"
38 #include "language/lexer/token.h"
39 #include "libpspp/assertion.h"
40 #include "libpspp/compiler.h"
41 #include "libpspp/copyleft.h"
42 #include "libpspp/temp-file.h"
43 #include "libpspp/version.h"
44 #include "libpspp/float-format.h"
45 #include "libpspp/i18n.h"
46 #include "libpspp/integer-format.h"
47 #include "libpspp/message.h"
48 #include "math/random.h"
49 #include "output/driver.h"
50 #include "output/journal.h"
51 #include "output/pivot-table.h"
52
53 #include "gl/ftoastr.h"
54 #include "gl/minmax.h"
55 #include "gl/relocatable.h"
56 #include "gl/vasnprintf.h"
57 #include "gl/xalloc.h"
58
59 #include "gettext.h"
60 #define _(msgid) gettext (msgid)
61 #define N_(msgid) (msgid)
62
63 struct setting
64   {
65     const char *name;
66     bool (*set) (struct lexer *);
67     char *(*show) (const struct dataset *);
68   };
69
70 static bool
71 match_subcommand (struct lexer *lexer, const char *name)
72 {
73   if (lex_match_id (lexer, name))
74     {
75       lex_match (lexer, T_EQUALS);
76       return true;
77     }
78   else
79     return false;
80 }
81
82 static int
83 subcommand_start_ofs (struct lexer *lexer)
84 {
85   int ofs = lex_ofs (lexer) - 1;
86   return lex_ofs_token (lexer, ofs)->type == T_EQUALS ? ofs - 1 : ofs;
87 }
88
89 static int
90 parse_enum_valist (struct lexer *lexer, va_list args)
91 {
92   for (;;)
93     {
94       const char *name = va_arg (args, char *);
95       if (!name)
96         return -1;
97       int value = va_arg (args, int);
98
99       if (lex_match_id (lexer, name))
100         return value;
101     }
102 }
103
104 #define parse_enum(...) parse_enum (__VA_ARGS__, NULL_SENTINEL)
105 static int SENTINEL(0)
106 (parse_enum) (struct lexer *lexer, ...)
107 {
108   va_list args;
109
110   va_start (args, lexer);
111   int retval = parse_enum_valist (lexer, args);
112   va_end (args);
113
114   return retval;
115 }
116
117 #define force_parse_enum(...) force_parse_enum (__VA_ARGS__, NULL_SENTINEL)
118 static int SENTINEL(0)
119 (force_parse_enum) (struct lexer *lexer, ...)
120 {
121   va_list args;
122
123   va_start (args, lexer);
124   int retval = parse_enum_valist (lexer, args);
125   va_end (args);
126
127   if (retval == -1)
128     {
129       enum { MAX_OPTIONS = 9 };
130       const char *options[MAX_OPTIONS];
131       int n = 0;
132
133       va_start (args, lexer);
134       while (n < MAX_OPTIONS)
135         {
136           const char *name = va_arg (args, char *);
137           if (!name)
138             break;
139           va_arg (args, int);
140
141           options[n++] = name;
142         }
143       va_end (args);
144
145       lex_error_expecting_array (lexer, options, n);
146     }
147
148   return retval;
149 }
150
151 static int
152 parse_bool (struct lexer *lexer)
153 {
154   return parse_enum (lexer,
155                      "ON", true, "YES", true,
156                      "OFF", false, "NO", false);
157 }
158
159 static int
160 force_parse_bool (struct lexer *lexer)
161 {
162   return force_parse_enum (lexer,
163                            "ON", true, "YES", true,
164                            "OFF", false, "NO", false);
165 }
166
167 static bool
168 parse_output_routing (struct lexer *lexer, enum settings_output_type type)
169 {
170   enum settings_output_devices devices;
171   if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "BOTH"))
172     devices = SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL;
173   else if (lex_match_id (lexer, "TERMINAL"))
174     devices = SETTINGS_DEVICE_TERMINAL;
175   else if (lex_match_id (lexer, "LISTING"))
176     devices = SETTINGS_DEVICE_LISTING;
177   else if (lex_match_id (lexer, "OFF") || lex_match_id (lexer, "NONE"))
178     devices = 0;
179   else
180     {
181       lex_error (lexer, NULL);
182       return false;
183     }
184
185   settings_set_output_routing (type, devices);
186
187   return true;
188 }
189
190 static char *
191 show_output_routing (enum settings_output_type type)
192 {
193   enum settings_output_devices devices;
194   const char *s;
195
196   devices = settings_get_output_routing (type);
197   if (devices & SETTINGS_DEVICE_LISTING)
198     s = devices & SETTINGS_DEVICE_TERMINAL ? "BOTH" : "LISTING";
199   else if (devices & SETTINGS_DEVICE_TERMINAL)
200     s = "TERMINAL";
201   else
202     s = "NONE";
203
204   return xstrdup (s);
205 }
206
207 static bool
208 parse_integer_format (struct lexer *lexer,
209                       void (*set_format) (enum integer_format))
210 {
211   int value = force_parse_enum (lexer,
212                                 "MSBFIRST", INTEGER_MSB_FIRST,
213                                 "LSBFIRST", INTEGER_LSB_FIRST,
214                                 "VAX", INTEGER_VAX,
215                                 "NATIVE", INTEGER_NATIVE);
216   if (value >= 0)
217     set_format (value);
218   return value >= 0;
219 }
220
221 /* Returns a name for the given INTEGER_FORMAT value. */
222 static char *
223 show_integer_format (enum integer_format integer_format)
224 {
225   return xasprintf ("%s (%s)",
226                     (integer_format == INTEGER_MSB_FIRST ? "MSBFIRST"
227                      : integer_format == INTEGER_LSB_FIRST ? "LSBFIRST"
228                      : "VAX"),
229                     integer_format == INTEGER_NATIVE ? "NATIVE" : "nonnative");
230 }
231
232 static bool
233 parse_real_format (struct lexer *lexer,
234                    void (*set_format) (enum float_format))
235 {
236   int value = force_parse_enum (lexer,
237                                 "NATIVE", FLOAT_NATIVE_DOUBLE,
238                                 "ISL", FLOAT_IEEE_SINGLE_LE,
239                                 "ISB", FLOAT_IEEE_SINGLE_BE,
240                                 "IDL", FLOAT_IEEE_DOUBLE_LE,
241                                 "IDB", FLOAT_IEEE_DOUBLE_BE,
242                                 "VF", FLOAT_VAX_F,
243                                 "VD", FLOAT_VAX_D,
244                                 "VG", FLOAT_VAX_G,
245                                 "ZS", FLOAT_Z_SHORT,
246                                 "ZL", FLOAT_Z_LONG);
247   if (value >= 0)
248     set_format (value);
249   return value >= 0;
250 }
251
252 /* Returns a name for the given FLOAT_FORMAT value. */
253 static char *
254 show_real_format (enum float_format float_format)
255 {
256   const char *format_name = "";
257
258   switch (float_format)
259     {
260     case FLOAT_IEEE_SINGLE_LE:
261       format_name = _("ISL (32-bit IEEE 754 single, little-endian)");
262       break;
263     case FLOAT_IEEE_SINGLE_BE:
264       format_name = _("ISB (32-bit IEEE 754 single, big-endian)");
265       break;
266     case FLOAT_IEEE_DOUBLE_LE:
267       format_name = _("IDL (64-bit IEEE 754 double, little-endian)");
268       break;
269     case FLOAT_IEEE_DOUBLE_BE:
270       format_name = _("IDB (64-bit IEEE 754 double, big-endian)");
271       break;
272
273     case FLOAT_VAX_F:
274       format_name = _("VF (32-bit VAX F, VAX-endian)");
275       break;
276     case FLOAT_VAX_D:
277       format_name = _("VD (64-bit VAX D, VAX-endian)");
278       break;
279     case FLOAT_VAX_G:
280       format_name = _("VG (64-bit VAX G, VAX-endian)");
281       break;
282
283     case FLOAT_Z_SHORT:
284       format_name = _("ZS (32-bit IBM Z hexadecimal short, big-endian)");
285       break;
286     case FLOAT_Z_LONG:
287       format_name = _("ZL (64-bit IBM Z hexadecimal long, big-endian)");
288       break;
289
290     case FLOAT_FP:
291     case FLOAT_HEX:
292       NOT_REACHED ();
293     }
294
295   return xasprintf ("%s (%s)", format_name,
296                     (float_format == FLOAT_NATIVE_DOUBLE
297                      ? "NATIVE" : "nonnative"));
298 }
299
300 static bool
301 parse_unimplemented (struct lexer *lexer, const char *name)
302 {
303   int start = subcommand_start_ofs (lexer);
304   if (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
305     lex_get (lexer);
306   int end = lex_ofs (lexer) - 1;
307
308   lex_ofs_msg (lexer, SW, start, end, _("%s is not yet implemented."), name);
309   return true;
310 }
311
312 static bool
313 parse_ccx (struct lexer *lexer, enum fmt_type ccx)
314 {
315   if (!lex_force_string (lexer))
316     return false;
317
318   settings_set_cc (lex_tokcstr (lexer), ccx);
319   lex_get (lexer);
320   return true;
321 }
322 \f
323 static bool
324 parse_BASETEXTDIRECTION (struct lexer *lexer)
325 {
326   return parse_unimplemented (lexer, "BASETEXTDIRECTION");
327 }
328
329 static bool
330 parse_BLANKS (struct lexer *lexer)
331 {
332   if (lex_match_id (lexer, "SYSMIS"))
333     settings_set_blanks (SYSMIS);
334   else
335     {
336       if (!lex_force_num (lexer))
337         return false;
338       settings_set_blanks (lex_number (lexer));
339       lex_get (lexer);
340     }
341   return true;
342 }
343
344 static char *
345 show_BLANKS (const struct dataset *ds UNUSED)
346 {
347   return (settings_get_blanks () == SYSMIS
348           ? xstrdup ("SYSMIS")
349           : xasprintf ("%.*g", DBL_DIG + 1, settings_get_blanks ()));
350 }
351
352 static bool
353 parse_BLOCK (struct lexer *lexer)
354 {
355   return parse_unimplemented (lexer, "BLOCK");
356 }
357
358 static bool
359 parse_BOX (struct lexer *lexer)
360 {
361   return parse_unimplemented (lexer, "BOX");
362 }
363
364 static bool
365 parse_CACHE (struct lexer *lexer)
366 {
367   return parse_unimplemented (lexer, "CACHE");
368 }
369
370 static bool
371 parse_CCA (struct lexer *lexer)
372 {
373   return parse_ccx (lexer, FMT_CCA);
374 }
375
376 static bool
377 parse_CCB (struct lexer *lexer)
378 {
379   return parse_ccx (lexer, FMT_CCB);
380 }
381
382 static bool
383 parse_CCC (struct lexer *lexer)
384 {
385   return parse_ccx (lexer, FMT_CCC);
386 }
387
388 static bool
389 parse_CCD (struct lexer *lexer)
390 {
391   return parse_ccx (lexer, FMT_CCD);
392 }
393
394 static bool
395 parse_CCE (struct lexer *lexer)
396 {
397   return parse_ccx (lexer, FMT_CCE);
398 }
399
400 static char *
401 show_cc (enum fmt_type type)
402 {
403   return fmt_number_style_to_string (fmt_settings_get_style (
404                                        settings_get_fmt_settings (), type));
405 }
406
407 static char *
408 show_CCA (const struct dataset *ds UNUSED)
409 {
410   return show_cc (FMT_CCA);
411 }
412
413 static char *
414 show_CCB (const struct dataset *ds UNUSED)
415 {
416   return show_cc (FMT_CCB);
417 }
418
419 static char *
420 show_CCC (const struct dataset *ds UNUSED)
421 {
422   return show_cc (FMT_CCC);
423 }
424
425 static char *
426 show_CCD (const struct dataset *ds UNUSED)
427 {
428   return show_cc (FMT_CCD);
429 }
430
431 static char *
432 show_CCE (const struct dataset *ds UNUSED)
433 {
434   return show_cc (FMT_CCE);
435 }
436
437 static bool
438 parse_CELLSBREAK (struct lexer *lexer)
439 {
440   return parse_unimplemented (lexer, "CELLSBREAK");
441 }
442
443 static bool
444 parse_CMPTRANS (struct lexer *lexer)
445 {
446   return parse_unimplemented (lexer, "CMPTRANS");
447 }
448
449 static bool
450 parse_COMPRESSION (struct lexer *lexer)
451 {
452   return parse_unimplemented (lexer, "COMPRESSION");
453 }
454
455 static bool
456 parse_CTEMPLATE (struct lexer *lexer)
457 {
458   return parse_unimplemented (lexer, "CTEMPLATE");
459 }
460
461 static bool
462 parse_DECIMAL (struct lexer *lexer)
463 {
464   int decimal_char = force_parse_enum (lexer,
465                                        "DOT", '.',
466                                        "COMMA", ',');
467   if (decimal_char != -1)
468     settings_set_decimal_char (decimal_char);
469   return decimal_char != -1;
470 }
471
472 static char *
473 show_DECIMAL (const struct dataset *ds UNUSED)
474 {
475   return xasprintf ("`%c'", settings_get_fmt_settings ()->decimal);
476 }
477
478 static bool
479 parse_EPOCH (struct lexer *lexer)
480 {
481   if (lex_match_id (lexer, "AUTOMATIC"))
482     settings_set_epoch (-1);
483   else if (lex_is_integer (lexer))
484     {
485       if (!lex_force_int_range (lexer, "EPOCH", 1500, INT_MAX))
486         return false;
487       settings_set_epoch (lex_integer (lexer));
488       lex_get (lexer);
489     }
490   else
491     {
492       lex_error (lexer, _("Syntax error expecting %s or year."), "AUTOMATIC");
493       return false;
494     }
495
496   return true;
497 }
498
499 static char *
500 show_EPOCH (const struct dataset *ds UNUSED)
501 {
502   return xasprintf ("%d", settings_get_epoch ());
503 }
504
505 static bool
506 parse_ERRORS (struct lexer *lexer)
507 {
508   return parse_output_routing (lexer, SETTINGS_OUTPUT_ERROR);
509 }
510
511 static char *
512 show_ERRORS (const struct dataset *ds UNUSED)
513 {
514   return show_output_routing (SETTINGS_OUTPUT_ERROR);
515 }
516
517 static bool
518 parse_FORMAT (struct lexer *lexer)
519 {
520   int start = subcommand_start_ofs (lexer);
521   struct fmt_spec fmt;
522
523   if (!parse_format_specifier (lexer, &fmt))
524     return false;
525
526   if (!fmt_check_output (&fmt))
527     return false;
528
529   int end = lex_ofs (lexer) - 1;
530   if (fmt_is_string (fmt.type))
531     {
532       char str[FMT_STRING_LEN_MAX + 1];
533       lex_ofs_error (lexer, start, end,
534                      _("%s requires numeric output format as an argument.  "
535                        "Specified format %s is of type string."),
536                      "FORMAT", fmt_to_string (&fmt, str));
537       return false;
538     }
539
540   settings_set_format (&fmt);
541   return true;
542 }
543
544 static char *
545 show_FORMAT (const struct dataset *ds UNUSED)
546 {
547   char str[FMT_STRING_LEN_MAX + 1];
548   return xstrdup (fmt_to_string (settings_get_format (), str));
549 }
550
551 static bool
552 parse_FUZZBITS (struct lexer *lexer)
553 {
554   if (!lex_force_int_range (lexer, "FUZZITS", 0, 20))
555     return false;
556   settings_set_fuzzbits (lex_integer (lexer));
557   lex_get (lexer);
558   return true;
559 }
560
561 static char *
562 show_FUZZBITS (const struct dataset *ds UNUSED)
563 {
564   return xasprintf ("%d", settings_get_fuzzbits ());
565 }
566
567 static bool
568 parse_HEADER (struct lexer *lexer)
569 {
570   return parse_unimplemented (lexer, "HEADER");
571 }
572
573 static bool
574 parse_INCLUDE (struct lexer *lexer)
575 {
576   int include = force_parse_bool (lexer);
577   if (include != -1)
578     settings_set_include (include);
579   return include != -1;
580 }
581
582 static char *
583 show_INCLUDE (const struct dataset *ds UNUSED)
584 {
585   return xstrdup (settings_get_include () ? "ON" : "OFF");
586 }
587
588 static bool
589 parse_JOURNAL (struct lexer *lexer)
590 {
591   int b = parse_bool (lexer);
592   if (b == true)
593     journal_enable ();
594   else if (b == false)
595     journal_disable ();
596   else if (lex_is_string (lexer) || lex_token (lexer) == T_ID)
597     {
598       char *filename = utf8_to_filename (lex_tokcstr (lexer));
599       journal_set_file_name (filename);
600       free (filename);
601
602       lex_get (lexer);
603     }
604   else
605     {
606       lex_error (lexer, NULL);
607       return false;
608     }
609   return true;
610 }
611
612 static char *
613 show_JOURNAL (const struct dataset *ds UNUSED)
614 {
615   const char *enabled = journal_is_enabled () ? "ON" : "OFF";
616   const char *file_name = journal_get_file_name ();
617   return (file_name
618           ? xasprintf ("%s (%s)", enabled, file_name)
619           : xstrdup (enabled));
620 }
621
622 static bool
623 parse_LEADZERO (struct lexer *lexer)
624 {
625   int leadzero = force_parse_bool (lexer);
626   if (leadzero != -1)
627     settings_set_include_leading_zero (leadzero);
628   return leadzero != -1;
629 }
630
631 static char *
632 show_LEADZERO (const struct dataset *ds UNUSED)
633 {
634   bool leadzero = settings_get_fmt_settings ()->include_leading_zero;
635   return xstrdup (leadzero ? "ON" : "OFF");
636 }
637
638 static bool
639 parse_LENGTH (struct lexer *lexer)
640 {
641   int page_length;
642
643   if (lex_match_id (lexer, "NONE"))
644     page_length = -1;
645   else
646     {
647       if (!lex_force_int_range (lexer, "LENGTH", 1, INT_MAX))
648         return false;
649       page_length = lex_integer (lexer);
650       lex_get (lexer);
651     }
652
653   if (page_length != -1)
654     settings_set_viewlength (page_length);
655
656   return true;
657 }
658
659 static char *
660 show_LENGTH (const struct dataset *ds UNUSED)
661 {
662   return xasprintf ("%d", settings_get_viewlength ());
663 }
664
665 static bool
666 parse_LOCALE (struct lexer *lexer)
667 {
668   if (!lex_force_string (lexer))
669     return false;
670
671   /* Try the argument as an encoding name, then as a locale name or alias. */
672   const char *s = lex_tokcstr (lexer);
673   if (valid_encoding (s))
674     set_default_encoding (s);
675   else if (!set_encoding_from_locale (s))
676     {
677       lex_error (lexer, _("%s is not a recognized encoding or locale name"), s);
678       return false;
679     }
680
681   lex_get (lexer);
682   return true;
683 }
684
685 static char *
686 show_LOCALE (const struct dataset *ds UNUSED)
687 {
688   return xstrdup (get_default_encoding ());
689 }
690
691 static bool
692 parse_MDISPLAY (struct lexer *lexer)
693 {
694   int mdisplay = force_parse_enum (lexer,
695                                    "TEXT", SETTINGS_MDISPLAY_TEXT,
696                                    "TABLES", SETTINGS_MDISPLAY_TABLES);
697   if (mdisplay >= 0)
698     settings_set_mdisplay (mdisplay);
699   return mdisplay >= 0;
700 }
701
702 static char *
703 show_MDISPLAY (const struct dataset *ds UNUSED)
704 {
705   return xstrdup (settings_get_mdisplay () == SETTINGS_MDISPLAY_TEXT
706                   ? "TEXT" : "TABLES");
707 }
708
709 static bool
710 parse_MESSAGES (struct lexer *lexer)
711 {
712   return parse_output_routing (lexer, SETTINGS_OUTPUT_NOTE);
713 }
714
715 static char *
716 show_MESSAGES (const struct dataset *ds UNUSED)
717 {
718   return show_output_routing (SETTINGS_OUTPUT_NOTE);
719 }
720
721 static bool
722 parse_MEXPAND (struct lexer *lexer)
723 {
724   int mexpand = force_parse_bool (lexer);
725   if (mexpand != -1)
726     settings_set_mexpand (mexpand);
727   return mexpand != -1;
728 }
729
730 static char *
731 show_MEXPAND (const struct dataset *ds UNUSED)
732 {
733   return xstrdup (settings_get_mexpand () ? "ON" : "OFF");
734 }
735
736 static bool
737 parse_MITERATE (struct lexer *lexer)
738 {
739   if (!lex_force_int_range (lexer, "MITERATE", 1, INT_MAX))
740     return false;
741   settings_set_miterate (lex_integer (lexer));
742   lex_get (lexer);
743   return true;
744 }
745
746 static char *
747 show_MITERATE (const struct dataset *ds UNUSED)
748 {
749   return xasprintf ("%d", settings_get_miterate ());
750 }
751
752 static bool
753 parse_MNEST (struct lexer *lexer)
754 {
755   if (!lex_force_int_range (lexer, "MNEST", 1, INT_MAX))
756     return false;
757   settings_set_mnest (lex_integer (lexer));
758   lex_get (lexer);
759   return true;
760 }
761
762 static char *
763 show_MNEST (const struct dataset *ds UNUSED)
764 {
765   return xasprintf ("%d", settings_get_mnest ());
766 }
767
768 static bool
769 parse_MPRINT (struct lexer *lexer)
770 {
771   int mprint = force_parse_bool (lexer);
772   if (mprint != -1)
773     settings_set_mprint (mprint);
774   return mprint != -1;
775 }
776
777 static char *
778 show_MPRINT (const struct dataset *ds UNUSED)
779 {
780   return xstrdup (settings_get_mprint () ? "ON" : "OFF");
781 }
782
783 static bool
784 parse_MXERRS (struct lexer *lexer)
785 {
786   if (!lex_force_int_range (lexer, "MXERRS", 1, INT_MAX))
787     return false;
788   settings_set_max_messages (MSG_S_ERROR, lex_integer (lexer));
789   lex_get (lexer);
790   return true;
791 }
792
793 static char *
794 show_MXERRS (const struct dataset *ds UNUSED)
795 {
796   return xasprintf ("%d", settings_get_max_messages (MSG_S_ERROR));
797 }
798
799 static bool
800 parse_MXLOOPS (struct lexer *lexer)
801 {
802   if (!lex_force_int_range (lexer, "MXLOOPS", 1, INT_MAX))
803     return false;
804   settings_set_mxloops (lex_integer (lexer));
805   lex_get (lexer);
806   return true;
807 }
808
809 static char *
810 show_MXLOOPS (const struct dataset *ds UNUSED)
811 {
812   return xasprintf ("%d", settings_get_mxloops ());
813 }
814
815 static bool
816 parse_MXWARNS (struct lexer *lexer)
817 {
818   if (!lex_force_int_range (lexer, "MXWARNS", 0, INT_MAX))
819     return false;
820   settings_set_max_messages (MSG_S_WARNING, lex_integer (lexer));
821   lex_get (lexer);
822   return true;
823 }
824
825 static char *
826 show_MXWARNS (const struct dataset *ds UNUSED)
827 {
828   return xasprintf ("%d", settings_get_max_messages (MSG_S_WARNING));
829 }
830
831 static bool
832 parse_PRINTBACK (struct lexer *lexer)
833 {
834   return parse_output_routing (lexer, SETTINGS_OUTPUT_SYNTAX);
835 }
836
837 static char *
838 show_PRINTBACK (const struct dataset *ds UNUSED)
839 {
840   return show_output_routing (SETTINGS_OUTPUT_SYNTAX);
841 }
842
843 static bool
844 parse_RESULTS (struct lexer *lexer)
845 {
846   return parse_output_routing (lexer, SETTINGS_OUTPUT_RESULT);
847 }
848
849 static char *
850 show_RESULTS (const struct dataset *ds UNUSED)
851 {
852   return show_output_routing (SETTINGS_OUTPUT_RESULT);
853 }
854
855 static bool
856 parse_RIB (struct lexer *lexer)
857 {
858   return parse_integer_format (lexer, settings_set_input_integer_format);
859 }
860
861 static char *
862 show_RIB (const struct dataset *ds UNUSED)
863 {
864   return show_integer_format (settings_get_input_integer_format ());
865 }
866
867 static bool
868 parse_RRB (struct lexer *lexer)
869 {
870   return parse_real_format (lexer, settings_set_input_float_format);
871 }
872
873 static char *
874 show_RRB (const struct dataset *ds UNUSED)
875 {
876   return show_real_format (settings_get_input_float_format ());
877 }
878
879 static bool
880 parse_SAFER (struct lexer *lexer)
881 {
882   bool ok = force_parse_enum (lexer, "ON", true, "YES", true) != -1;
883   if (ok)
884     settings_set_safer_mode ();
885   return ok;
886 }
887
888 static char *
889 show_SAFER (const struct dataset *ds UNUSED)
890 {
891   return xstrdup (settings_get_safer_mode () ? "ON" : "OFF");
892 }
893
894 static bool
895 parse_SCOMPRESSION (struct lexer *lexer)
896 {
897   int value = force_parse_bool (lexer);
898   if (value >= 0)
899     settings_set_scompression (value);
900   return value >= 0;
901 }
902
903 static char *
904 show_SCOMPRESSION (const struct dataset *ds UNUSED)
905 {
906   return xstrdup (settings_get_scompression () ? "ON" : "OFF");
907 }
908
909 static bool
910 parse_SEED (struct lexer *lexer)
911 {
912   if (lex_match_id (lexer, "RANDOM"))
913     set_rng (time (0));
914   else
915     {
916       if (!lex_force_num (lexer))
917         return false;
918       set_rng (lex_number (lexer));
919       lex_get (lexer);
920     }
921
922   return true;
923 }
924
925 static bool
926 parse_SMALL (struct lexer *lexer)
927 {
928   if (!lex_force_num (lexer))
929     return false;
930   settings_set_small (lex_number (lexer));
931   lex_get (lexer);
932   return true;
933 }
934
935 static char *
936 show_SMALL (const struct dataset *ds UNUSED)
937 {
938   char buf[DBL_BUFSIZE_BOUND];
939   if (dtoastr (buf, sizeof buf, 0, 0, settings_get_small ()) < 0)
940     abort ();
941   return xstrdup (buf);
942 }
943
944 static char *
945 show_SUBTITLE (const struct dataset *ds UNUSED)
946 {
947   return xstrdup (output_get_subtitle ());
948 }
949
950 static char *
951 show_TEMPDIR (const struct dataset *ds UNUSED)
952 {
953   return xstrdup (temp_dir_name ());
954 }
955
956 static char *
957 show_TITLE (const struct dataset *ds UNUSED)
958 {
959   return xstrdup (output_get_title ());
960 }
961
962 static bool
963 parse_TNUMBERS (struct lexer *lexer)
964 {
965   int value = force_parse_enum (lexer,
966                                 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
967                                 "VALUES", SETTINGS_VALUE_SHOW_VALUE,
968                                 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
969   if (value >= 0)
970     settings_set_show_values (value);
971   return value >= 0;
972 }
973
974 static char *
975 show_TNUMBERS (const struct dataset *ds UNUSED)
976 {
977   enum settings_value_show tnumbers = settings_get_show_values ();
978   return xstrdup (tnumbers == SETTINGS_VALUE_SHOW_LABEL ? "LABELS"
979                   : tnumbers == SETTINGS_VALUE_SHOW_VALUE ? "VALUES"
980                   : "BOTH");
981 }
982
983 static bool
984 parse_TVARS (struct lexer *lexer)
985 {
986   int value = force_parse_enum (lexer,
987                                 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
988                                 "NAMES", SETTINGS_VALUE_SHOW_VALUE,
989                                 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
990   if (value >= 0)
991     settings_set_show_variables (value);
992   return value >= 0;
993 }
994
995 static char *
996 show_TVARS (const struct dataset *ds UNUSED)
997 {
998   enum settings_value_show tvars = settings_get_show_variables ();
999   return xstrdup (tvars == SETTINGS_VALUE_SHOW_LABEL ? "LABELS"
1000                   : tvars == SETTINGS_VALUE_SHOW_VALUE ? "NAMES"
1001                   : "BOTH");
1002 }
1003
1004 static bool
1005 parse_TLOOK (struct lexer *lexer)
1006 {
1007   if (lex_match_id (lexer, "NONE"))
1008     pivot_table_look_set_default (pivot_table_look_builtin_default ());
1009   else if (lex_is_string (lexer))
1010     {
1011       struct pivot_table_look *look;
1012       char *error = pivot_table_look_read (lex_tokcstr (lexer), &look);
1013       lex_get (lexer);
1014
1015       if (error)
1016         {
1017           msg (SE, "%s", error);
1018           free (error);
1019           return false;
1020         }
1021
1022       pivot_table_look_set_default (look);
1023       pivot_table_look_unref (look);
1024     }
1025
1026   return true;
1027 }
1028
1029 static bool
1030 parse_UNDEFINED (struct lexer *lexer)
1031 {
1032   int value = force_parse_enum (lexer,
1033                                 "WARN", true,
1034                                 "NOWARN", false);
1035   if (value >= 0)
1036     settings_set_undefined (value);
1037   return value >= 0;
1038 }
1039
1040 static char *
1041 show_UNDEFINED (const struct dataset *ds UNUSED)
1042 {
1043   return xstrdup (settings_get_undefined () ? "WARN" : "NOWARN");
1044 }
1045
1046 static char *
1047 show_VERSION (const struct dataset *ds UNUSED)
1048 {
1049   return strdup (announced_version);
1050 }
1051
1052 static char *
1053 show_WEIGHT (const struct dataset *ds)
1054 {
1055   const struct variable *var = dict_get_weight (dataset_dict (ds));
1056   return xstrdup (var != NULL ? var_get_name (var) : "OFF");
1057 }
1058
1059 static bool
1060 parse_WIB (struct lexer *lexer)
1061 {
1062   return parse_integer_format (lexer, settings_set_output_integer_format);
1063 }
1064
1065 static char *
1066 show_WIB (const struct dataset *ds UNUSED)
1067 {
1068   return show_integer_format (settings_get_output_integer_format ());
1069 }
1070
1071 static bool
1072 parse_WRB (struct lexer *lexer)
1073 {
1074   return parse_real_format (lexer, settings_set_output_float_format);
1075 }
1076
1077 static char *
1078 show_WRB (const struct dataset *ds UNUSED)
1079 {
1080   return show_real_format (settings_get_output_float_format ());
1081 }
1082
1083 static bool
1084 parse_WIDTH (struct lexer *lexer)
1085 {
1086   if (lex_match_id (lexer, "NARROW"))
1087     settings_set_viewwidth (79);
1088   else if (lex_match_id (lexer, "WIDE"))
1089     settings_set_viewwidth (131);
1090   else
1091     {
1092       if (!lex_force_int_range (lexer, "WIDTH", 40, INT_MAX))
1093         return false;
1094       settings_set_viewwidth (lex_integer (lexer));
1095       lex_get (lexer);
1096     }
1097
1098   return true;
1099 }
1100
1101 static char *
1102 show_WIDTH (const struct dataset *ds UNUSED)
1103 {
1104   return xasprintf ("%d", settings_get_viewwidth ());
1105 }
1106
1107 static bool
1108 parse_WORKSPACE (struct lexer *lexer)
1109 {
1110   if (!lex_force_int_range (lexer, "WORKSPACE",
1111                             settings_get_testing_mode () ? 1 : 1024,
1112                             INT_MAX))
1113     return false;
1114   int workspace = lex_integer (lexer);
1115   lex_get (lexer);
1116   settings_set_workspace (MIN (workspace, INT_MAX / 1024) * 1024);
1117   return true;
1118 }
1119
1120 static char *
1121 show_WORKSPACE (const struct dataset *ds UNUSED)
1122 {
1123   size_t ws = settings_get_workspace () / 1024L;
1124   return xasprintf ("%zu", ws);
1125 }
1126 \f
1127 static char *
1128 show_DIRECTORY (const struct dataset *ds UNUSED)
1129 {
1130   char *buf = NULL;
1131   char *wd = NULL;
1132   size_t len = 256;
1133
1134   do
1135     {
1136       len <<= 1;
1137       buf = xrealloc (buf, len);
1138     }
1139   while (NULL == (wd = getcwd (buf, len)));
1140
1141   return wd;
1142 }
1143
1144 static char *
1145 show_N (const struct dataset *ds)
1146 {
1147   const struct casereader *reader = dataset_source (ds);
1148   return (reader
1149           ? xasprintf ("%lld", (long long int) casereader_count_cases (reader))
1150           : xstrdup (_("Unknown")));
1151 }
1152
1153 static void
1154 do_show (const struct dataset *ds, const struct setting *s,
1155          struct pivot_table **ptp)
1156 {
1157   struct pivot_table *pt = *ptp;
1158   if (!pt)
1159     {
1160       pt = *ptp = pivot_table_create (N_("Settings"));
1161       pivot_dimension_create (pt, PIVOT_AXIS_ROW, N_("Setting"));
1162     }
1163
1164   struct pivot_value *name = pivot_value_new_user_text (s->name, SIZE_MAX);
1165   char *text = s->show (ds);
1166   if (!text)
1167     text = xstrdup("empty");
1168   struct pivot_value *value = pivot_value_new_user_text_nocopy (text);
1169
1170   int row = pivot_category_create_leaf (pt->dimensions[0]->root, name);
1171   pivot_table_put1 (pt, row, value);
1172 }
1173
1174 static void
1175 show_warranty (const struct dataset *ds UNUSED)
1176 {
1177   fputs (lack_of_warranty, stdout);
1178 }
1179
1180 static void
1181 show_copying (const struct dataset *ds UNUSED)
1182 {
1183   fputs (copyleft, stdout);
1184 }
1185
1186 static void
1187 add_row (struct pivot_table *table, const char *attribute,
1188          const char *value)
1189 {
1190   int row = pivot_category_create_leaf (table->dimensions[0]->root,
1191                                         pivot_value_new_text (attribute));
1192   if (value)
1193     pivot_table_put1 (table, row, pivot_value_new_user_text (value, -1));
1194 }
1195
1196 static void
1197 show_system (const struct dataset *ds UNUSED)
1198 {
1199   struct pivot_table *table = pivot_table_create (N_("System Information"));
1200   pivot_dimension_create (table, PIVOT_AXIS_ROW, N_("Attribute"));
1201
1202   add_row (table, N_("Version"), version);
1203   add_row (table, N_("Host System"), host_system);
1204   add_row (table, N_("Build System"), build_system);
1205   add_row (table, N_("Locale Directory"), relocate (locale_dir));
1206   add_row (table, N_("Compiler Version"),
1207 #ifdef __VERSION__
1208            __VERSION__
1209 #else
1210            "Unknown"
1211 #endif
1212            );
1213   pivot_table_submit (table);
1214 }
1215 \f
1216 static const struct setting settings[] = {
1217   { "BASETEXTDIRECTION", parse_BASETEXTDIRECTION, NULL },
1218   { "BLANKS", parse_BLANKS, show_BLANKS },
1219   { "BLOCK", parse_BLOCK, NULL },
1220   { "BOX", parse_BOX, NULL },
1221   { "CACHE", parse_CACHE, NULL },
1222   { "CCA", parse_CCA, show_CCA },
1223   { "CCB", parse_CCB, show_CCB },
1224   { "CCC", parse_CCC, show_CCC },
1225   { "CCD", parse_CCD, show_CCD },
1226   { "CCE", parse_CCE, show_CCE },
1227   { "CELLSBREAK", parse_CELLSBREAK, NULL },
1228   { "CMPTRANS", parse_CMPTRANS, NULL },
1229   { "COMPRESSION", parse_COMPRESSION, NULL },
1230   { "CTEMPLATE", parse_CTEMPLATE, NULL },
1231   { "DECIMAL", parse_DECIMAL, show_DECIMAL },
1232   { "DIRECTORY", NULL, show_DIRECTORY },
1233   { "EPOCH", parse_EPOCH, show_EPOCH },
1234   { "ERRORS", parse_ERRORS, show_ERRORS },
1235   { "FORMAT", parse_FORMAT, show_FORMAT },
1236   { "FUZZBITS", parse_FUZZBITS, show_FUZZBITS },
1237   { "HEADER", parse_HEADER, NULL },
1238   { "INCLUDE", parse_INCLUDE, show_INCLUDE },
1239   { "JOURNAL", parse_JOURNAL, show_JOURNAL },
1240   { "LEADZERO", parse_LEADZERO, show_LEADZERO },
1241   { "LENGTH", parse_LENGTH, show_LENGTH },
1242   { "LOCALE", parse_LOCALE, show_LOCALE },
1243   { "MDISPLAY", parse_MDISPLAY, show_MDISPLAY },
1244   { "MESSAGES", parse_MESSAGES, show_MESSAGES },
1245   { "MEXPAND", parse_MEXPAND, show_MEXPAND },
1246   { "MITERATE", parse_MITERATE, show_MITERATE },
1247   { "MNEST", parse_MNEST, show_MNEST },
1248   { "MPRINT", parse_MPRINT, show_MPRINT },
1249   { "MXERRS", parse_MXERRS, show_MXERRS },
1250   { "MXLOOPS", parse_MXLOOPS, show_MXLOOPS },
1251   { "MXWARNS", parse_MXWARNS, show_MXWARNS },
1252   { "N", NULL, show_N },
1253   { "PRINTBACK", parse_PRINTBACK, show_PRINTBACK },
1254   { "RESULTS", parse_RESULTS, show_RESULTS },
1255   { "RIB", parse_RIB, show_RIB },
1256   { "RRB", parse_RRB, show_RRB },
1257   { "SAFER", parse_SAFER, show_SAFER },
1258   { "SCOMPRESSION", parse_SCOMPRESSION, show_SCOMPRESSION },
1259   { "SEED", parse_SEED, NULL },
1260   { "SMALL", parse_SMALL, show_SMALL },
1261   { "TEMPDIR", NULL, show_TEMPDIR },
1262   { "TNUMBERS", parse_TNUMBERS, show_TNUMBERS },
1263   { "TVARS", parse_TVARS, show_TVARS },
1264   { "TLOOK", parse_TLOOK, NULL },
1265   { "UNDEFINED", parse_UNDEFINED, show_UNDEFINED },
1266   { "VERSION", NULL, show_VERSION },
1267   { "WEIGHT", NULL, show_WEIGHT },
1268   { "WIB", parse_WIB, show_WIB },
1269   { "WRB", parse_WRB, show_WRB },
1270   { "WIDTH", parse_WIDTH, show_WIDTH },
1271   { "WORKSPACE", parse_WORKSPACE, show_WORKSPACE },
1272 };
1273 enum { N_SETTINGS = sizeof settings / sizeof *settings };
1274
1275 static bool
1276 parse_setting (struct lexer *lexer)
1277 {
1278   for (size_t i = 0; i < N_SETTINGS; i++)
1279     if (settings[i].set && match_subcommand (lexer, settings[i].name))
1280         return settings[i].set (lexer);
1281
1282   lex_error (lexer, NULL);
1283   return false;
1284 }
1285
1286 int
1287 cmd_set (struct lexer *lexer, struct dataset *ds UNUSED)
1288 {
1289   for (;;)
1290     {
1291       lex_match (lexer, T_SLASH);
1292       if (lex_token (lexer) == T_ENDCMD)
1293         break;
1294
1295       if (!parse_setting (lexer))
1296         return CMD_FAILURE;
1297     }
1298
1299   return CMD_SUCCESS;
1300 }
1301
1302 static void
1303 show_all (const struct dataset *ds, struct pivot_table **ptp)
1304 {
1305   for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
1306     if (settings[i].show)
1307       do_show (ds, &settings[i], ptp);
1308 }
1309
1310 static void
1311 show_all_cc (const struct dataset *ds, struct pivot_table **ptp)
1312 {
1313   for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
1314     {
1315       const struct setting *s = &settings[i];
1316       if (s->show && !strncmp (s->name, "CC", 2))
1317         do_show (ds, s, ptp);
1318     }
1319 }
1320
1321 int
1322 cmd_show (struct lexer *lexer, struct dataset *ds)
1323 {
1324   struct pivot_table *pt = NULL;
1325   if (lex_token (lexer) == T_ENDCMD)
1326     {
1327       show_all (ds, &pt);
1328       pivot_table_submit (pt);
1329       return CMD_SUCCESS;
1330     }
1331
1332   do
1333     {
1334       if (lex_match (lexer, T_ALL))
1335         show_all (ds, &pt);
1336       else if (lex_match_id (lexer, "CC"))
1337         show_all_cc (ds, &pt);
1338       else if (lex_match_id (lexer, "WARRANTY"))
1339         show_warranty (ds);
1340       else if (lex_match_id (lexer, "COPYING") || lex_match_id (lexer, "LICENSE"))
1341         show_copying (ds);
1342       else if (lex_match_id (lexer, "SYSTEM"))
1343         show_system (ds);
1344       else if (lex_match_id (lexer, "TITLE"))
1345         {
1346           struct setting s = { .name = "TITLE", .show = show_TITLE };
1347           do_show (ds, &s, &pt);
1348         }
1349       else if (lex_match_id (lexer, "SUBTITLE"))
1350         {
1351           struct setting s = { .name = "SUBTITLE", .show = show_SUBTITLE };
1352           do_show (ds, &s, &pt);
1353         }
1354       else if (lex_token (lexer) == T_ID)
1355         {
1356           int i;
1357
1358           for (i = 0; i < sizeof settings / sizeof *settings; i++)
1359             {
1360               const struct setting *s = &settings[i];
1361               if (s->show && lex_match_id (lexer, s->name))
1362                 {
1363                   do_show (ds, s, &pt);
1364                   goto found;
1365                 }
1366               }
1367           lex_error (lexer, NULL);
1368           return CMD_FAILURE;
1369
1370         found: ;
1371         }
1372       else
1373         {
1374           lex_error (lexer, NULL);
1375           return CMD_FAILURE;
1376         }
1377
1378       lex_match (lexer, T_SLASH);
1379     }
1380   while (lex_token (lexer) != T_ENDCMD);
1381
1382   if (pt)
1383     pivot_table_submit (pt);
1384
1385   return CMD_SUCCESS;
1386 }
1387 \f
1388 #define MAX_SAVED_SETTINGS 5
1389
1390 static struct settings *saved_settings[MAX_SAVED_SETTINGS];
1391 static int n_saved_settings;
1392
1393 int
1394 cmd_preserve (struct lexer *lexer, struct dataset *ds UNUSED)
1395 {
1396   if (n_saved_settings < MAX_SAVED_SETTINGS)
1397     {
1398       saved_settings[n_saved_settings++] = settings_get ();
1399       return CMD_SUCCESS;
1400     }
1401   else
1402     {
1403       lex_next_error (lexer, -1, -1,
1404                       _("Too many %s commands without a %s: at most "
1405                         "%d levels of saved settings are allowed."),
1406                       "PRESERVE", "RESTORE",
1407                       MAX_SAVED_SETTINGS);
1408       return CMD_CASCADING_FAILURE;
1409     }
1410 }
1411
1412 int
1413 cmd_restore (struct lexer *lexer, struct dataset *ds UNUSED)
1414 {
1415   if (n_saved_settings > 0)
1416     {
1417       struct settings *s = saved_settings[--n_saved_settings];
1418       settings_set (s);
1419       settings_destroy (s);
1420       return CMD_SUCCESS;
1421     }
1422   else
1423     {
1424       lex_next_error (lexer, -1, -1,
1425                       _("%s without matching %s."), "RESTORE", "PRESERVE");
1426       return CMD_FAILURE;
1427     }
1428 }