+1999-04-12 14:55 -0400 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * 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):
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;
/* 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] == '#')
}
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)
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++ = ' ';
}
if (!buf)
return;
if (*buf == '\0')
- buf = "@ ";
+ buf = "\r ";
len = strlen (buf);
CPP_RESERVE (pfile, len + 1);
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;
}
{
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;
/* 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);
&& !CPP_TRADITIONAL (pfile)
&& unsafe_chars (xbuf[totlen - 1], expanded[0]))
{
- xbuf[totlen++] = '@';
+ xbuf[totlen++] = '\r';
xbuf[totlen++] = ' ';
}
&& !CPP_TRADITIONAL (pfile)
&& unsafe_chars (xbuf[totlen - 1], exp[offset]))
{
- xbuf[totlen++] = '@';
+ xbuf[totlen++] = '\r';
xbuf[totlen++] = ' ';
}
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.
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;
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];
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 ' ';
return ' ';
}
else if (c == '\r')
+ /* \r cannot be a macro escape marker here. */
CPP_BUMP_LINE (pfile);
}
}
}
else if (c == '\r')
{
+ /* \r cannot be a macro escape marker here. */
CPP_BUMP_LINE (pfile);
continue;
}
return ' ';
}
else if (c == '\r')
+ /* \r cannot be a macro escape marker here. */
CPP_BUMP_LINE (pfile);
CPP_PUTC (pfile, c);
}
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 == '-')
{
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.
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);
}
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<space> 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;
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))
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;
}
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);
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 '\\':
return 0;
}
else if (c == '\r')
+ /* \r cannot be a macro escape here. */
CPP_BUMP_LINE (pfile);
else
{
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;
};