lexer: New function lex_error_expecting().
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 5 Nov 2011 18:23:23 +0000 (11:23 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Nov 2011 16:19:23 +0000 (08:19 -0800)
This centralizes some fairly common strings into lexer.c.

13 files changed:
src/language/data-io/get-data.c
src/language/data-io/get.c
src/language/data-io/save-translate.c
src/language/data-io/save.c
src/language/dictionary/attributes.c
src/language/expressions/parse.c
src/language/lexer/lexer.c
src/language/lexer/lexer.h
src/language/stats/aggregate.c
src/language/utilities/include.c
src/language/utilities/set.q
tests/language/control/do-repeat.at
tests/language/data-io/inpt-pgm.at

index 9b878c553a92bf1a16e37f5985506e025db924c6..4274f959d26048de21d79797d3eed879da6766fd 100644 (file)
@@ -35,6 +35,7 @@
 #include "language/data-io/placement-parser.h"
 #include "language/lexer/format-parser.h"
 #include "language/lexer/lexer.h"
+#include "libpspp/cast.h"
 #include "libpspp/i18n.h"
 #include "libpspp/message.h"
 
@@ -345,7 +346,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
                            DP_DELIMITED, &has_type);
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "FIXED", "DELIMITED");
+              lex_error_expecting (lexer, "FIXED", "DELIMITED", NULL_SENTINEL);
               goto error;
             }
           if (!ok)
@@ -383,7 +384,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
             }
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "LINE", "VARIABLES");
+              lex_error_expecting (lexer, "LINE", "VARIABLES", NULL_SENTINEL);
               goto error;
             }
         }
@@ -494,7 +495,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
         break;
       else
         {
-          lex_error (lexer, _("expecting %s"), "VARIABLES");
+          lex_error_expecting (lexer, "VARIABLES", NULL_SENTINEL);
           goto error;
         }
     }
index 0e542ef0d28dc50b08ea97bd780424da5aede1d1..ea65b5c14e7524c4ad14453ef2b972524f3547bf 100644 (file)
@@ -96,7 +96,7 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command
            type = PFM_TAPE;
          else
            {
-             lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+             lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
               goto error;
            }
        }
index f6487c57932e3faad8a64e45adcf570e9ab7b897..cbed4b1008e656a4aab819280cc5db2de0e4ff8a 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -115,7 +115,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             type = TAB_FILE;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB");
+              lex_error_expecting (lexer, "CSV", "TAB", NULL_SENTINEL);
               goto error;
             }
         }
@@ -132,7 +132,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             recode_user_missing = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE");
+              lex_error_expecting (lexer, "IGNORE", "RECODE", NULL_SENTINEL);
               goto error;
             }
         }
@@ -145,7 +145,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             use_value_labels = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS");
+              lex_error_expecting (lexer, "VALUES", "LABELS", NULL_SENTINEL);
               goto error;
             }
         }
@@ -193,8 +193,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     decimal = ',';
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "DOT", "COMMA");
+                      lex_error_expecting (lexer, "DOT", "COMMA",
+                                           NULL_SENTINEL);
                       goto error;
                     }
                 }
@@ -207,8 +207,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     use_print_formats = true;
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "PLAIN", "VARIABLE");
+                      lex_error_expecting (lexer, "PLAIN", "VARIABLE",
+                                           NULL_SENTINEL);
                       goto error;
                     }
                 }
@@ -225,7 +225,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             retain_unselected = false;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
               goto error;
             }
         }
index cf847361264d618b1001677bd86c62661e73d3cb..66cdd45293aa4efcd79d3a1f630e13aa43573c00 100644 (file)
@@ -213,8 +213,8 @@ parse_write_command (struct lexer *lexer, struct dataset *ds,
             cw = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"),
-                         "READONLY", "WRITEABLE");
+              lex_error_expecting (lexer, "READONLY", "WRITEABLE",
+                                   NULL_SENTINEL);
               goto error;
             }
           sysfile_opts.create_writeable = porfile_opts.create_writeable = cw;
