#include <time.h>
#include <unistd.h>
-#include "gl/ftoastr.h"
-#include "gl/vasnprintf.h"
-
#include "data/casereader.h"
#include "data/data-in.h"
#include "data/data-out.h"
#include "language/command.h"
#include "language/lexer/format-parser.h"
#include "language/lexer/lexer.h"
+#include "language/lexer/token.h"
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
#include "libpspp/copyleft.h"
#include "output/journal.h"
#include "output/pivot-table.h"
+#include "gl/ftoastr.h"
#include "gl/minmax.h"
+#include "gl/relocatable.h"
+#include "gl/vasnprintf.h"
#include "gl/xalloc.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
+#define N_(msgid) (msgid)
struct setting
{
return false;
}
+static int
+subcommand_start_ofs (struct lexer *lexer)
+{
+ int ofs = lex_ofs (lexer) - 1;
+ return lex_ofs_token (lexer, ofs)->type == T_EQUALS ? ofs - 1 : ofs;
+}
+
static int
parse_enum_valist (struct lexer *lexer, va_list args)
{
"OFF", false, "NO", false);
}
-static bool
-force_parse_int (struct lexer *lexer, int *integerp)
-{
- if (!lex_force_int (lexer))
- return false;
- *integerp = lex_integer (lexer);
- lex_get (lexer);
- return true;
-}
-
static bool
parse_output_routing (struct lexer *lexer, enum settings_output_type type)
{
static bool
parse_unimplemented (struct lexer *lexer, const char *name)
{
- msg (SW, _("%s is not yet implemented."), name);
+ int start = subcommand_start_ofs (lexer);
if (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
lex_get (lexer);
+ int end = lex_ofs (lexer) - 1;
+
+ lex_ofs_msg (lexer, SW, start, end, _("%s is not yet implemented."), name);
return true;
}
if (!lex_force_string (lexer))
return false;
- settings_set_cc (lex_tokcstr (lexer), ccx);
+ char *error = settings_set_cc (lex_tokcstr (lexer), ccx);
+ if (error)
+ {
+ lex_error (lexer, "%s", error);
+ free (error);
+ return false;
+ }
+
lex_get (lexer);
return true;
}
}
else
{
- lex_error (lexer, _("expecting %s or year"), "AUTOMATIC");
+ lex_error (lexer, _("Syntax error expecting %s or year."), "AUTOMATIC");
return false;
}
static bool
parse_FORMAT (struct lexer *lexer)
{
+ int start = subcommand_start_ofs (lexer);
struct fmt_spec fmt;
- lex_match (lexer, T_EQUALS);
if (!parse_format_specifier (lexer, &fmt))
return false;
- if (!fmt_check_output (&fmt))
- return false;
+ char *error = fmt_check_output__ (&fmt);
+ if (error)
+ {
+ lex_next_error (lexer, -1, -1, "%s", error);
+ free (error);
+ return false;
+ }
+ int end = lex_ofs (lexer) - 1;
if (fmt_is_string (fmt.type))
{
char str[FMT_STRING_LEN_MAX + 1];
- msg (SE, _("%s requires numeric output format as an argument. "
- "Specified format %s is of type string."),
- "FORMAT",
- fmt_to_string (&fmt, str));
+ lex_ofs_error (lexer, start, end,
+ _("%s requires numeric output format as an argument. "
+ "Specified format %s is of type string."),
+ "FORMAT", fmt_to_string (&fmt, str));
return false;
}
: xstrdup (enabled));
}
+static bool
+parse_LEADZERO (struct lexer *lexer)
+{
+ int leadzero = force_parse_bool (lexer);
+ if (leadzero != -1)
+ settings_set_include_leading_zero (leadzero);
+ return leadzero != -1;
+}
+
+static char *
+show_LEADZERO (const struct dataset *ds UNUSED)
+{
+ bool leadzero = settings_get_fmt_settings ()->include_leading_zero;
+ return xstrdup (leadzero ? "ON" : "OFF");
+}
+
static bool
parse_LENGTH (struct lexer *lexer)
{
set_default_encoding (s);
else if (!set_encoding_from_locale (s))
{
- msg (ME, _("%s is not a recognized encoding or locale name"), s);
+ lex_error (lexer, _("%s is not a recognized encoding or locale name"), s);
return false;
}
return xstrdup (get_default_encoding ());
}
+static bool
+parse_MDISPLAY (struct lexer *lexer)
+{
+ int mdisplay = force_parse_enum (lexer,
+ "TEXT", SETTINGS_MDISPLAY_TEXT,
+ "TABLES", SETTINGS_MDISPLAY_TABLES);
+ if (mdisplay >= 0)
+ settings_set_mdisplay (mdisplay);
+ return mdisplay >= 0;
+}
+
+static char *
+show_MDISPLAY (const struct dataset *ds UNUSED)
+{
+ return xstrdup (settings_get_mdisplay () == SETTINGS_MDISPLAY_TEXT
+ ? "TEXT" : "TABLES");
+}
+
static bool
parse_MESSAGES (struct lexer *lexer)
{
static bool
parse_MXERRS (struct lexer *lexer)
{
- int n;
- if (!force_parse_int (lexer, &n))
+ if (!lex_force_int_range (lexer, "MXERRS", 1, INT_MAX))
return false;
-
- if (n >= 1)
- settings_set_max_messages (MSG_S_ERROR, n);
- else
- msg (SE, _("%s must be at least 1."), "MXERRS");
+ settings_set_max_messages (MSG_S_ERROR, lex_integer (lexer));
+ lex_get (lexer);
return true;
}
static bool
parse_MXLOOPS (struct lexer *lexer)
{
- int n;
- if (!force_parse_int (lexer, &n))
+ if (!lex_force_int_range (lexer, "MXLOOPS", 1, INT_MAX))
return false;
-
- if (n >= 1)
- settings_set_mxloops (n);
- else
- msg (SE, _("%s must be at least 1."), "MXLOOPS");
+ settings_set_mxloops (lex_integer (lexer));
+ lex_get (lexer);
return true;
}
static bool
parse_MXWARNS (struct lexer *lexer)
{
- int n;
- if (!force_parse_int (lexer, &n))
+ if (!lex_force_int_range (lexer, "MXWARNS", 0, INT_MAX))
return false;
-
- if (n >= 0)
- settings_set_max_messages (MSG_S_WARNING, n);
- else
- msg (SE, _("%s must not be negative."), "MXWARNS");
+ settings_set_max_messages (MSG_S_WARNING, lex_integer (lexer));
+ lex_get (lexer);
return true;
}
return xstrdup (output_get_subtitle ());
}
-static char *
-show_SYSTEM (const struct dataset *ds UNUSED)
-{
- return xstrdup (host_system);
-}
-
static char *
show_TEMPDIR (const struct dataset *ds UNUSED)
{
}
static void
-do_show (const struct dataset *ds, const struct setting *s)
+do_show (const struct dataset *ds, const struct setting *s,
+ struct pivot_table **ptp)
{
- char *value = s->show (ds);
- msg (SN, _("%s is %s."), s->name, value ? value : _("empty"));
- free (value);
+ struct pivot_table *pt = *ptp;
+ if (!pt)
+ {
+ pt = *ptp = pivot_table_create (N_("Settings"));
+ pivot_dimension_create (pt, PIVOT_AXIS_ROW, N_("Setting"));
+ }
+
+ struct pivot_value *name = pivot_value_new_user_text (s->name, SIZE_MAX);
+ char *text = s->show (ds);
+ if (!text)
+ text = xstrdup("empty");
+ struct pivot_value *value = pivot_value_new_user_text_nocopy (text);
+
+ int row = pivot_category_create_leaf (pt->dimensions[0]->root, name);
+ pivot_table_put1 (pt, row, value);
}
static void
{
fputs (copyleft, stdout);
}
+
+static void
+add_row (struct pivot_table *table, const char *attribute,
+ const char *value)
+{
+ int row = pivot_category_create_leaf (table->dimensions[0]->root,
+ pivot_value_new_text (attribute));
+ if (value)
+ pivot_table_put1 (table, row, pivot_value_new_user_text (value, -1));
+}
+
+static void
+show_system (const struct dataset *ds UNUSED)
+{
+ struct pivot_table *table = pivot_table_create (N_("System Information"));
+ pivot_dimension_create (table, PIVOT_AXIS_ROW, N_("Attribute"));
+
+ add_row (table, N_("Version"), version);
+ add_row (table, N_("Host System"), host_system);
+ add_row (table, N_("Build System"), build_system);
+ add_row (table, N_("Locale Directory"), relocate (locale_dir));
+ add_row (table, N_("Compiler Version"),
+#ifdef __VERSION__
+ __VERSION__
+#else
+ "Unknown"
+#endif
+ );
+ pivot_table_submit (table);
+}
\f
static const struct setting settings[] = {
{ "BASETEXTDIRECTION", parse_BASETEXTDIRECTION, NULL },
{ "HEADER", parse_HEADER, NULL },
{ "INCLUDE", parse_INCLUDE, show_INCLUDE },
{ "JOURNAL", parse_JOURNAL, show_JOURNAL },
+ { "LEADZERO", parse_LEADZERO, show_LEADZERO },
{ "LENGTH", parse_LENGTH, show_LENGTH },
{ "LOCALE", parse_LOCALE, show_LOCALE },
+ { "MDISPLAY", parse_MDISPLAY, show_MDISPLAY },
{ "MESSAGES", parse_MESSAGES, show_MESSAGES },
{ "MEXPAND", parse_MEXPAND, show_MEXPAND },
{ "MITERATE", parse_MITERATE, show_MITERATE },
{ "SCOMPRESSION", parse_SCOMPRESSION, show_SCOMPRESSION },
{ "SEED", parse_SEED, NULL },
{ "SMALL", parse_SMALL, show_SMALL },
- { "SYSTEM", NULL, show_SYSTEM },
{ "TEMPDIR", NULL, show_TEMPDIR },
{ "TNUMBERS", parse_TNUMBERS, show_TNUMBERS },
{ "TVARS", parse_TVARS, show_TVARS },
}
static void
-show_all (const struct dataset *ds)
+show_all (const struct dataset *ds, struct pivot_table **ptp)
{
for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
if (settings[i].show)
- do_show (ds, &settings[i]);
+ do_show (ds, &settings[i], ptp);
}
static void
-show_all_cc (const struct dataset *ds)
+show_all_cc (const struct dataset *ds, struct pivot_table **ptp)
{
for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
{
const struct setting *s = &settings[i];
if (s->show && !strncmp (s->name, "CC", 2))
- do_show (ds, s);
+ do_show (ds, s, ptp);
}
}
int
cmd_show (struct lexer *lexer, struct dataset *ds)
{
+ struct pivot_table *pt = NULL;
if (lex_token (lexer) == T_ENDCMD)
{
- show_all (ds);
+ show_all (ds, &pt);
+ pivot_table_submit (pt);
return CMD_SUCCESS;
}
do
{
if (lex_match (lexer, T_ALL))
- show_all (ds);
+ show_all (ds, &pt);
else if (lex_match_id (lexer, "CC"))
- show_all_cc (ds);
+ show_all_cc (ds, &pt);
else if (lex_match_id (lexer, "WARRANTY"))
show_warranty (ds);
else if (lex_match_id (lexer, "COPYING") || lex_match_id (lexer, "LICENSE"))
show_copying (ds);
+ else if (lex_match_id (lexer, "SYSTEM"))
+ show_system (ds);
else if (lex_match_id (lexer, "TITLE"))
{
struct setting s = { .name = "TITLE", .show = show_TITLE };
- do_show (ds, &s);
+ do_show (ds, &s, &pt);
}
else if (lex_match_id (lexer, "SUBTITLE"))
{
struct setting s = { .name = "SUBTITLE", .show = show_SUBTITLE };
- do_show (ds, &s);
+ do_show (ds, &s, &pt);
}
else if (lex_token (lexer) == T_ID)
{
- int i;
-
- for (i = 0; i < sizeof settings / sizeof *settings; i++)
+ for (size_t i = 0; i < sizeof settings / sizeof *settings; i++)
{
const struct setting *s = &settings[i];
if (s->show && lex_match_id (lexer, s->name))
{
- do_show (ds, s);
+ do_show (ds, s, &pt);
goto found;
}
}
}
while (lex_token (lexer) != T_ENDCMD);
+ if (pt)
+ pivot_table_submit (pt);
+
return CMD_SUCCESS;
}
\f
static int n_saved_settings;
int
-cmd_preserve (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
+cmd_preserve (struct lexer *lexer, struct dataset *ds UNUSED)
{
if (n_saved_settings < MAX_SAVED_SETTINGS)
{
}
else
{
- msg (SE, _("Too many %s commands without a %s: at most "
- "%d levels of saved settings are allowed."),
- "PRESERVE", "RESTORE",
- MAX_SAVED_SETTINGS);
+ lex_next_error (lexer, -1, -1,
+ _("Too many %s commands without a %s: at most "
+ "%d levels of saved settings are allowed."),
+ "PRESERVE", "RESTORE",
+ MAX_SAVED_SETTINGS);
return CMD_CASCADING_FAILURE;
}
}
int
-cmd_restore (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
+cmd_restore (struct lexer *lexer, struct dataset *ds UNUSED)
{
if (n_saved_settings > 0)
{
}
else
{
- msg (SE, _("%s without matching %s."), "RESTORE", "PRESERVE");
+ lex_next_error (lexer, -1, -1,
+ _("%s without matching %s."), "RESTORE", "PRESERVE");
return CMD_FAILURE;
}
}
-
-/*
- Local Variables:
- mode: c
- End:
-*/