lexer: Fix implementation of lex_force_string_or_id().
[pspp] / src / language / lexer / lexer.c
index ea81f19559926a37fc47e69efe7c464a82384909..a3642f8a6c6f7e7f5fc5b9376ee31db8308e9efa 100644 (file)
@@ -604,9 +604,16 @@ lex_force_match (struct lexer *lexer, enum token_type type)
     }
   else
     {
-      char *s = xasprintf ("`%s'", token_type_to_string (type));
-      lex_error_expecting (lexer, s, NULL_SENTINEL);
-      free (s);
+      const char *type_string = token_type_to_string (type);
+      if (type_string)
+       {
+         char *s = xasprintf ("`%s'", type_string);
+         lex_error_expecting (lexer, s, NULL_SENTINEL);
+         free (s);
+       }
+      else
+       lex_error_expecting (lexer, token_type_to_name (type), NULL_SENTINEL);
+
       return false;
     }
 }
@@ -637,7 +644,7 @@ lex_force_string (struct lexer *lexer)
 bool
 lex_force_string_or_id (struct lexer *lexer)
 {
-  return lex_is_integer (lexer) || lex_force_string (lexer);
+  return lex_token (lexer) == T_ID || lex_force_string (lexer);
 }
 
 /* If the current token is an integer, does nothing and returns true.
@@ -1174,19 +1181,33 @@ 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],
-                                    space,
-                                    segmenter_get_prompt (&src->segmenter));
+      size_t head_ofs = src->head - src->tail;
+      size_t space = src->allocated - head_ofs;
+      enum prompt_style prompt = segmenter_get_prompt (&src->segmenter);
+      size_t n = src->reader->class->read (src->reader, &src->buffer[head_ofs],
+                                           space, prompt);
       assert (n <= space);
 
+      for (char *p = &src->buffer[head_ofs]; p < &src->buffer[head_ofs + n];
+           p++)
+        if (*p == '\0')
+          {
+            struct msg m;
+            m.category = MSG_C_SYNTAX;
+            m.severity = MSG_S_ERROR;
+            m.file_name = src->reader->file_name;
+            m.first_line = 0;
+            m.last_line = 0;
+            m.first_column = 0;
+            m.last_column = 0;
+            m.text = xstrdup ("Bad character U+0000 in input.");
+            msg_emit (&m);
+
+            *p = ' ';
+          }
+
       if (n == 0)
         {
           /* End of input.