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