!ENDDEFINE in a string or comment doesn't count.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 27 Jun 2021 19:58:35 +0000 (12:58 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 27 Jun 2021 19:58:35 +0000 (12:58 -0700)
src/language/lexer/segment.c
tests/language/lexer/segment.at

index 6bb602bbb99d31351dcc3733c8745315f4a7f3df..67f6ef617ff57cb287d6151612e92282a77cfd43 100644 (file)
@@ -1580,11 +1580,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