segment: Ignore !ENDDEFINE in /*comments*/ and "strings".
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jul 2021 05:10:26 +0000 (22:10 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 5 Jul 2021 01:22:12 +0000 (18:22 -0700)
src/language/lexer/segment.c
tests/language/lexer/segment.at

index 2689811593f4b515682e21c8c315d4a44562d9b4..9c2c9b11e8eba18e34b13f40124e3eb3439a97ae 100644 (file)
@@ -1579,11 +1579,33 @@ find_enddefine (struct substring input)
 {
   size_t n = input.length;
   const struct substring enddefine = ss_cstr ("!ENDDEFINE");
-  for (size_t i = 0; i + enddefine.length <= n; i++)
-    if (input.string[i] == '!'
-        && ss_equals_case (ss_substr (input, i, enddefine.length), enddefine))
-      return i;
-  return SIZE_MAX;
+  for (int ofs = 0;;)
+    {
+      /* Skip !ENDDEFINE in comment. */
+      ofs = skip_spaces_and_comments (input.string, n, true, ofs);
+      if (ofs + enddefine.length > n)
+        return SIZE_MAX;
+
+      char c = input.string[ofs];
+      if (c == '!'
+               && ss_equals_case (ss_substr (input, ofs, enddefine.length),
+                                  enddefine))
+        return ofs;
+      else if (c == '\'' || c == '"')
+        {
+          /* Skip quoted !ENDDEFINE. */
+          ofs++;
+          for (;;)
+            {
+              if (ofs >= n)
+                return SIZE_MAX;
+              else if (input.string[ofs++] == c)
+                break;
+            }
+        }
+      else
+        ofs++;
+    }
 }
 
 /* We are in the body of a macro definition, looking for additional lines of
index 00f3fe0c3fdf2478ff09827058a72a63059a51f5..86a09411947f883538d3fcedb2482908817832b4 100644 (file)
@@ -1014,7 +1014,7 @@ AT_SETUP([DEFINE command - simple])
 AT_KEYWORDS([segment])
 AT_DATA([input], [dnl
 define !macro1()
-var1 var2 var3
+var1 var2 var3 "!enddefine"
 !enddefine.
 ])
 AT_DATA([expout-base], [dnl
@@ -1025,7 +1025,7 @@ punct           )
 spaces
 newline         \n (DEFINE)
 
-macro_body      var1_var2_var3
+macro_body      var1_var2_var3_"!enddefine"
 newline         \n (DEFINE)
 
 macro_id        !enddefine
@@ -1040,7 +1040,7 @@ AT_CLEANUP
 AT_SETUP([DEFINE command - no newline after parentheses])
 AT_KEYWORDS([segment])
 AT_DATA([input], [dnl
-define !macro1() var1 var2 var3
+define !macro1() var1 var2 var3 /* !enddefine
 !enddefine.
 ])
 AT_DATA([expout-base], [dnl
@@ -1048,7 +1048,7 @@ identifier      define    space
 macro_id        !macro1
 punct           (
 punct           )
-macro_body      _var1_var2_var3
+macro_body      _var1_var2_var3_/*_!enddefine
 newline         \n (DEFINE)
 
 macro_id        !enddefine