aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2024-08-05 16:29:28 +0200
committerJan Beulich <jbeulich@suse.com>2024-08-05 16:29:28 +0200
commit526363dbe4524a5364853276caba3306b813b71c (patch)
treea90258e3555bbc16707dcb0c34a552c2ba3b8789
parent1068b74548858fe9c8ed17f0bba8b136111fbec9 (diff)
downloadgdb-526363dbe4524a5364853276caba3306b813b71c.zip
gdb-526363dbe4524a5364853276caba3306b813b71c.tar.gz
gdb-526363dbe4524a5364853276caba3306b813b71c.tar.bz2
gas: generalize / tighten #APP / #NO_APP recognition
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.
-rw-r--r--gas/input-file.c16
-rw-r--r--gas/read.c35
2 files changed, 40 insertions, 11 deletions
diff --git a/gas/input-file.c b/gas/input-file.c
index 89f03a9..c96d276 100644
--- a/gas/input-file.c
+++ b/gas/input-file.c
@@ -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);
diff --git a/gas/read.c b/gas/read.c
index c6fb3dc..7855193 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -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);
}