2c867145efd9c412925953ddf59d6fd6efe74c23
[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   char *error = fmt_check_output__ (&fmt);
527   if (error)
528     {
529       lex_next_error (lexer, -1, -1, "%s", error);
530       free (error);
531       return false;
532     }
533
534   int end = lex_ofs (lexer) - 1;
535   if (fmt_is_string (fmt.type))
536     {
537       char str[FMT_STRING_LEN_MAX + 1];
538       lex_ofs_error (lexer, start, end,
539                      _("%s requires numeric output format as an argument.  "
540                        "Specified format %s is of type string."),
541                      "FORMAT", fmt_to_string (&fmt, str));
542       return false;
543     }
544
545   settings_set_format (&fmt);
546   return true;
547 }
548
549 static char *
550 show_FORMAT (const struct dataset *ds UNUSED)
551 {
552   char str[FMT_STRING_LEN_MAX + 1];
553   return xstrdup (fmt_to_string (settings_get_format (), str));
554 }
555
556 static bool
557 parse_FUZZBITS (struct lexer *lexer)
558 {
559   if (!lex_force_int_range (lexer, "FUZZITS", 0, 20))
560     return false;
561   settings_set_fuzzbits (lex_integer (lexer));
562   lex_get (lexer);
563   return true;
564 }
565
566 static char *
567 show_FUZZBITS (const struct dataset *ds UNUSED)
568 {
569   return xasprintf ("%d", settings_get_fuzzbits ());
570 }
571
572 static bool
573 parse_HEADER (struct lexer *lexer)
574 {
575   return parse_unimplemented (lexer, "HEADER");
576 }
577
578 static bool
579 parse_INCLUDE (struct lexer *lexer)
580 {
581   int include = force_parse_bool (lexer);
582   if (include != -1)
583     settings_set_include (include);
584   return include != -1;
585 }
586
587 static char *
588 show_INCLUDE (const struct dataset *ds UNUSED)
589 {
590   return xstrdup (settings_get_include () ? "ON" : "OFF");
591 }
592
593 static bool
594 parse_JOURNAL (struct lexer *lexer)
595 {
596   int b = parse_bool (lexer);
597   if (b == true)
598     journal_enable ();
599   else if (b == false)
600     journal_disable ();
601   else if (lex_is_string (lexer) || lex_token (lexer) == T_ID)
602     {
603       char *filename = utf8_to_filename (lex_tokcstr (lexer));
604       journal_set_file_name (filename);
605       free (filename);
606
607       lex_get (lexer);
608     }
609   else
610     {
611       lex_error (lexer, NULL);
612       return false;
613     }
614   return true;
615 }
616
617 static char *
618 show_JOURNAL (const struct dataset *ds UNUSED)
619 {
620   const char *enabled = journal_is_enabled () ? "ON" : "OFF";
621   const char *file_name = journal_get_file_name ();
622   return (file_name
623           ? xasprintf ("%s (%s)", enabled, file_name)
624           : xstrdup (enabled));
625 }
626
627 static bool
628 parse_LEADZERO (struct lexer *lexer)
629 {
630   int leadzero = force_parse_bool (lexer);
631   if (leadzero != -1)
632     settings_set_include_leading_zero (leadzero);
633   return leadzero != -1;
634 }
635
636 static char *
637 show_LEADZERO (const struct dataset *ds UNUSED)
638 {
639   bool leadzero = settings_get_fmt_settings ()->include_leading_zero;
640   return xstrdup (leadzero ? "ON" : "OFF");
641 }
642
643 static bool
644 parse_LENGTH (struct lexer *lexer)
645 {
646   int page_length;
647
648   if (lex_match_id (lexer, "NONE"))
649     page_length = -1;
650   else
651     {
652       if (!lex_force_int_range (lexer, "LENGTH", 1, INT_MAX))
653         return false;
654       page_length = lex_integer (lexer);
655       lex_get (lexer);
656     }
657
658   if (page_length != -1)
659     settings_set_viewlength (page_length);
660
661   return true;
662 }
663
664 static char *
665 show_LENGTH (const struct dataset *ds UNUSED)
666 {
667   return xasprintf ("%d", settings_get_viewlength ());
668 }
669
670 static bool
671 parse_LOCALE (struct lexer *lexer)
672 {
673   if (!lex_force_string (lexer))
674     return false;
675
676   /* Try the argument as an encoding name, then as a locale name or alias. */
677   const char *s = lex_tokcstr (lexer);
678   if (valid_encoding (s))
679     set_default_encoding (s);
680   else if (!set_encoding_from_locale (s))
681     {
682       lex_error (lexer, _("%s is not a recognized encoding or locale name"), s);
683       return false;
684     }
685
686   lex_get (lexer);
687   return true;
688 }
689
690 static char *
691 show_LOCALE (const struct dataset *ds UNUSED)
692 {
693   return xstrdup (get_default_encoding ());
694 }
695
696 static bool
697 parse_MDISPLAY (struct lexer *lexer)
698 {
699   int mdisplay = force_parse_enum (lexer,
700                                    "TEXT", SETTINGS_MDISPLAY_TEXT,
701                                    "TABLES", SETTINGS_MDISPLAY_TABLES);
702   if (mdisplay >= 0)
703     settings_set_mdisplay (mdisplay);
704   return mdisplay >= 0;
705 }
706
707 static char *
708 show_MDISPLAY (const struct dataset *ds UNUSED)
709 {
710   return xstrdup (settings_get_mdisplay () == SETTINGS_MDISPLAY_TEXT
711                   ? "TEXT" : "TABLES");
712 }
713
714 static bool
715 parse_MESSAGES (struct lexer *lexer)
716 {
717   return parse_output_routing (lexer, SETTINGS_OUTPUT_NOTE);
718 }
719
720 static char *
721 show_MESSAGES (const struct dataset *ds UNUSED)
722 {
723   return show_output_routing (SETTINGS_OUTPUT_NOTE);
724 }
725
726 static bool
727 parse_MEXPAND (struct lexer *lexer)
728 {
729   int mexpand = force_parse_bool (lexer);
730   if (mexpand != -1)
731     settings_set_mexpand (mexpand);
732   return mexpand != -1;
733 }
734
735 static char *
736 show_MEXPAND (const struct dataset *ds UNUSED)
737 {
738   return xstrdup (settings_get_mexpand () ? "ON" : "OFF");
739 }
740
741 static bool
742 parse_MITERATE (struct lexer *lexer)
743 {
744   if (!lex_force_int_range (lexer, "MITERATE", 1, INT_MAX))
745     return false;
746   settings_set_miterate (lex_integer (lexer));
747   lex_get (lexer);
748   return true;
749 }
750
751 static char *
752 show_MITERATE (const struct dataset *ds UNUSED)
753 {
754   return xasprintf ("%d", settings_get_miterate ());
755 }
756
757 static bool
758 parse_MNEST (struct lexer *lexer)
759 {
760   if (!lex_force_int_range (lexer, "MNEST", 1, INT_MAX))
761     return false;
762   settings_set_mnest (lex_integer (lexer));
763   lex_get (lexer);
764   return true;
765 }
766
767 static char *
768 show_MNEST (const struct dataset *ds UNUSED)
769 {
770   return xasprintf ("%d", settings_get_mnest ());
771 }
772
773 static bool
774 parse_MPRINT (struct lexer *lexer)
775 {
776   int mprint = force_parse_bool (lexer);
777   if (mprint != -1)
778     settings_set_mprint (mprint);
779   return mprint != -1;
780 }
781
782 static char *
783 show_MPRINT (const struct dataset *ds UNUSED)
784 {
785   return xstrdup (settings_get_mprint () ? "ON" : "OFF");
786 }
787
788 static bool
789 parse_MXERRS (struct lexer *lexer)
790 {
791   if (!lex_force_int_range (lexer, "MXERRS", 1, INT_MAX))
792     return false;
793   settings_set_max_messages (MSG_S_ERROR, lex_integer (lexer));
794   lex_get (lexer);
795   return true;
796 }
797
798 static char *
799 show_MXERRS (const struct dataset *ds UNUSED)
800 {
801   return xasprintf ("%d", settings_get_max_messages (MSG_S_ERROR));
802 }
803
804 static bool
805 parse_MXLOOPS (struct lexer *lexer)
806 {
807   if (!lex_force_int_range (lexer, "MXLOOPS", 1, INT_MAX))
808     return false;
809   settings_set_mxloops (lex_integer (lexer));
810   lex_get (lexer);
811   return true;
812 }
813
814 static char *
815 show_MXLOOPS (const struct dataset *ds UNUSED)
816 {
817   return xasprintf ("%d", settings_get_mxloops ());
818 }
819
820 static bool
821 parse_MXWARNS (struct lexer *lexer)
822 {
823   if (!lex_force_int_range (lexer, "MXWARNS", 0, INT_MAX))
824     return false;
825   settings_set_max_messages (MSG_S_WARNING, lex_integer (lexer));
826   lex_get (lexer);
827   return true;
828 }
829
830 static char *
831 show_MXWARNS (const struct dataset *ds UNUSED)
832 {
833   return xasprintf ("%d", settings_get_max_messages (MSG_S_WARNING));
834 }
835
836 static bool
837 parse_PRINTBACK (struct lexer *lexer)
838 {
839   return parse_output_routing (lexer, SETTINGS_OUTPUT_SYNTAX);
840 }
841
842 static char *
843 show_PRINTBACK (const struct dataset *ds UNUSED)
844 {
845   return show_output_routing (SETTINGS_OUTPUT_SYNTAX);
846 }
847
848 static bool
849 parse_RESULTS (struct lexer *lexer)
850 {
851   return parse_output_routing (lexer, SETTINGS_OUTPUT_RESULT);
852 }
853
854 static char *
855 show_RESULTS (const struct dataset *ds UNUSED)
856 {
857   return show_output_routing (SETTINGS_OUTPUT_RESULT);
858 }
859
860 static bool
861 parse_RIB (struct lexer *lexer)
862 {
863   return parse_integer_format (lexer, settings_set_input_integer_format);
864 }
865
866 static char *
867 show_RIB (const struct dataset *ds UNUSED)
868 {
869   return show_integer_format (settings_get_input_integer_format ());
870 }
871
872 static bool
873 parse_RRB (struct lexer *lexer)
874 {
875   return parse_real_format (lexer, settings_set_input_float_format);
876 }
877
878 static char *
879 show_RRB (const struct dataset *ds UNUSED)
880 {
881   return show_real_format (settings_get_input_float_format ());
882 }
883
884 static bool
885 parse_SAFER (struct lexer *lexer)
886 {
887   bool ok = force_parse_enum (lexer, "ON", true, "YES", true) != -1;
888   if (ok)
889     settings_set_safer_mode ();
890   return ok;
891 }
892
893 static char *
894 show_SAFER (const struct dataset *ds UNUSED)
895 {
896   return xstrdup (settings_get_safer_mode () ? "ON" : "OFF");
897 }
898
899 static bool
900 parse_SCOMPRESSION (struct lexer *lexer)
901 {
902   int value = force_parse_bool (lexer);
903   if (value >= 0)
904     settings_set_scompression (value);
905   return value >= 0;
906 }
907
908 static char *
909 show_SCOMPRESSION (const struct dataset *ds UNUSED)
910 {
911   return xstrdup (settings_get_scompression () ? "ON" : "OFF");
912 }
913
914 static bool
915 parse_SEED (struct lexer *lexer)
916 {
917   if (lex_match_id (lexer, "RANDOM"))
918     set_rng (time (0));
919   else
920     {
921       if (!lex_force_num (lexer))
922         return false;
923       set_rng (lex_number (lexer));
924       lex_get (lexer);
925     }
926
927   return true;
928 }
929
930 static bool
931 parse_SMALL (struct lexer *lexer)
932 {
933   if (!lex_force_num (lexer))
934     return false;
935   settings_set_small (lex_number (lexer));
936   lex_get (lexer);
937   return true;
938 }
939
940 static char *
941 show_SMALL (const struct dataset *ds UNUSED)
942 {
943   char buf[DBL_BUFSIZE_BOUND];
944   if (dtoastr (buf, sizeof buf, 0, 0, settings_get_small ()) < 0)
945     abort ();
946   return xstrdup (buf);
947 }
948
949 static char *
950 show_SUBTITLE (const struct dataset *ds UNUSED)
951 {
952   return xstrdup (output_get_subtitle ());
953 }
954
955 static char *
956 show_TEMPDIR (const struct dataset *ds UNUSED)
957 {
958   return xstrdup (temp_dir_name ());
959 }
960
961 static char *
962 show_TITLE (const struct dataset *ds UNUSED)
963 {
964   return xstrdup (output_get_title ());
965 }
966
967 static bool
968 parse_TNUMBERS (struct lexer *lexer)
969 {
970   int value = force_parse_enum (lexer,
971                                 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
972                                 "VALUES", SETTINGS_VALUE_SHOW_VALUE,
973                                 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
974   if (value >= 0)
975     settings_set_show_values (value);
976   return value >= 0;
977 }
978
979 static char *
980 show_TNUMBERS (const struct dataset *ds UNUSED)
981 {
982   enum settings_value_show tnumbers = settings_get_show_values ();
983   return xstrdup (tnumbers == SETTINGS_VALUE_SHOW_LABEL ? "LABELS"
984                   : tnumbers == SETTINGS_VALUE_SHOW_VALUE ? "VALUES"
985                   : "BOTH");
986 }
987
988 static bool
989 parse_TVARS (struct lexer *lexer)
990 {
991   int value = force_parse_enum (lexer,
992                                 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
993                                 "NAMES", SETTINGS_VALUE_SHOW_VALUE,
994                                 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
995   if (value >= 0)
996     settings_set_show_variables (value);
997   return value >= 0;
998 }
999
1000 static char *
1001 show_TVARS (const struct dataset *ds UNUSED)
1002 {
1003   enum settings_value_show tvars = settings_get_show_variables ();
1004   return xstrdup (tvars == SETTINGS_VALUE_SHOW_LABEL ? "LABELS"
1005                   : tvars == SETTINGS_VALUE_SHOW_VALUE ? "NAMES"
1006                   : "BOTH");
1007 }
1008
1009 static bool
1010 parse_TLOOK (struct lexer *lexer)
1011 {
1012   if (lex_match_id (lexer, "NONE"))
1013     pivot_table_look_set_default (pivot_table_look_builtin_default ());
1014   else if (lex_is_string (lexer))
1015     {
1016       struct pivot_table_look *look;
1017       char *error = pivot_table_look_read (lex_tokcstr (lexer), &look);
1018       lex_get (lexer);
1019
1020       if (error)
1021         {
1022           msg (SE, "%s", error);
1023           free (error);
1024           return false;
1025         }
1026
1027       pivot_table_look_set_default (look);
1028       pivot_table_look_unref (look);
1029     }
1030
1031   return true;
1032 }
1033
1034 static bool
1035 parse_UNDEFINED (struct lexer *lexer)
1036 {
1037   int value = force_parse_enum (lexer,
1038                                 "WARN", true,
1039                                 "NOWARN", false);
1040   if (value >= 0)
1041     settings_set_undefined (value);
1042   return value >= 0;
1043 }
1044
1045 static char *
1046 show_UNDEFINED (const struct dataset *ds UNUSED)
1047 {
1048   return xstrdup (settings_get_undefined () ? "WARN" : "NOWARN");
1049 }
1050
1051 static char *
1052 show_VERSION (const struct dataset *ds UNUSED)
1053 {
1054   return strdup (announced_version);
1055 }
1056
1057 static char *
1058 show_WEIGHT (const struct dataset *ds)
1059 {
1060   const struct variable *var = dict_get_weight (dataset_dict (ds));
1061   return xstrdup (var != NULL ? var_get_name (var) : "OFF");
1062 }
1063
1064 static bool
1065 parse_WIB (struct lexer *lexer)
1066 {
1067   return parse_integer_format (lexer, settings_set_output_integer_format);
1068 }
1069
1070 static char *
1071 show_WIB (const struct dataset *ds UNUSED)
1072 {
1073   return show_integer_format (settings_get_output_integer_format ());
1074 }
1075
1076 static bool
1077 parse_WRB (struct lexer *lexer)
1078 {
1079   return parse_real_format (lexer, settings_set_output_float_format);
1080 }
1081
1082 static char *
1083 show_WRB (const struct dataset *ds UNUSED)
1084 {
1085   return show_real_format (settings_get_output_float_format ());
1086 }
1087
1088 static bool
1089 parse_WIDTH (struct lexer *lexer)
1090 {
1091   if (lex_match_id (lexer, "NARROW"))
1092     settings_set_viewwidth (79);
1093   else if (lex_match_id (lexer, "WIDE"))
1094     settings_set_viewwidth (131);
1095   else
1096     {
1097       if (!lex_force_int_range (lexer, "WIDTH", 40, INT_MAX))
1098         return false;
1099       settings_set_viewwidth (lex_integer (lexer));
1100       lex_get (lexer);
1101     }
1102
1103   return true;
1104 }
1105
1106 static char *
1107 show_WIDTH (const struct dataset *ds UNUSED)
1108 {
1109   return xasprintf ("%d", settings_get_viewwidth ());
1110 }
1111
1112 static bool
1113 parse_WORKSPACE (struct lexer *lexer)
1114 {
1115   if (!lex_force_int_range (lexer, "WORKSPACE",
1116                             settings_get_testing_mode () ? 1 : 1024,
1117                             INT_MAX))
1118     return false;
1119   int workspace = lex_integer (lexer);
1120   lex_get (lexer);
1121   settings_set_workspace (MIN (workspace, INT_MAX / 1024) * 1024);
1122   return true;
1123 }
1124
1125 static char *
1126 show_WORKSPACE (const struct dataset *ds UNUSED)
1127 {
1128   size_t ws = settings_get_workspace () / 1024L;
1129   return xasprintf ("%zu", ws);
1130 }
1131 \f
1132 static char *
1133 show_DIRECTORY (const struct dataset *ds UNUSED)
1134 {
1135   char *buf = NULL;
1136   char *wd = NULL;
1137   size_t len = 256;
1138
1139   do
1140     {
1141       len <<= 1;
1142       buf = xrealloc (buf, len);
1143     }
1144   while (NULL == (wd = getcwd (buf, len)));
1145
1146   return wd;
1147 }
1148
1149 static char *
1150 show_N (const struct dataset *ds)
1151 {
1152   const struct casereader *reader = dataset_source (ds);
1153   return (reader
1154           ? xasprintf ("%lld", (long long int) casereader_count_cases (reader))
1155           : xstrdup (_("Unknown")));
1156 }
1157
1158 static void
1159 do_show (const struct dataset *ds, const struct setting *s,
1160          struct pivot_table **ptp)
1161 {
1162   struct pivot_table *pt = *ptp;
1163   if (!pt)
1164     {
1165       pt = *ptp = pivot_table_create (N_("Settings"));
1166       pivot_dimension_create (pt, PIVOT_AXIS_ROW, N_("Setting"));
1167     }
1168
1169   struct pivot_value *name = pivot_value_new_user_text (s->name, SIZE_MAX);
1170   char *text = s->show (ds);
1171   if (!text)
1172     text = xstrdup("empty");
1173   struct pivot_value *value = pivot_value_new_user_text_nocopy (text);
1174
1175   int row = pivot_category_create_leaf (pt->dimensions[0]->root, name);
1176   pivot_table_put1 (pt, row, value);
1177 }
1178
1179 static void
1180 show_warranty (const struct dataset *ds UNUSED)
1181 {
1182   fputs (lack_of_warranty, stdout);
1183 }
1184
1185 static void
1186 show_copying (const struct dataset *ds UNUSED)
1187 {
1188   fputs (copyleft, stdout);
1189 }
1190
1191 static void
1192 add_row (struct pivot_table *table, const char *attribute,
1193          const char *value)
1194 {
1195   int row = pivot_category_create_leaf (table->dimensions[0]->root,
1196                                         pivot_value_new_text (attribute));
1197   if (value)
1198     pivot_table_put1 (table, row, pivot_value_new_user_text (value, -1));
1199 }
1200
1201 static void
1202 show_system (const struct dataset *ds UNUSED)
1203 {
1204   struct pivot_table *table = pivot_table_create (N_("System Information"));
1205   pivot_dimension_create (table, PIVOT_AXIS_ROW, N_("Attribute"));
1206
1207   add_row (table, N_("Version"), version);
1208   add_row (table, N_("Host System"), host_system);
1209   add_row (table, N_("Build System"), build_system);
1210   add_row (table, N_("Locale Directory"), relocate (locale_dir));
1211   add_row (table, N_("Compiler Version"),
1212 #ifdef __VERSION__
1213            __VERSION__
1214 #else
1215            "Unknown"
1216 #endif
1217            );
1218   pivot_table_submit (table);
1219 }
1220 \f
1221 static const struct setting settings[] = {
1222   { "BASETEXTDIRECTION", parse_BASETEXTDIRECTION, NULL },
1223   { "BLANKS", parse_BLANKS, show_BLANKS },
1224   { "BLOCK", parse_BLOCK, NULL },
1225   { "BOX", parse_BOX, NULL },
1226   { "CACHE", parse_CACHE, NULL },
1227   { "CCA", parse_CCA, show_CCA },
1228   { "CCB", parse_CCB, show_CCB },
1229   { "CCC", parse_CCC, show_CCC },
1230   { "CCD", parse_CCD, show_CCD },
1231   { "CCE", parse_CCE, show_CCE },
1232   { "CELLSBREAK", parse_CELLSBREAK, NULL },
1233   { "CMPTRANS", parse_CMPTRANS, NULL },
1234   { "COMPRESSION", parse_COMPRESSION, NULL },
1235   { "CTEMPLATE", parse_CTEMPLATE, NULL },
1236   { "DECIMAL", parse_DECIMAL, show_DECIMAL },
1237   { "DIRECTORY", NULL, show_DIRECTORY },
1238   { "EPOCH", parse_EPOCH, show_EPOCH },
1239   { "ERRORS", parse_ERRORS, show_ERRORS },
1240   { "FORMAT", parse_FORMAT, show_FORMAT },
1241   { "FUZZBITS", parse_FUZZBITS, show_FUZZBITS },
1242   { "HEADER", parse_HEADER, NULL },
1243   { "INCLUDE", parse_INCLUDE, show_INCLUDE },
1244   { "JOURNAL", parse_JOURNAL, show_JOURNAL },
1245   { "LEADZERO", parse_LEADZERO, show_LEADZERO },
1246   { "LENGTH", parse_LENGTH, show_LENGTH },
1247   { "LOCALE", parse_LOCALE, show_LOCALE },
1248   { "MDISPLAY", parse_MDISPLAY, show_MDISPLAY },
1249   { "MESSAGES", parse_MESSAGES, show_MESSAGES },
1250   { "MEXPAND", parse_MEXPAND, show_MEXPAND },
1251   { "MITERATE", parse_MITERATE, show_MITERATE },
1252   { "MNEST", parse_MNEST, show_MNEST },
1253   { "MPRINT", parse_MPRINT, show_MPRINT },
1254   { "MXERRS", parse_MXERRS, show_MXERRS },
1255   { "MXLOOPS", parse_MXLOOPS, show_MXLOOPS },
1256   { "MXWARNS", parse_MXWARNS, show_MXWARNS },
1257   { "N", NULL, show_N },
1258   { "PRINTBACK", parse_PRINTBACK, show_PRINTBACK },
1259   { "RESULTS", parse_RESULTS, show_RESULTS },
1260   { "RIB", parse_RIB, show_RIB },
1261   { "RRB", parse_RRB, show_RRB },
1262   { "SAFER", parse_SAFER, show_SAFER },
1263   { "SCOMPRESSION", parse_SCOMPRESSION, show_SCOMPRESSION },
1264   { "SEED", parse_SEED, NULL },
1265   { "SMALL", parse_SMALL, show_SMALL },
1266   { "TEMPDIR", NULL, show_TEMPDIR },
1267   { "TNUMBERS", parse_TNUMBERS, show_TNUMBERS },
1268   { "TVARS", parse_TVARS, show_TVARS },
1269   { "TLOOK", parse_TLOOK, NULL },
1270   { "UNDEFINED", parse_UNDEFINED, show_UNDEFINED },
1271   { "VERSION", NULL, show_VERSION },
1272   { "WEIGHT", NULL, show_WEIGHT },
1273   { "WIB", parse_WIB, show_WIB },
1274   { "WRB", parse_WRB, show_WRB },
1275   { "WIDTH", parse_WIDTH, show_WIDTH },
1276   { "WORKSPACE", parse_WORKSPACE, show_WORKSPACE },
1277 };
1278 enum { N_SETTINGS = sizeof settings / sizeof *settings };
1279
1280 static bool
1281 parse_setting (struct lexer *lexer)
1282 {
1283   for (size_t i = 0; i < N_SETTINGS; i++)
1284     if (settings[i].set && match_subcommand (lexer, settings[i].name))
1285         return settings[i].set (lexer);
1286
1287   lex_error (lexer, NULL);
1288   return false;
1289 }
1290
1291 int
1292 cmd_set (struct lexer *lexer, struct dataset *ds UNUSED)
1293 {
1294   for (;;)
1295     {
1296       lex_match (lexer, T_SLASH);
1297       if (lex_token (lexer) == T_ENDCMD)
1298         break;
1299
1300       if (!parse_setting (lexer))
1301         return CMD_FAILURE;
1302     }
1303
1304   return CMD_SUCCESS;
1305 }
1306
1307 static void
1308 show_all (const struct dataset *ds, struct pivot_table **ptp)
1309 {
1310   for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
1311     if (settings[i].show)
1312       do_show (ds, &settings[i], ptp);
1313 }
1314
1315 static void
1316 show_all_cc (const struct dataset *ds, struct pivot_table **ptp)
1317 {
1318   for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
1319     {
1320       const struct setting *s = &settings[i];
1321       if (s->show && !strncmp (s->name, "CC", 2))
1322         do_show (ds, s, ptp);
1323     }
1324 }
1325
1326 int
1327 cmd_show (struct lexer *lexer, struct dataset *ds)
1328 {
1329   struct pivot_table *pt = NULL;
1330   if (lex_token (lexer) == T_ENDCMD)
1331     {
1332       show_all (ds, &pt);
1333       pivot_table_submit (pt);
1334       return CMD_SUCCESS;
1335     }
1336
1337   do
1338     {
1339       if (lex_match (lexer, T_ALL))
1340         show_all (ds, &pt);
1341       else if (lex_match_id (lexer, "CC"))
1342         show_all_cc (ds, &pt);
1343       else if (lex_match_id (lexer, "WARRANTY"))
1344         show_warranty (ds);
1345       else if (lex_match_id (lexer, "COPYING") || lex_match_id (lexer, "LICENSE"))
1346         show_copying (ds);
1347       else if (lex_match_id (lexer, "SYSTEM"))
1348         show_system (ds);
1349       else if (lex_match_id (lexer, "TITLE"))
1350         {
1351           struct setting s = { .name = "TITLE", .show = show_TITLE };
1352           do_show (ds, &s, &pt);
1353         }
1354       else if (lex_match_id (lexer, "SUBTITLE"))
1355         {
1356           struct setting s = { .name = "SUBTITLE", .show = show_SUBTITLE };
1357           do_show (ds, &s, &pt);
1358         }
1359       else if (lex_token (lexer) == T_ID)
1360         {
1361           int i;
1362
1363           for (i = 0; i < sizeof settings / sizeof *settings; i++)
1364             {
1365               const struct setting *s = &settings[i];
1366               if (s->show && lex_match_id (lexer, s->name))
1367                 {
1368                   do_show (ds, s, &pt);
1369                   goto found;
1370                 }
1371               }
1372           lex_error (lexer, NULL);
1373           return CMD_FAILURE;
1374
1375         found: ;
1376         }
1377       else
1378         {
1379           lex_error (lexer, NULL);
1380           return CMD_FAILURE;
1381         }
1382
1383       lex_match (lexer, T_SLASH);
1384     }
1385   while (lex_token (lexer) != T_ENDCMD);
1386
1387   if (pt)
1388     pivot_table_submit (pt);
1389
1390   return CMD_SUCCESS;
1391 }
1392 \f
1393 #define MAX_SAVED_SETTINGS 5
1394
1395 static struct settings *saved_settings[MAX_SAVED_SETTINGS];
1396 static int n_saved_settings;
1397
1398 int
1399 cmd_preserve (struct lexer *lexer, struct dataset *ds UNUSED)
1400 {
1401   if (n_saved_settings < MAX_SAVED_SETTINGS)
1402     {
1403       saved_settings[n_saved_settings++] = settings_get ();
1404       return CMD_SUCCESS;
1405     }
1406   else
1407     {
1408       lex_next_error (lexer, -1, -1,
1409                       _("Too many %s commands without a %s: at most "
1410                         "%d levels of saved settings are allowed."),
1411                       "PRESERVE", "RESTORE",
1412                       MAX_SAVED_SETTINGS);
1413       return CMD_CASCADING_FAILURE;
1414     }
1415 }
1416
1417 int
1418 cmd_restore (struct lexer *lexer, struct dataset *ds UNUSED)
1419 {
1420   if (n_saved_settings > 0)
1421     {
1422       struct settings *s = saved_settings[--n_saved_settings];
1423       settings_set (s);
1424       settings_destroy (s);
1425       return CMD_SUCCESS;
1426     }
1427   else
1428     {
1429       lex_next_error (lexer, -1, -1,
1430                       _("%s without matching %s."), "RESTORE", "PRESERVE");
1431       return CMD_FAILURE;
1432     }
1433 }