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