]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: generalize / tighten #APP / #NO_APP recognition
authorJan Beulich <jbeulich@suse.com>
Mon, 5 Aug 2024 14:29:28 +0000 (16:29 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 5 Aug 2024 14:29:28 +0000 (16:29 +0200)
For one '#' may not be in line_comment_chars[] in the first place. Look
for just it when it is (these "directives" are akin to C preprocessor
directives after all), but accept any other line comment character
otherwise (in read.c further requiring a match on the counterpart
"directive").

Then, when in the middle of a file, the constructs should be all on
their own on a line.  There needs to be a newline ahead of them and
after them.

Finally '\n' may not be the only end-of-line character. Accept any (but
not end-of-statement ones) in read.c, while making sure in input-file.c
there is one in the first place - merely any kind of whitespace isn't
good enough.

gas/input-file.c
gas/read.c

index 89f03a98be8ea8fc3ef7d6f8725b7fe5e5a6a536..c96d2760a47b497b21d92ebbb39162fc39c5cc50 100644 (file)
@@ -164,34 +164,38 @@ input_file_open (const char *filename,
     }
   gas_assert (c != EOF);
 
-  if (c == '#')
+  if (strchr (line_comment_chars, '#')
+      ? c == '#'
+      : c && strchr (line_comment_chars, c))
     {
       /* Begins with comment, may not want to preprocess.  */
+      int lead = c;
+
       c = getc (f_in);
       if (c == 'N')
        {
          char *p = fgets (buf, sizeof (buf), f_in);
-         if (p && startswith (p, "O_APP") && ISSPACE (p[5]))
+         if (p && startswith (p, "O_APP") && is_end_of_line (p[5]))
            preprocess = 0;
          if (!p || !strchr (p, '\n'))
-           ungetc ('#', f_in);
+           ungetc (lead, f_in);
          else
            ungetc ('\n', f_in);
        }
       else if (c == 'A')
        {
          char *p = fgets (buf, sizeof (buf), f_in);
-         if (p && startswith (p, "PP") && ISSPACE (p[2]))
+         if (p && startswith (p, "PP") && is_end_of_line (p[2]))
            preprocess = 1;
          if (!p || !strchr (p, '\n'))
-           ungetc ('#', f_in);
+           ungetc (lead, f_in);
          else
            ungetc ('\n', f_in);
        }
       else if (c == '\n')
        ungetc ('\n', f_in);
       else
-       ungetc ('#', f_in);
+       ungetc (lead, f_in);
     }
   else
     ungetc (c, f_in);
index c6fb3dc5a1d4fa3031aa0e6b059f59814169be8e..78551937ccd173678fa2b3d667ffcc4223968dc8 100644 (file)
@@ -864,6 +864,29 @@ do_align (unsigned int n, char *fill, unsigned int len, unsigned int max)
     record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
 }
 
+/* Find first <eol><next_char>NO_APP<eol>, if any, in the supplied buffer.
+   Return NULL if there's none, or else the position of <next_char>.  */
+static char *
+find_no_app (const char *s, char next_char)
+{
+  const char *start = s;
+  const char srch[] = { next_char, 'N', 'O', '_', 'A', 'P', 'P', '\0' };
+
+  for (;;)
+    {
+      char *ends = strstr (s, srch);
+
+      if (ends == NULL)
+       break;
+      if (is_end_of_line (ends[sizeof (srch) - 1])
+         && (ends == start || is_end_of_line (ends[-1])))
+       return ends;
+      s = ends + sizeof (srch) - 1;
+    }
+
+  return NULL;
+}
+
 /* We read the file, putting things into a web that represents what we
    have been reading.  */
 void
@@ -955,8 +978,10 @@ read_a_source_file (const char *name)
 #endif
 
          next_char = *input_line_pointer;
-         if (was_new_line == 1 && next_char
-             && strchr (line_comment_chars, next_char))
+         if (was_new_line == 1
+             && (strchr (line_comment_chars, '#')
+                 ? next_char == '#'
+                 : next_char && strchr (line_comment_chars, next_char)))
            {
              /* Its a comment.  Check for APP followed by NO_APP.  */
              sb sbuf;
@@ -964,7 +989,7 @@ read_a_source_file (const char *name)
              size_t len;
 
              s = input_line_pointer + 1;
-             if (!startswith (s, "APP\n"))
+             if (!startswith (s, "APP") || !is_end_of_line (s[3]))
                {
                  /* We ignore it.  Note: Not ignore_rest_of_line ()!  */
                  while (s <= buffer_limit)
@@ -976,7 +1001,7 @@ read_a_source_file (const char *name)
              bump_line_counters ();
              s += 4;
 
-             ends = strstr (s, "#NO_APP\n");
+             ends = find_no_app (s, next_char);
              len = ends ? ends - s : buffer_limit - s;
 
              sb_build (&sbuf, len + 100);
@@ -992,7 +1017,7 @@ read_a_source_file (const char *name)
                      buffer_limit = input_scrub_next_buffer (&buffer);
                      if (!buffer_limit)
                        break;
-                     ends = strstr (buffer, "#NO_APP\n");
+                     ends = find_no_app (buffer, next_char);
                      len = ends ? ends - buffer : buffer_limit - buffer;
                      sb_add_buffer (&sbuf, buffer, len);
                    }