From ed45de98388acec5ed80b3a664c05b8b43f842ab Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Mon, 12 Apr 1999 12:03:10 +0000 Subject: [PATCH] cpphash.c (collect_expansion, [...]): Make the escape character in macro buffers '\r', not '@'. 1999-04-12 14:55 -0400 Zack Weinberg * cpphash.c (collect_expansion, macroexpand, push_macro_expansion): Make the escape character in macro buffers '\r', not '@'. Remove code to protect literal occurences of the escape character; '\r' cannot appear in a macro buffer unless we put it there. * cpplib.c (skip_comment, copy_comment, cpp_skip_hspace, copy_rest_of_line, cpp_get_token, parse_string, parse_assertion): '\r' might be a backslash-newline marker, or it might be a macro escape marker, depending on CPP_BUFFER (pfile)->has_escapes. '@' is not a special character. * cpplib.h: Update commentary. From-SVN: r26371 --- gcc/ChangeLog | 15 ++++++ gcc/cpphash.c | 57 ++++++-------------- gcc/cpplib.c | 141 ++++++++++++++++++++++++++++++-------------------- gcc/cpplib.h | 15 ++++-- 4 files changed, 125 insertions(+), 103 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f086b63474..148fb5772ef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +1999-04-12 14:55 -0400 Zack Weinberg + + * cpphash.c (collect_expansion, macroexpand, + push_macro_expansion): Make the escape character in macro + buffers '\r', not '@'. Remove code to protect literal + occurences of the escape character; '\r' cannot appear + in a macro buffer unless we put it there. + * cpplib.c (skip_comment, copy_comment, cpp_skip_hspace, + copy_rest_of_line, cpp_get_token, parse_string, + parse_assertion): '\r' might be a backslash-newline marker, or + it might be a macro escape marker, depending on + CPP_BUFFER (pfile)->has_escapes. '@' is not a special + character. + * cpplib.h: Update commentary. + Mon Apr 12 09:30:03 1999 Richard Earnshaw (rearnsha@arm.com) * arm.h (target_fp_name, structure_size_string, arm_cpu_select): diff --git a/gcc/cpphash.c b/gcc/cpphash.c index 5c2d5f3d800..06de9d443ef 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -304,10 +304,6 @@ collect_expansion (pfile, buf, limit, nargs, arglist) leading and trailing newline-marker and final null. */ maxsize = (sizeof (DEFINITION) + (limit - p) + 5); - /* Occurrences of '@' get doubled, so allocate extra space for them. */ - while (p < limit) - if (*p++ == '@') - maxsize++; defn = (DEFINITION *) xcalloc (1, maxsize); defn->nargs = nargs; @@ -318,7 +314,7 @@ collect_expansion (pfile, buf, limit, nargs, arglist) /* Add one initial space escape-marker to prevent accidental token-pasting (often removed by macroexpand). */ - *exp_p++ = '@'; + *exp_p++ = '\r'; *exp_p++ = ' '; if (limit - p >= 2 && p[0] == '#' && p[1] == '#') @@ -359,13 +355,6 @@ collect_expansion (pfile, buf, limit, nargs, arglist) } break; - case '@': - /* An '@' in a string or character constant stands for itself, - and does not need to be escaped. */ - if (!expected_delimiter) - *exp_p++ = c; - break; - case '#': /* # is ordinary inside a string. */ if (expected_delimiter) @@ -548,10 +537,10 @@ collect_expansion (pfile, buf, limit, nargs, arglist) if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0) { - /* If ANSI, put in a "@ " marker to prevent token pasting. + /* If ANSI, put in a "\r " marker to prevent token pasting. But not if "inside a string" (which in ANSI mode happens only for -D option). */ - *exp_p++ = '@'; + *exp_p++ = '\r'; *exp_p++ = ' '; } @@ -965,7 +954,7 @@ special_symbol (hp, pfile) if (!buf) return; if (*buf == '\0') - buf = "@ "; + buf = "\r "; len = strlen (buf); CPP_RESERVE (pfile, len + 1); @@ -1224,9 +1213,9 @@ macroexpand (pfile, hp) if (is_space[c]) { if (CPP_WRITTEN (pfile) > (unsigned) arg->stringified - && (CPP_PWRITTEN (pfile))[-1] == '@') + && (CPP_PWRITTEN (pfile))[-1] == '\r') { - /* "@ " escape markers are removed */ + /* "\r " escape markers are removed */ CPP_ADJUST_WRITTEN (pfile, -1); continue; } @@ -1360,27 +1349,11 @@ macroexpand (pfile, hp) { if (is_space[l1[-1]]) l1--; - else if (l1[-1] == '@') - { - U_CHAR *p2 = l1 - 1; - /* If whitespace is preceded by an odd number - of `@' signs, the last `@' was a whitespace - marker; drop it too. */ - while (p2 != p1 && p2[0] == '@') - p2--; - if ((l1 - p2) & 1) - l1--; - break; - } + else if (l1[-1] == '\r') + l1--; else if (l1[-1] == '-') { - U_CHAR *p2 = l1 - 1; - /* If a `-' is preceded by an odd number of - `@' signs then it and the last `@' are - a no-reexpansion marker. */ - while (p2 != p1 && p2[0] == '@') - p2--; - if ((l1 - p2) & 1) + if (l1 != p1 + 1 && l1[-2] == '\r') l1 -= 2; else break; @@ -1392,7 +1365,7 @@ macroexpand (pfile, hp) /* Delete any no-reexpansion marker that precedes an identifier at the beginning of the argument. */ - if (p1[0] == '@' && p1[1] == '-') + if (p1[0] == '\r' && p1[1] == '-') p1 += 2; bcopy (p1, xbuf + totlen, l1 - p1); @@ -1405,7 +1378,7 @@ macroexpand (pfile, hp) && !CPP_TRADITIONAL (pfile) && unsafe_chars (xbuf[totlen - 1], expanded[0])) { - xbuf[totlen++] = '@'; + xbuf[totlen++] = '\r'; xbuf[totlen++] = ' '; } @@ -1416,7 +1389,7 @@ macroexpand (pfile, hp) && !CPP_TRADITIONAL (pfile) && unsafe_chars (xbuf[totlen - 1], exp[offset])) { - xbuf[totlen++] = '@'; + xbuf[totlen++] = '\r'; xbuf[totlen++] = ' '; } @@ -1533,7 +1506,7 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp) mbuf->cleanup = macro_cleanup; mbuf->data = hp; - /* The first chars of the expansion should be a "@ " added by + /* The first chars of the expansion should be a "\r " added by collect_expansion. This is to prevent accidental token-pasting between the text preceding the macro invocation, and the macro expansion text. @@ -1551,7 +1524,7 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp) Also, we don't need the extra space if the first char is '(', or some other (less common) characters. */ - if (xbuf[0] == '@' && xbuf[1] == ' ' + if (xbuf[0] == '\r' && xbuf[1] == ' ' && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\'' || xbuf[2] == '\"')) mbuf->cur += 2; @@ -1560,7 +1533,7 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp) if this is safe. We can do a better job here since we can know what the next char will be. */ if (xbuf_len >= 3 - && mbuf->rlimit[-2] == '@' + && mbuf->rlimit[-2] == '\r' && mbuf->rlimit[-1] == ' ') { int c1 = mbuf->rlimit[-3]; diff --git a/gcc/cpplib.c b/gcc/cpplib.c index d50848698b0..3ed75db1d66 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -260,6 +260,7 @@ skip_comment (pfile, m) return EOF; } else if (c == '\n' || c == '\r') + /* \r cannot be a macro escape marker here. */ CPP_BUMP_LINE (pfile); else if (c == '/' && prev_c == '*') return ' '; @@ -288,6 +289,7 @@ skip_comment (pfile, m) return ' '; } else if (c == '\r') + /* \r cannot be a macro escape marker here. */ CPP_BUMP_LINE (pfile); } } @@ -323,6 +325,7 @@ copy_comment (pfile, m) } else if (c == '\r') { + /* \r cannot be a macro escape marker here. */ CPP_BUMP_LINE (pfile); continue; } @@ -362,6 +365,7 @@ copy_comment (pfile, m) return ' '; } else if (c == '\r') + /* \r cannot be a macro escape marker here. */ CPP_BUMP_LINE (pfile); CPP_PUTC (pfile, c); @@ -392,7 +396,17 @@ cpp_skip_hspace (pfile) } else if (c == '\r') { - CPP_BUFFER (pfile)->lineno++; + /* \r is a backslash-newline marker if !has_escapes, and + a deletable-whitespace or no-reexpansion marker otherwise. */ + if (CPP_BUFFER (pfile)->has_escapes) + { + if (PEEKC() == ' ') + FORWARD(1); + else + break; + } + else + CPP_BUFFER (pfile)->lineno++; } else if (c == '/' || c == '-') { @@ -400,22 +414,12 @@ cpp_skip_hspace (pfile) if (c == EOF) return; else if (c != ' ') - { - FORWARD(-1); - return; - } - } - else if (c == '@' && CPP_BUFFER (pfile)->has_escapes - && PEEKC() == ' ') - { - FORWARD(1); + break; } else - { - FORWARD(-1); - return; - } + break; } + FORWARD(-1); } /* Read the rest of the current line. @@ -437,8 +441,13 @@ copy_rest_of_line (pfile) return; case '\r': - CPP_BUFFER (pfile)->lineno++; - continue; + if (CPP_BUFFER (pfile)->has_escapes) + break; + else + { + CPP_BUFFER (pfile)->lineno++; + continue; + } case '\'': case '\"': parse_string (pfile, c); @@ -2233,9 +2242,23 @@ cpp_get_token (pfile) } else if (c == '\r') { - /* Backslash newline is replaced by nothing. */ - CPP_ADJUST_WRITTEN (pfile, -1); - CPP_BUMP_LINE (pfile); + if (!CPP_BUFFER (pfile)->has_escapes) + { + /* Backslash newline is replaced by nothing. */ + CPP_ADJUST_WRITTEN (pfile, -1); + CPP_BUMP_LINE (pfile); + } + else + { + /* We might conceivably get \r- or \r in + here. Just delete 'em. */ + int d = GETC(); + if (d != '-' && d != ' ') + cpp_fatal (pfile, + "internal error: unrecognized escape \\r%c", + d); + CPP_ADJUST_WRITTEN (pfile, -1); + } } } return CPP_STRING; @@ -2258,33 +2281,6 @@ cpp_get_token (pfile) pfile->only_seen_white = 0; return CPP_OTHER; - case '@': - if (CPP_BUFFER (pfile)->has_escapes) - { - c = GETC (); - if (c == '-') - { - if (pfile->output_escapes) - CPP_PUTS (pfile, "@-", 2); - parse_name (pfile, GETC ()); - return CPP_NAME; - } - else if (c == ' ') - { - CPP_RESERVE (pfile, 2); - if (pfile->output_escapes) - CPP_PUTC_Q (pfile, '@'); - CPP_PUTC_Q (pfile, c); - return CPP_HSPACE; - } - } - if (pfile->output_escapes) - { - CPP_PUTS (pfile, "@@", 2); - return CPP_OTHER; - } - goto randomchar; - case '.': c2 = PEEKC (); if (ISDIGIT(c2)) @@ -2410,13 +2406,13 @@ cpp_get_token (pfile) if (hp->type == T_DISABLED) { if (pfile->output_escapes) - { /* Return "@-IDENT", followed by '\0'. */ + { /* Return "\r-IDENT", followed by '\0'. */ int i; CPP_RESERVE (pfile, 3); ident = pfile->token_buffer + before_name_written; CPP_ADJUST_WRITTEN (pfile, 2); for (i = ident_len; i >= 0; i--) ident[i+2] = ident[i]; - ident[0] = '@'; + ident[0] = '\r'; ident[1] = '-'; } return CPP_NAME; @@ -2490,13 +2486,38 @@ cpp_get_token (pfile) } return CPP_HSPACE; - case '\\': - goto randomchar; - case '\r': - /* Backslash newline is ignored. */ - CPP_BUMP_LINE (pfile); - goto get_next; + if (CPP_BUFFER (pfile)->has_escapes) + { + c = GETC (); + if (c == '-') + { + if (pfile->output_escapes) + CPP_PUTS (pfile, "\r-", 2); + parse_name (pfile, GETC ()); + return CPP_NAME; + } + else if (c == ' ') + { + CPP_RESERVE (pfile, 2); + if (pfile->output_escapes) + CPP_PUTC_Q (pfile, '\r'); + CPP_PUTC_Q (pfile, c); + return CPP_HSPACE; + } + else + { + cpp_fatal (pfile, + "internal error: unrecognized escape \\r%c", c); + goto get_next; + } + } + else + { + /* Backslash newline is ignored. */ + CPP_BUMP_LINE (pfile); + goto get_next; + } case '\n': CPP_PUTC (pfile, c); @@ -2639,9 +2660,16 @@ parse_string (pfile, c) break; case '\r': - /* Backslash newline is replaced by nothing at all. */ CPP_ADJUST_WRITTEN (pfile, -1); - CPP_BUMP_LINE (pfile); + if (CPP_BUFFER (pfile)->has_escapes) + { + cpp_fatal (pfile, + "internal error: \\r escape inside string constant"); + FORWARD(1); + } + else + /* Backslash newline is replaced by nothing at all. */ + CPP_BUMP_LINE (pfile); break; case '\\': @@ -2711,6 +2739,7 @@ parse_assertion (pfile) return 0; } else if (c == '\r') + /* \r cannot be a macro escape here. */ CPP_BUMP_LINE (pfile); else { diff --git a/gcc/cpplib.h b/gcc/cpplib.h index ccf8f929642..bffd493232f 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -124,12 +124,17 @@ struct cpp_buffer char seen_eof; /* True if buffer contains escape sequences. - Currently there are three kinds: - "@-" means following identifier should not be macro-expanded. - "@ " means a token-separator. This turns into " " in final output + Currently there are two kinds: + "\r-" means following identifier should not be macro-expanded. + "\r " means a token-separator. This turns into " " in final output if not stringizing and needed to separate tokens; otherwise nothing. - "@@" means a normal '@'. - (An '@' inside a string stands for itself and is never an escape.) */ + Any other two-character sequence beginning with \r is an error. + + If this is NOT set, then \r is a one-character escape meaning backslash + newline. This is guaranteed not to occur in the middle of a token. + The two interpretations of \r do not conflict, because the two-character + escapes are used only in macro buffers, and backslash-newline is removed + from macro expansion text in collect_expansion and/or macarg. */ char has_escapes; }; -- 2.30.2