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.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include "gl/vasnprintf.h"
28 #include "data/casereader.h"
29 #include "data/data-in.h"
30 #include "data/data-out.h"
31 #include "data/dataset.h"
32 #include "data/dictionary.h"
33 #include "data/format.h"
34 #include "data/settings.h"
35 #include "data/value.h"
36 #include "data/variable.h"
37 #include "language/command.h"
38 #include "language/lexer/format-parser.h"
39 #include "language/lexer/lexer.h"
40 #include "libpspp/assertion.h"
41 #include "libpspp/compiler.h"
42 #include "libpspp/copyleft.h"
43 #include "libpspp/temp-file.h"
44 #include "libpspp/version.h"
45 #include "libpspp/float-format.h"
46 #include "libpspp/i18n.h"
47 #include "libpspp/integer-format.h"
48 #include "libpspp/message.h"
49 #include "math/random.h"
50 #include "output/driver.h"
51 #include "output/journal.h"
52 #include "output/pivot-table.h"
54 #include "gl/minmax.h"
55 #include "gl/xalloc.h"
58 #define _(msgid) gettext (msgid)
61 match_subcommand (struct lexer *lexer, const char *name)
63 if (lex_match_id (lexer, name))
65 lex_match (lexer, T_EQUALS);
73 parse_enum_valist (struct lexer *lexer, va_list args)
77 const char *name = va_arg (args, char *);
80 int value = va_arg (args, int);
82 if (lex_match_id (lexer, name))
87 #define parse_enum(...) parse_enum (__VA_ARGS__, NULL_SENTINEL)
88 static int SENTINEL(0)
89 (parse_enum) (struct lexer *lexer, ...)
93 va_start (args, lexer);
94 int retval = parse_enum_valist (lexer, args);
100 #define force_parse_enum(...) force_parse_enum (__VA_ARGS__, NULL_SENTINEL)
101 static int SENTINEL(0)
102 (force_parse_enum) (struct lexer *lexer, ...)
106 va_start (args, lexer);
107 int retval = parse_enum_valist (lexer, args);
112 enum { MAX_OPTIONS = 9 };
113 const char *options[MAX_OPTIONS];
116 va_start (args, lexer);
117 while (n < MAX_OPTIONS)
119 const char *name = va_arg (args, char *);
128 lex_error_expecting_array (lexer, options, n);
135 parse_bool (struct lexer *lexer)
137 return parse_enum (lexer,
138 "ON", true, "YES", true,
139 "OFF", false, "NO", false);
143 force_parse_bool (struct lexer *lexer)
145 return force_parse_enum (lexer,
146 "ON", true, "YES", true,
147 "OFF", false, "NO", false);
151 force_parse_int (struct lexer *lexer, int *integerp)
153 if (!lex_force_int (lexer))
155 *integerp = lex_integer (lexer);
161 parse_output_routing (struct lexer *lexer, enum settings_output_type type)
163 enum settings_output_devices devices;
164 if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "BOTH"))
165 devices = SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL;
166 else if (lex_match_id (lexer, "TERMINAL"))
167 devices = SETTINGS_DEVICE_TERMINAL;
168 else if (lex_match_id (lexer, "LISTING"))
169 devices = SETTINGS_DEVICE_LISTING;
170 else if (lex_match_id (lexer, "OFF") || lex_match_id (lexer, "NONE"))
174 lex_error (lexer, NULL);
178 settings_set_output_routing (type, devices);
184 parse_integer_format (struct lexer *lexer,
185 void (*set_format) (enum integer_format))
187 int value = force_parse_enum (lexer,
188 "MSBFIRST", INTEGER_MSB_FIRST,
189 "LSBFIRST", INTEGER_LSB_FIRST,
191 "NATIVE", INTEGER_NATIVE);
198 parse_real_format (struct lexer *lexer,
199 void (*set_format) (enum float_format))
201 int value = force_parse_enum (lexer,
202 "NATIVE", FLOAT_NATIVE_DOUBLE,
203 "ISL", FLOAT_IEEE_SINGLE_LE,
204 "ISB", FLOAT_IEEE_SINGLE_BE,
205 "IDL", FLOAT_IEEE_DOUBLE_LE,
206 "IDB", FLOAT_IEEE_DOUBLE_BE,
218 parse_unimplemented (struct lexer *lexer, const char *name)
220 msg (SW, _("%s is not yet implemented."), name);
221 if (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
227 parse_ccx (struct lexer *lexer, enum fmt_type ccx)
229 if (!lex_force_string (lexer))
232 settings_set_cc (lex_tokcstr (lexer), ccx);
238 parse_BASETEXTDIRECTION (struct lexer *lexer)
240 return parse_unimplemented (lexer, "BASETEXTDIRECTION");
244 parse_BLANKS (struct lexer *lexer)
246 if (lex_match_id (lexer, "SYSMIS"))
247 settings_set_blanks (SYSMIS);
250 if (!lex_force_num (lexer))
252 settings_set_blanks (lex_number (lexer));
259 parse_BLOCK (struct lexer *lexer)
261 return parse_unimplemented (lexer, "BLOCK");
265 parse_BOX (struct lexer *lexer)
267 return parse_unimplemented (lexer, "BOX");
271 parse_CACHE (struct lexer *lexer)
273 return parse_unimplemented (lexer, "CACHE");
277 parse_CCA (struct lexer *lexer)
279 return parse_ccx (lexer, FMT_CCA);
283 parse_CCB (struct lexer *lexer)
285 return parse_ccx (lexer, FMT_CCB);
289 parse_CCC (struct lexer *lexer)
291 return parse_ccx (lexer, FMT_CCC);
295 parse_CCD (struct lexer *lexer)
297 return parse_ccx (lexer, FMT_CCD);
301 parse_CCE (struct lexer *lexer)
303 return parse_ccx (lexer, FMT_CCE);
307 parse_CELLSBREAK (struct lexer *lexer)
309 return parse_unimplemented (lexer, "CELLSBREAK");
313 parse_CMPTRANS (struct lexer *lexer)
315 return parse_unimplemented (lexer, "CMPTRANS");
319 parse_COMPRESSION (struct lexer *lexer)
321 return parse_unimplemented (lexer, "COMPRESSION");
325 parse_CTEMPLATE (struct lexer *lexer)
327 return parse_unimplemented (lexer, "CTEMPLATE");
331 parse_DECIMAL (struct lexer *lexer)
333 int decimal_char = force_parse_enum (lexer,
336 if (decimal_char != -1)
337 settings_set_decimal_char (decimal_char);
338 return decimal_char != -1;
342 parse_EPOCH (struct lexer *lexer)
344 if (lex_match_id (lexer, "AUTOMATIC"))
345 settings_set_epoch (-1);
346 else if (lex_is_integer (lexer))
348 if (!lex_force_int_range (lexer, "EPOCH", 1500, INT_MAX))
350 settings_set_epoch (lex_integer (lexer));
355 lex_error (lexer, _("expecting %s or year"), "AUTOMATIC");
363 parse_ERRORS (struct lexer *lexer)
365 return parse_output_routing (lexer, SETTINGS_OUTPUT_ERROR);
369 parse_FORMAT (struct lexer *lexer)
373 lex_match (lexer, T_EQUALS);
374 if (!parse_format_specifier (lexer, &fmt))
377 if (!fmt_check_output (&fmt))
380 if (fmt_is_string (fmt.type))
382 char str[FMT_STRING_LEN_MAX + 1];
383 msg (SE, _("%s requires numeric output format as an argument. "
384 "Specified format %s is of type string."),
386 fmt_to_string (&fmt, str));
390 settings_set_format (&fmt);
395 parse_FUZZBITS (struct lexer *lexer)
397 if (!lex_force_int_range (lexer, "FUZZITS", 0, 20))
399 settings_set_fuzzbits (lex_integer (lexer));
405 parse_HEADER (struct lexer *lexer)
407 return parse_unimplemented (lexer, "HEADER");
411 parse_INCLUDE (struct lexer *lexer)
413 int include = force_parse_bool (lexer);
415 settings_set_include (include);
416 return include != -1;
420 parse_JOURNAL (struct lexer *lexer)
422 int b = parse_bool (lexer);
427 else if (lex_is_string (lexer) || lex_token (lexer) == T_ID)
429 char *filename = utf8_to_filename (lex_tokcstr (lexer));
430 journal_set_file_name (filename);
437 lex_error (lexer, NULL);
444 parse_LENGTH (struct lexer *lexer)
448 if (lex_match_id (lexer, "NONE"))
452 if (!lex_force_int_range (lexer, "LENGTH", 1, INT_MAX))
454 page_length = lex_integer (lexer);
458 if (page_length != -1)
459 settings_set_viewlength (page_length);
465 parse_LOCALE (struct lexer *lexer)
467 if (!lex_force_string (lexer))
470 /* Try the argument as an encoding name, then as a locale name or alias. */
471 const char *s = lex_tokcstr (lexer);
472 if (valid_encoding (s))
473 set_default_encoding (s);
474 else if (!set_encoding_from_locale (s))
476 msg (ME, _("%s is not a recognized encoding or locale name"), s);
485 parse_MESSAGES (struct lexer *lexer)
487 return parse_output_routing (lexer, SETTINGS_OUTPUT_NOTE);
491 parse_MEXPAND (struct lexer *lexer)
493 int mexpand = force_parse_bool (lexer);
495 settings_set_mexpand (mexpand);
496 return mexpand != -1;
500 parse_MITERATE (struct lexer *lexer)
502 if (!lex_force_int_range (lexer, "MITERATE", 1, INT_MAX))
504 settings_set_miterate (lex_integer (lexer));
510 parse_MNEST (struct lexer *lexer)
512 if (!lex_force_int_range (lexer, "MNEST", 1, INT_MAX))
514 settings_set_mnest (lex_integer (lexer));
520 parse_MPRINT (struct lexer *lexer)
522 int mprint = force_parse_bool (lexer);
524 settings_set_mprint (mprint);
529 parse_MXERRS (struct lexer *lexer)
532 if (!force_parse_int (lexer, &n))
536 settings_set_max_messages (MSG_S_ERROR, n);
538 msg (SE, _("%s must be at least 1."), "MXERRS");
543 parse_MXLOOPS (struct lexer *lexer)
546 if (!force_parse_int (lexer, &n))
550 settings_set_mxloops (n);
552 msg (SE, _("%s must be at least 1."), "MXLOOPS");
557 parse_MXWARNS (struct lexer *lexer)
560 if (!force_parse_int (lexer, &n))
564 settings_set_max_messages (MSG_S_WARNING, n);
566 msg (SE, _("%s must not be negative."), "MXWARNS");
571 parse_PRINTBACK (struct lexer *lexer)
573 return parse_output_routing (lexer, SETTINGS_OUTPUT_SYNTAX);
577 parse_RESULTS (struct lexer *lexer)
579 return parse_output_routing (lexer, SETTINGS_OUTPUT_RESULT);
583 parse_RIB (struct lexer *lexer)
585 return parse_integer_format (lexer, settings_set_input_integer_format);
589 parse_RRB (struct lexer *lexer)
591 return parse_real_format (lexer, settings_set_input_float_format);
595 parse_SAFER (struct lexer *lexer)
597 bool ok = force_parse_enum (lexer, "ON", true, "YES", true) != -1;
599 settings_set_safer_mode ();
604 parse_SCOMPRESSION (struct lexer *lexer)
606 int value = force_parse_bool (lexer);
608 settings_set_scompression (value);
613 parse_SEED (struct lexer *lexer)
615 if (lex_match_id (lexer, "RANDOM"))
619 if (!lex_force_num (lexer))
621 set_rng (lex_number (lexer));
629 parse_SMALL (struct lexer *lexer)
631 if (!lex_force_num (lexer))
633 settings_set_small (lex_number (lexer));
639 parse_TNUMBERS (struct lexer *lexer)
641 int value = force_parse_enum (lexer,
642 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
643 "VALUES", SETTINGS_VALUE_SHOW_VALUE,
644 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
646 settings_set_show_values (value);
651 parse_TVARS (struct lexer *lexer)
653 int value = force_parse_enum (lexer,
654 "LABELS", SETTINGS_VALUE_SHOW_LABEL,
655 "NAMES", SETTINGS_VALUE_SHOW_VALUE,
656 "BOTH", SETTINGS_VALUE_SHOW_BOTH);
658 settings_set_show_variables (value);
663 parse_TLOOK (struct lexer *lexer)
665 if (lex_match_id (lexer, "NONE"))
666 pivot_table_look_set_default (pivot_table_look_builtin_default ());
667 else if (lex_is_string (lexer))
669 struct pivot_table_look *look;
670 char *error = pivot_table_look_read (lex_tokcstr (lexer), &look);
675 msg (SE, "%s", error);
680 pivot_table_look_set_default (look);
681 pivot_table_look_unref (look);
688 parse_UNDEFINED (struct lexer *lexer)
690 int value = force_parse_enum (lexer,
694 settings_set_undefined (value);
699 parse_WIB (struct lexer *lexer)
701 return parse_integer_format (lexer, settings_set_output_integer_format);
705 parse_WRB (struct lexer *lexer)
707 return parse_real_format (lexer, settings_set_output_float_format);
711 parse_WIDTH (struct lexer *lexer)
713 if (lex_match_id (lexer, "NARROW"))
714 settings_set_viewwidth (79);
715 else if (lex_match_id (lexer, "WIDE"))
716 settings_set_viewwidth (131);
719 if (!lex_force_int_range (lexer, "WIDTH", 40, INT_MAX))
721 settings_set_viewwidth (lex_integer (lexer));
729 parse_WORKSPACE (struct lexer *lexer)
731 if (!lex_force_int_range (lexer, "WORKSPACE",
732 settings_get_testing_mode () ? 1 : 1024,
735 int workspace = lex_integer (lexer);
737 settings_set_workspace (MIN (workspace, INT_MAX / 1024) * 1024);
742 parse_setting (struct lexer *lexer)
747 bool (*function) (struct lexer *);
749 const struct setting settings[] = {
750 { "BASETEXTDIRECTION", parse_BASETEXTDIRECTION },
751 { "BLANKS", parse_BLANKS },
752 { "BLOCK", parse_BLOCK },
753 { "BOX", parse_BOX },
754 { "CACHE", parse_CACHE },
755 { "CCA", parse_CCA },
756 { "CCB", parse_CCB },
757 { "CCC", parse_CCC },
758 { "CCD", parse_CCD },
759 { "CCE", parse_CCE },
760 { "CELLSBREAK", parse_CELLSBREAK },
761 { "CMPTRANS", parse_CMPTRANS },
762 { "COMPRESSION", parse_COMPRESSION },
763 { "CTEMPLATE", parse_CTEMPLATE },
764 { "DECIMAL", parse_DECIMAL },
765 { "EPOCH", parse_EPOCH },
766 { "ERRORS", parse_ERRORS },
767 { "FORMAT", parse_FORMAT },
768 { "FUZZBITS", parse_FUZZBITS },
769 { "HEADER", parse_HEADER },
770 { "INCLUDE", parse_INCLUDE },
771 { "JOURNAL", parse_JOURNAL },
772 { "LENGTH", parse_LENGTH },
773 { "LOCALE", parse_LOCALE },
774 { "MESSAGES", parse_MESSAGES },
775 { "MEXPAND", parse_MEXPAND },
776 { "MITERATE", parse_MITERATE },
777 { "MNEST", parse_MNEST },
778 { "MPRINT", parse_MPRINT },
779 { "MXERRS", parse_MXERRS },
780 { "MXLOOPS", parse_MXLOOPS },
781 { "MXWARNS", parse_MXWARNS },
782 { "PRINTBACK", parse_PRINTBACK },
783 { "RESULTS", parse_RESULTS },
784 { "RIB", parse_RIB },
785 { "RRB", parse_RRB },
786 { "SAFER", parse_SAFER },
787 { "SCOMPRESSION", parse_SCOMPRESSION },
788 { "SEED", parse_SEED },
789 { "SMALL", parse_SMALL },
790 { "TNUMBERS", parse_TNUMBERS },
791 { "TVARS", parse_TVARS },
792 { "TLOOK", parse_TLOOK },
793 { "UNDEFINED", parse_UNDEFINED },
794 { "WIB", parse_WIB },
795 { "WRB", parse_WRB },
796 { "WIDTH", parse_WIDTH },
797 { "WORKSPACE", parse_WORKSPACE },
799 enum { N_SETTINGS = sizeof settings / sizeof *settings };
801 for (size_t i = 0; i < N_SETTINGS; i++)
802 if (match_subcommand (lexer, settings[i].name))
803 return settings[i].function (lexer);
805 lex_error (lexer, NULL);
810 cmd_set (struct lexer *lexer, struct dataset *ds UNUSED)
814 lex_match (lexer, T_SLASH);
815 if (lex_token (lexer) == T_ENDCMD)
818 if (!parse_setting (lexer))
826 show_output_routing (enum settings_output_type type)
828 enum settings_output_devices devices;
831 devices = settings_get_output_routing (type);
832 if (devices & SETTINGS_DEVICE_LISTING)
833 s = devices & SETTINGS_DEVICE_TERMINAL ? "BOTH" : "LISTING";
834 else if (devices & SETTINGS_DEVICE_TERMINAL)
843 show_blanks (const struct dataset *ds UNUSED)
845 return (settings_get_blanks () == SYSMIS
847 : xasprintf ("%.*g", DBL_DIG + 1, settings_get_blanks ()));
851 show_cc (enum fmt_type type)
853 return fmt_number_style_to_string (fmt_settings_get_style (
854 settings_get_fmt_settings (), type));
858 show_cca (const struct dataset *ds UNUSED)
860 return show_cc (FMT_CCA);
864 show_ccb (const struct dataset *ds UNUSED)
866 return show_cc (FMT_CCB);
870 show_ccc (const struct dataset *ds UNUSED)
872 return show_cc (FMT_CCC);
876 show_ccd (const struct dataset *ds UNUSED)
878 return show_cc (FMT_CCD);
882 show_cce (const struct dataset *ds UNUSED)
884 return show_cc (FMT_CCE);
888 show_decimals (const struct dataset *ds UNUSED)
890 return xasprintf ("`%c'", settings_get_fmt_settings ()->decimal);
894 show_errors (const struct dataset *ds UNUSED)
896 return show_output_routing (SETTINGS_OUTPUT_ERROR);
900 show_format (const struct dataset *ds UNUSED)
902 char str[FMT_STRING_LEN_MAX + 1];
903 return xstrdup (fmt_to_string (settings_get_format (), str));
907 show_fuzzbits (const struct dataset *ds UNUSED)
909 return xasprintf ("%d", settings_get_fuzzbits ());
913 show_journal (const struct dataset *ds UNUSED)
915 return (journal_is_enabled ()
916 ? xasprintf ("\"%s\"", journal_get_file_name ())
917 : xstrdup ("disabled"));
921 show_length (const struct dataset *ds UNUSED)
923 return xasprintf ("%d", settings_get_viewlength ());
927 show_locale (const struct dataset *ds UNUSED)
929 return xstrdup (get_default_encoding ());
933 show_mexpand (const struct dataset *ds UNUSED)
935 return xstrdup (settings_get_mexpand () ? "ON" : "OFF");
939 show_mprint (const struct dataset *ds UNUSED)
941 return xstrdup (settings_get_mprint () ? "ON" : "OFF");
945 show_miterate (const struct dataset *ds UNUSED)
947 return xasprintf ("%d", settings_get_miterate ());
951 show_mnest (const struct dataset *ds UNUSED)
953 return xasprintf ("%d", settings_get_mnest ());
957 show_messages (const struct dataset *ds UNUSED)
959 return show_output_routing (SETTINGS_OUTPUT_NOTE);
963 show_printback (const struct dataset *ds UNUSED)
965 return show_output_routing (SETTINGS_OUTPUT_SYNTAX);
969 show_results (const struct dataset *ds UNUSED)
971 return show_output_routing (SETTINGS_OUTPUT_RESULT);
975 show_mxerrs (const struct dataset *ds UNUSED)
977 return xasprintf ("%d", settings_get_max_messages (MSG_S_ERROR));
981 show_mxloops (const struct dataset *ds UNUSED)
983 return xasprintf ("%d", settings_get_mxloops ());
987 show_mxwarns (const struct dataset *ds UNUSED)
989 return xasprintf ("%d", settings_get_max_messages (MSG_S_WARNING));
992 /* Returns a name for the given INTEGER_FORMAT value. */
994 show_integer_format (enum integer_format integer_format)
996 return xasprintf ("%s (%s)",
997 (integer_format == INTEGER_MSB_FIRST ? "MSBFIRST"
998 : integer_format == INTEGER_LSB_FIRST ? "LSBFIRST"
1000 integer_format == INTEGER_NATIVE ? "NATIVE" : "nonnative");
1003 /* Returns a name for the given FLOAT_FORMAT value. */
1005 show_float_format (enum float_format float_format)
1007 const char *format_name = "";
1009 switch (float_format)
1011 case FLOAT_IEEE_SINGLE_LE:
1012 format_name = _("ISL (32-bit IEEE 754 single, little-endian)");
1014 case FLOAT_IEEE_SINGLE_BE:
1015 format_name = _("ISB (32-bit IEEE 754 single, big-endian)");
1017 case FLOAT_IEEE_DOUBLE_LE:
1018 format_name = _("IDL (64-bit IEEE 754 double, little-endian)");
1020 case FLOAT_IEEE_DOUBLE_BE:
1021 format_name = _("IDB (64-bit IEEE 754 double, big-endian)");
1025 format_name = _("VF (32-bit VAX F, VAX-endian)");
1028 format_name = _("VD (64-bit VAX D, VAX-endian)");
1031 format_name = _("VG (64-bit VAX G, VAX-endian)");
1035 format_name = _("ZS (32-bit IBM Z hexadecimal short, big-endian)");
1038 format_name = _("ZL (64-bit IBM Z hexadecimal long, big-endian)");
1046 return xasprintf ("%s (%s)", format_name,
1047 (float_format == FLOAT_NATIVE_DOUBLE
1048 ? "NATIVE" : "nonnative"));
1052 show_rib (const struct dataset *ds UNUSED)
1054 return show_integer_format (settings_get_input_integer_format ());
1058 show_rrb (const struct dataset *ds UNUSED)
1060 return show_float_format (settings_get_input_float_format ());
1064 show_scompression (const struct dataset *ds UNUSED)
1066 return xstrdup (settings_get_scompression () ? "ON" : "OFF");
1070 show_undefined (const struct dataset *ds UNUSED)
1072 return xstrdup (settings_get_undefined () ? "WARN" : "NOWARN");
1076 show_weight (const struct dataset *ds)
1078 const struct variable *var = dict_get_weight (dataset_dict (ds));
1079 return xstrdup (var != NULL ? var_get_name (var) : "OFF");
1083 show_wib (const struct dataset *ds UNUSED)
1085 return show_integer_format (settings_get_output_integer_format ());
1089 show_wrb (const struct dataset *ds UNUSED)
1091 return show_float_format (settings_get_output_float_format ());
1095 show_width (const struct dataset *ds UNUSED)
1097 return xasprintf ("%d", settings_get_viewwidth ());
1101 show_workspace (const struct dataset *ds UNUSED)
1103 size_t ws = settings_get_workspace () / 1024L;
1104 return xasprintf ("%zu", ws);
1108 show_current_directory (const struct dataset *ds UNUSED)
1117 buf = xrealloc (buf, len);
1119 while (NULL == (wd = getcwd (buf, len)));
1125 show_tempdir (const struct dataset *ds UNUSED)
1127 return strdup (temp_dir_name ());
1131 show_version (const struct dataset *ds UNUSED)
1133 return strdup (announced_version);
1137 show_system (const struct dataset *ds UNUSED)
1139 return strdup (host_system);
1143 show_n (const struct dataset *ds)
1148 const struct casereader *reader = dataset_source (ds);
1151 return strdup (_("Unknown"));
1153 n = casereader_count_cases (reader);
1155 return asnprintf (NULL, &l, "%ld", n);
1162 char *(*function) (const struct dataset *);
1165 const struct show_sbc show_table[] =
1167 {"BLANKS", show_blanks},
1173 {"DECIMALS", show_decimals},
1174 {"DIRECTORY", show_current_directory},
1175 {"ENVIRONMENT", show_system},
1176 {"ERRORS", show_errors},
1177 {"FORMAT", show_format},
1178 {"FUZZBITS", show_fuzzbits},
1179 {"JOURNAL", show_journal},
1180 {"LENGTH", show_length},
1181 {"LOCALE", show_locale},
1182 {"MEXPAND", show_mexpand},
1183 {"MPRINT", show_mprint},
1184 {"MITERATE", show_miterate},
1185 {"MNEST", show_mnest},
1186 {"MESSAGES", show_messages},
1187 {"MXERRS", show_mxerrs},
1188 {"MXLOOPS", show_mxloops},
1189 {"MXWARNS", show_mxwarns},
1191 {"PRINTBACk", show_printback},
1192 {"RESULTS", show_results},
1195 {"SCOMPRESSION", show_scompression},
1196 {"TEMPDIR", show_tempdir},
1197 {"UNDEFINED", show_undefined},
1198 {"VERSION", show_version},
1199 {"WEIGHT", show_weight},
1202 {"WIDTH", show_width},
1203 {"WORKSPACE", show_workspace},
1207 do_show (const struct dataset *ds, const struct show_sbc *sbc)
1209 char *value = sbc->function (ds);
1210 msg (SN, _("%s is %s."), sbc->name, value);
1215 show_all (const struct dataset *ds)
1219 for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
1220 do_show (ds, &show_table[i]);
1224 show_all_cc (const struct dataset *ds)
1228 for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
1230 const struct show_sbc *sbc = &show_table[i];
1231 if (!strncmp (sbc->name, "CC", 2))
1237 show_warranty (const struct dataset *ds UNUSED)
1239 fputs (lack_of_warranty, stdout);
1243 show_copying (const struct dataset *ds UNUSED)
1245 fputs (copyleft, stdout);
1250 cmd_show (struct lexer *lexer, struct dataset *ds)
1252 if (lex_token (lexer) == T_ENDCMD)
1260 if (lex_match (lexer, T_ALL))
1262 else if (lex_match_id (lexer, "CC"))
1264 else if (lex_match_id (lexer, "WARRANTY"))
1266 else if (lex_match_id (lexer, "COPYING") || lex_match_id (lexer, "LICENSE"))
1268 else if (lex_token (lexer) == T_ID)
1272 for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
1274 const struct show_sbc *sbc = &show_table[i];
1275 if (lex_match_id (lexer, sbc->name))
1281 lex_error (lexer, NULL);
1288 lex_error (lexer, NULL);
1292 lex_match (lexer, T_SLASH);
1294 while (lex_token (lexer) != T_ENDCMD);
1299 #define MAX_SAVED_SETTINGS 5
1301 static struct settings *saved_settings[MAX_SAVED_SETTINGS];
1302 static int n_saved_settings;
1305 cmd_preserve (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
1307 if (n_saved_settings < MAX_SAVED_SETTINGS)
1309 saved_settings[n_saved_settings++] = settings_get ();
1314 msg (SE, _("Too many %s commands without a %s: at most "
1315 "%d levels of saved settings are allowed."),
1316 "PRESERVE", "RESTORE",
1317 MAX_SAVED_SETTINGS);
1318 return CMD_CASCADING_FAILURE;
1323 cmd_restore (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
1325 if (n_saved_settings > 0)
1327 struct settings *s = saved_settings[--n_saved_settings];
1329 settings_destroy (s);
1334 msg (SE, _("%s without matching %s."), "RESTORE", "PRESERVE");