From: Jan Beulich Date: Mon, 5 Aug 2024 14:29:28 +0000 (+0200) Subject: gas: generalize / tighten #APP / #NO_APP recognition X-Git-Tag: gdb-16-branchpoint~1227 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=526363dbe4524a5364853276caba3306b813b71c;p=thirdparty%2Fbinutils-gdb.git 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. --- diff --git a/gas/input-file.c b/gas/input-file.c index 89f03a98be8..c96d2760a47 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 c6fb3dc5a1d..78551937ccd 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 NO_APP, if any, in the supplied buffer. + Return NULL if there's none, or else the position of . */ +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); }