+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);
+}
+