@@ -228,7 +228,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds,
             *retain_unselected = false;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
               goto error;
             }
         }
@@ -256,7 +256,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds,
             porfile_opts.type = PFM_TAPE;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+              lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
               goto error;
             }
         }
index c7598d1c45b37899ecba1d7a375e3dbaea3d9987..fc9cc9a5d28b72dd7b86701fb1cf42557b66a9f0 100644 (file)
@@ -197,7 +197,7 @@ parse_attributes (struct lexer *lexer, const char *dict_encoding,
         command = DELETE;
       else if (command == UNKNOWN)
         {
-          lex_error (lexer, _("expecting %s or %s"), "ATTRIBUTE=", "DELETE=");
+          lex_error_expecting (lexer, "ATTRIBUTE=", "DELETE=", NULL_SENTINEL);
           return CMD_FAILURE;
         }
 
index ed5a07093c712b3b034b82f71d6af1fbdc4db0fd..32c2e6152917f721f2a50fc1d569720e8ad9386b 100644 (file)
@@ -1268,8 +1268,7 @@ parse_function (struct lexer *lexer, struct expression *e)
           break;
         else if (!lex_match (lexer, T_COMMA))
           {
-            lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
-                       first->name);
+            lex_error_expecting (lexer, ",", ")", NULL_SENTINEL);
             goto fail;
           }
       }
index 5f1cc4ba2bb4709c7affce0f31479635e79c50f0..a356b3821de28150b848ff6ca2131f61dfdc9b84 100644 (file)
@@ -268,6 +268,75 @@ lex_next_error (struct lexer *lexer, int n0, int n1, const char *format, ...)
   va_end (args);
 }
 
+/* Prints a syntax error message saying that OPTION0 or one of the other
+   strings following it, up to the first NULL, is expected. */
+void
+lex_error_expecting (struct lexer *lexer, const char *option0, ...)
+{
+  enum { MAX_OPTIONS = 8 };
+  const char *options[MAX_OPTIONS + 1];
+  va_list args;
+  int n;
+
+  va_start (args, option0);
+  options[0] = option0;
+  n = 0;
+  while (n + 1 < MAX_OPTIONS && options[n] != NULL)
+    options[++n] = va_arg (args, const char *);
+  va_end (args);
+
+  switch (n)
+    {
+    case 0:
+      lex_error (lexer, NULL);
+      break;
+
+    case 1:
+      lex_error (lexer, _("expecting %s"), options[0]);
+      break;
+
+    case 2:
+      lex_error (lexer, _("expecting %s or %s"), options[0], options[1]);
+      break;
+
+    case 3:
+      lex_error (lexer, _("expecting %s, %s, or %s"), options[0], options[1],
+                 options[2]);
+      break;
+
+    case 4:
+      lex_error (lexer, _("expecting %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3]);
+      break;
+
+    case 5:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4]);
+      break;
+
+    case 6:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5]);
+      break;
+
+    case 7:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5], options[6]);
+      break;
+
+    case 8:
+      lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, %s, or %s"),
+                 options[0], options[1], options[2], options[3], options[4],
+                 options[5], options[6], options[7]);
+      break;
+
+    default:
+      NOT_REACHED ();
+    }
+}
+
 /* Reports an error to the effect that subcommand SBC may only be
    specified once. */
 void
@@ -491,7 +560,7 @@ lex_force_match_id (struct lexer *lexer, const char *identifier)
     return true;
   else
     {
-      lex_error (lexer, _("expecting `%s'"), identifier);
+      lex_error_expecting (lexer, identifier, NULL_SENTINEL);
       return false;
     }
 }
@@ -508,7 +577,9 @@ lex_force_match (struct lexer *lexer, enum token_type type)
     }
   else
     {
-      lex_error (lexer, _("expecting `%s'"), token_type_to_string (type));
+      char *s = xasprintf ("`%s'", token_type_to_string (type));
+      lex_error_expecting (lexer, s, NULL_SENTINEL);
+      free (s);
       return false;
     }
 }
