work on pivot-table-test
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 31 Dec 2020 01:26:17 +0000 (17:26 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 31 Dec 2020 03:58:11 +0000 (19:58 -0800)
tests/output/pivot-table-test.c

index 514ce7f8dca4143faae393f0d0a0410938ae80f8..7890470d5fe548fe01da5e8fc5283551335da3b8 100644 (file)
@@ -25,6 +25,7 @@
 
 #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"
@@ -266,6 +267,129 @@ usage (void)
   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)
 {
@@ -277,7 +401,20 @@ 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
@@ -286,16 +423,15 @@ read_value (struct lexer *lexer)
       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
@@ -376,54 +512,6 @@ parse_bool_setting (struct lexer *lexer, const char *name,
     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)
 {