improve macro error messages
[pspp] / src / language / lexer / macro.c
index 2accd94df95b752fa68dd5c90acdb2bc9ae61a63..bee23c999cb1be7f6254d69cdf315eea6206319c 100644 (file)
@@ -287,28 +287,37 @@ classify_token (enum token_type type)
 }
 
 void
-macro_tokens_to_representation (struct macro_tokens *mts, struct string *s)
+macro_tokens_to_representation (struct macro_tokens *mts, struct string *s,
+                                size_t *ofs, size_t *len)
 {
+  assert ((ofs != NULL) == (len != NULL));
+
   if (!mts->n)
     return;
 
-  macro_token_to_representation (&mts->mts[0], s);
-  for (size_t i = 1; i < mts->n; i++)
+  for (size_t i = 0; i < mts->n; i++)
     {
-      enum token_type prev = mts->mts[i - 1].token.type;
-      enum token_type next = mts->mts[i].token.type;
-
-      if (prev == T_ENDCMD)
-        ds_put_byte (s, '\n');
-      else
+      if (i > 0)
         {
-          enum token_class pc = classify_token (prev);
-          enum token_class nc = classify_token (next);
-          if (needs_space (pc, nc))
-            ds_put_byte (s, ' ');
+          enum token_type prev = mts->mts[i - 1].token.type;
+          enum token_type next = mts->mts[i].token.type;
+
+          if (prev == T_ENDCMD)
+            ds_put_byte (s, '\n');
+          else
+            {
+              enum token_class pc = classify_token (prev);
+              enum token_class nc = classify_token (next);
+              if (needs_space (pc, nc))
+                ds_put_byte (s, ' ');
+            }
         }
 
+      if (ofs)
+        ofs[i] = s->ss.length;
       macro_token_to_representation (&mts->mts[i], s);
+      if (len)
+        len[i] = s->ss.length - ofs[i];
     }
 }
 
@@ -1060,7 +1069,7 @@ expand_macro_function (struct parse_macro_function_ctx *ctx,
       if (mts.n > 1)
         {
           struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 };
-          macro_tokens_to_representation (&tail, output);
+          macro_tokens_to_representation (&tail, output, NULL, NULL);
         }
       macro_tokens_uninit (&mts);
       ds_destroy (&tmp);
@@ -1090,7 +1099,7 @@ expand_macro_function (struct parse_macro_function_ctx *ctx,
       struct macro_tokens exp = { .n = 0 };
       macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros, ctx->me,
                     ctx->vars, ctx->expand, NULL, &exp);
-      macro_tokens_to_representation (&exp, output);
+      macro_tokens_to_representation (&exp, output, NULL, NULL);
       macro_tokens_uninit (&exp);
       macro_tokens_uninit (&mts);
     }