index 0a3e6c37c03de317a25f107820dd313ef8f4bd7e..b0787e8f44eb4f55a4da4799aa62fdec96a7f223 100644 (file)
@@ -155,6 +155,8 @@ void lex_next_error (struct lexer *, int n0, int n1, const char *, ...)
   PRINTF_FORMAT (4, 5);
 int lex_end_of_command (struct lexer *);
 
+void lex_error_expecting (struct lexer *, const char *, ...) SENTINEL(0);
+
 void lex_sbc_only_once (const char *);
 void lex_sbc_missing (struct lexer *, const char *);
 
index fed765692f9a65cc30d20c3b1d17ff2bef81843b..f4cbaac448b3acfbd67fa81c8775176fbb6b33e0 100644 (file)
@@ -223,7 +223,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
          lex_match (lexer, T_EQUALS);
          if (!lex_match_id (lexer, "COLUMNWISE"))
            {
-             lex_error (lexer, _("expecting %s"), "COLUMNWISE");
+             lex_error_expecting (lexer, "COLUMNWISE", NULL);
               goto error;
            }
          agr.missing = COLUMNWISE;
index bcee162c6a04f56e44a01164d0c7af87662cba62..89da3b9bf517b86f7dff167a0acec0842c014852 100644 (file)
@@ -106,8 +106,8 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum variant variant)
            syntax_mode = LEX_SYNTAX_AUTO;
          else
            {
-             lex_error (lexer, _("expecting %s, %s, or %s after %s"),
-                         "BATCH", "INTERACTIVE", "AUTO", "SYNTAX");
+             lex_error_expecting (lexer, "BATCH", "INTERACTIVE", "AUTO",
+                                   NULL_SENTINEL);
              goto exit;
            }
        }
@@ -124,8 +124,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum variant variant)
            }
          else
            {
-             lex_error (lexer, _("expecting %s or %s after %s"),
-                         "YES", "NO", "CD");
+             lex_error_expecting (lexer, "YES", "NO", NULL_SENTINEL);
              goto exit;
            }
        }
@@ -142,8 +141,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum variant variant)
            }
          else
            {
-             lex_error (lexer, _("expecting %s or %s after %s"),
-                         "CONTINUE", "STOP", "ERROR");
+             lex_error_expecting (lexer, "CONTINUE", "STOP", NULL_SENTINEL);
              goto exit;
            }
        }
index c538c8c47ed50f5163868b82bd678ed4a34f6b66..8b892c7fb6bfdb092207a6950ca0fb7a01055c6d 100644 (file)
@@ -331,7 +331,7 @@ stc_custom_tnumbers (struct lexer *lexer,
     }
   else
     {
-      lex_error (lexer, _("expecting VALUES, LABELS or BOTH"));
+      lex_error_expecting (lexer, "VALUES", "LABELS", "BOTH", NULL_SENTINEL);
       return 0;
     }
 
index 4421ba6b715fbf2641b602d004ea4b3f23eca68b..75c0e77a36e9b6aa056ecb488944c410e41da4f2 100644 (file)
@@ -145,6 +145,6 @@ DATA LIST NOTABLE /x 1.
 DO REPEAT y = 1 TO 10.
 ])
 AT_CHECK([pspp -O format=csv do-repeat.sps], [1], [dnl
-error: DO REPEAT: Syntax error at end of input: expecting `END'.
+error: DO REPEAT: Syntax error at end of input: expecting END.
 ])
 AT_CLEANUP
index f048d3743fd44f881561354a3951929550c7849b..03f9a2a5108def99ab98bee502287d58631f316c 100644 (file)
@@ -28,6 +28,6 @@ END INPUT PROGRAM.
 DESCRIPTIVES x.
 ])
 AT_CHECK([pspp -O format=csv input-program.sps], [1], [dnl
-error: DESCRIPTIVES: Syntax error at end of input: expecting `BEGIN'.
+error: DESCRIPTIVES: Syntax error at end of input: expecting BEGIN.
 ])
 AT_CLEANUP