#include "data/file-handle-def.h"
#include "language/lexer/lexer.h"
+#include "language/lexer/format-parser.h"
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
#include "libpspp/i18n.h"
exit (EXIT_SUCCESS);
}
+static bool
+parse_settings_value_show (struct lexer *lexer, const char *name,
+ enum settings_value_show *show)
+{
+ if (lex_match_id (lexer, name))
+ {
+ if (!lex_force_match (lexer, T_EQUALS))
+ exit (1);
+
+ if (lex_match_id (lexer, "DEFAULT"))
+ *show = SETTINGS_VALUE_SHOW_DEFAULT;
+ else if (lex_match_id (lexer, "VALUE"))
+ *show = SETTINGS_VALUE_SHOW_VALUE;
+ else if (lex_match_id (lexer, "LABEL"))
+ *show = SETTINGS_VALUE_SHOW_LABEL;
+ else if (lex_match_id (lexer, "BOTH"))
+ *show = SETTINGS_VALUE_SHOW_BOTH;
+ else
+ {
+ lex_error_expecting (lexer, "DEFAULT", "VALUE", "LABEL", "BOTH");
+ exit (1);
+ }
+
+ return true;
+ }
+ else
+ return false;
+}
+
+static bool
+parse_string_setting (struct lexer *lexer, const char *name, char **stringp)
+{
+ if (lex_match_id (lexer, name))
+ {
+ lex_match (lexer, T_EQUALS);
+ if (!lex_force_string (lexer))
+ exit (1);
+
+ free (*stringp);
+ *stringp = xstrdup (lex_tokcstr (lexer));
+
+ lex_get (lexer);
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+read_value_option (struct lexer *lexer, struct pivot_value *value)
+{
+ enum settings_value_show *show
+ = (value->type == PIVOT_VALUE_NUMERIC ? &value->numeric.show
+ : value->type == PIVOT_VALUE_STRING ? &value->string.show
+ : value->type == PIVOT_VALUE_VARIABLE ? &value->variable.show
+ : NULL);
+ if (show && parse_settings_value_show (lexer, "SHOW", show))
+ return;
+
+ char **var_name
+ = (value->type == PIVOT_VALUE_NUMERIC ? &value->numeric.var_name
+ : value->type == PIVOT_VALUE_STRING ? &value->string.var_name
+ : NULL);
+ if (var_name && parse_string_setting (lexer, "VAR", var_name))
+ return;
+
+ char **label
+ = (value->type == PIVOT_VALUE_NUMERIC ? &value->numeric.value_label
+ : value->type == PIVOT_VALUE_STRING ? &value->string.value_label
+ : value->type == PIVOT_VALUE_VARIABLE ? &value->variable.var_label
+ : NULL);
+ if (label && parse_string_setting (lexer, "LABEL", label))
+ return;
+
+ if (value->type == PIVOT_VALUE_STRING && lex_match_id (lexer, "HEX"))
+ {
+ value->string.hex = true;
+ return;
+ }
+
+ if (value->type == PIVOT_VALUE_NUMERIC)
+ {
+ msg_disable ();
+ struct fmt_spec fmt;
+ bool ok = parse_format_specifier (lexer, &fmt);
+ msg_enable ();
+
+ if (ok)
+ {
+ if (!fmt_check_output (&fmt)
+ || !fmt_check_type_compat (&fmt, VAL_NUMERIC))
+ exit (1);
+
+ value->numeric.format = fmt;
+ return;
+ }
+ }
+
+ if (parse_string_setting (lexer, "SUPERSCRIPT", &value->superscript))
+ return;
+
+ if (lex_match_id (lexer, "SUBSCRIPTS"))
+ {
+ lex_match (lexer, T_EQUALS);
+ size_t allocated_subscripts = value->n_subscripts;
+ while (lex_token (lexer) == T_STRING)
+ {
+ if (value->n_subscripts >= allocated_subscripts)
+ value->subscripts = x2nrealloc (value->subscripts,
+ &allocated_subscripts,
+ sizeof *value->subscripts);
+
+ value->subscripts[value->n_subscripts++] = xstrdup (
+ lex_tokcstr (lexer));
+ lex_get (lexer);
+ }
+ return;
+ }
+
+ lex_error (lexer, "Expecting valid value option");
+ exit (1);
+}
+
static struct pivot_value *
read_value (struct lexer *lexer)
{
}
else if (lex_is_string (lexer))
{
- value = pivot_value_new_user_text (lex_tokcstr (lexer), SIZE_MAX);
+ value = xmalloc (sizeof *value);
+ *value = (struct pivot_value) {
+ .type = PIVOT_VALUE_STRING,
+ .string = { .s = xstrdup (lex_tokcstr (lexer)) },
+ };
+ lex_get (lexer);
+ }
+ else if (lex_token (lexer) == T_ID)
+ {
+ value = xmalloc (sizeof *value);
+ *value = (struct pivot_value) {
+ .type = PIVOT_VALUE_VARIABLE,
+ .variable = { .var_name = xstrdup (lex_tokcstr (lexer)) },
+ };
lex_get (lexer);
}
else
exit (1);
}
- if (!lex_match (lexer, T_LBRACK))
- return value;
- do
+ while (lex_match (lexer, T_LBRACK))
{
- msg (SE, "Options not yet supported");
- exit (1);
+ read_value_option (lexer, value);
+
+ if (!lex_force_match (lexer, T_RBRACK))
+ exit (1);
}
- while (lex_match (lexer, T_COMMA));
- if (!lex_force_match (lexer, T_RBRACK))
- exit (1);
+
+ return value;
}
static void
return false;
}
-static bool
-parse_settings_value_show (struct lexer *lexer, const char *name,
- enum settings_value_show *show)
-{
- if (lex_match_id (lexer, name))
- {
- if (!lex_force_match (lexer, T_EQUALS))
- exit (1);
-
- if (lex_match_id (lexer, "DEFAULT"))
- *show = SETTINGS_VALUE_SHOW_DEFAULT;
- else if (lex_match_id (lexer, "VALUE"))
- *show = SETTINGS_VALUE_SHOW_VALUE;
- else if (lex_match_id (lexer, "LABEL"))
- *show = SETTINGS_VALUE_SHOW_LABEL;
- else if (lex_match_id (lexer, "BOTH"))
- *show = SETTINGS_VALUE_SHOW_BOTH;
- else
- {
- lex_error_expecting (lexer, "DEFAULT", "VALUE", "LABEL", "BOTH");
- exit (1);
- }
-
- return true;
- }
- else
- return false;
-}
-
-static bool
-parse_string_setting (struct lexer *lexer, const char *name, char **stringp)
-{
- if (lex_match_id (lexer, name))
- {
- lex_match (lexer, T_EQUALS);
- if (!lex_force_string (lexer))
- exit (1);
-
- free (*stringp);
- *stringp = xstrdup (lex_tokcstr (lexer));
-
- lex_get (lexer);
- return true;
- }
- else
- return false;
-}
-
static void
read_look (struct lexer *lexer, struct pivot_table *pt)
{