lexer: Check that 'read' function in lex_source returns valid value.
[pspp] / src / language / lexer / lexer.c
index e3725681c9c6a207332987046e5e9bee721008ee..1caadac1de9854433d499122686d1ffa052d9704 100644 (file)
@@ -362,6 +362,24 @@ lex_sbc_missing (const char *sbc)
   msg (SE, _("Required subcommand %s was not specified."), sbc);
 }
 
+/* Reports an error to the effect that specification SPEC may only be specified
+   once within subcommand SBC. */
+void
+lex_spec_only_once (struct lexer *lexer, const char *sbc, const char *spec)
+{
+  lex_error (lexer, _("%s may only be specified once within subcommand %s"),
+             spec, sbc);
+}
+
+/* Reports an error to the effect that specification SPEC is missing within
+   subcommand SBC. */
+void
+lex_spec_missing (struct lexer *lexer, const char *sbc, const char *spec)
+{
+  lex_error (lexer, _("Required %s specification missing from %s subcommand"),
+             sbc, spec);
+}
+
 /* Prints a syntax error message containing the current token and
    given message MESSAGE (if non-null). */
 void
@@ -607,6 +625,21 @@ lex_force_string (struct lexer *lexer)
     }
 }
 
+/* If the current token is a string or an identifier, does nothing and returns
+   true.  Otherwise, reports an error and returns false.
+
+   This is meant for use in syntactic situations where we want to encourage the
+   user to supply a quoted string, but for compatibility we also accept
+   identifiers.  (One example of such a situation is file names.)  Therefore,
+   the error message issued when the current token is wrong only says that a
+   string is expected and doesn't mention that an identifier would also be
+   accepted. */
+bool
+lex_force_string_or_id (struct lexer *lexer)
+{
+  return lex_is_integer (lexer) || lex_force_string (lexer);
+}
+
 /* If the current token is an integer, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
@@ -1176,14 +1209,18 @@ lex_source_read__ (struct lex_source *src)
   do
     {
       size_t head_ofs;
+      size_t space;
       size_t n;
 
       lex_source_expand__ (src);
 
       head_ofs = src->head - src->tail;
+      space = src->allocated - head_ofs;
       n = src->reader->class->read (src->reader, &src->buffer[head_ofs],
-                                    src->allocated - head_ofs,
+                                    space,
                                     segmenter_get_prompt (&src->segmenter));
+      assert (n <= space);
+
       if (n == 0)
         {
           /* End of input.