Commit 5bdc1512 by Richard Kenner

(enum sharp_token_type): New type.

(stringify, raw_before, raw_after): Use this type instead of char.
(collect_expansion, dump_single_macro): Keep track of white space
after # and around ## tokens, since the C Standard requires a
diagnostic if the white space doesn't match during a redefinition.
(sharp_token, sharp_sharp_token): Labels renamed from hash_token and
hash_hash_token for naming consistency.

From-SVN: r9036
parent 34dd3838
...@@ -677,6 +677,16 @@ struct macrodef ...@@ -677,6 +677,16 @@ struct macrodef
static struct macrodef create_definition (); static struct macrodef create_definition ();
enum sharp_token_type {
NO_SHARP_TOKEN, /* token not present */
SHARP_TOKEN = '#', /* token spelled with # only */
WHITE_SHARP_TOKEN, /* token spelled with # and white space */
PERCENT_COLON_TOKEN = '%', /* token spelled with %: only */
WHITE_PERCENT_COLON_TOKEN /* token spelled with %: and white space */
};
/* Structure allocated for every #define. For a simple replacement /* Structure allocated for every #define. For a simple replacement
such as such as
#define foo bar , #define foo bar ,
...@@ -711,12 +721,9 @@ struct definition { ...@@ -711,12 +721,9 @@ struct definition {
struct reflist { struct reflist {
struct reflist *next; struct reflist *next;
/* The following three members have the value '#' if spelled with "#", enum sharp_token_type stringify; /* set if a # operator before arg */
and '%' if spelled with "%:". */ enum sharp_token_type raw_before; /* set if a ## operator before arg */
char stringify; /* nonzero if this arg was preceded by a enum sharp_token_type raw_after; /* set if a ## operator after arg */
# operator. */
char raw_before; /* Nonzero if a ## operator before arg. */
char raw_after; /* Nonzero if a ## operator after arg. */
char rest_args; /* Nonzero if this arg. absorbs the rest */ char rest_args; /* Nonzero if this arg. absorbs the rest */
int nchars; /* Number of literal chars to copy before int nchars; /* Number of literal chars to copy before
...@@ -5757,9 +5764,9 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5757,9 +5764,9 @@ collect_expansion (buf, end, nargs, arglist)
U_CHAR *concat = 0; U_CHAR *concat = 0;
/* Pointer to first nonspace after last single-# seen. */ /* Pointer to first nonspace after last single-# seen. */
U_CHAR *stringify = 0; U_CHAR *stringify = 0;
/* How those tokens were spelled: 0, '#', or '%' (meaning %:). */ /* How those tokens were spelled. */
char concat_spelling = 0; enum sharp_token_type concat_sharp_token_type = NO_SHARP_TOKEN;
char stringify_spelling = 0; enum sharp_token_type stringify_sharp_token_type = NO_SHARP_TOKEN;
int maxsize; int maxsize;
int expected_delimiter = '\0'; int expected_delimiter = '\0';
...@@ -5843,11 +5850,11 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5843,11 +5850,11 @@ collect_expansion (buf, end, nargs, arglist)
/* Treat %:%: as ## and %: as #. */ /* Treat %:%: as ## and %: as #. */
if (p[1] == '%' && p[2] == ':') { if (p[1] == '%' && p[2] == ':') {
p += 2; p += 2;
goto hash_hash_token; goto sharp_sharp_token;
} }
if (nargs >= 0) { if (nargs >= 0) {
p++; p++;
goto hash_token; goto sharp_token;
} }
} }
} }
...@@ -5858,7 +5865,7 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5858,7 +5865,7 @@ collect_expansion (buf, end, nargs, arglist)
if (expected_delimiter) if (expected_delimiter)
break; break;
if (*p == '#') { if (*p == '#') {
hash_hash_token: sharp_sharp_token:
/* ##: concatenate preceding and following tokens. */ /* ##: concatenate preceding and following tokens. */
/* Take out the first #, discard preceding whitespace. */ /* Take out the first #, discard preceding whitespace. */
exp_p--; exp_p--;
...@@ -5866,24 +5873,30 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5866,24 +5873,30 @@ collect_expansion (buf, end, nargs, arglist)
--exp_p; --exp_p;
/* Skip the second #. */ /* Skip the second #. */
p++; p++;
/* Discard following whitespace. */ concat_sharp_token_type = c;
SKIP_WHITE_SPACE (p); if (is_hor_space[*p]) {
concat_sharp_token_type++;
p++;
SKIP_WHITE_SPACE (p);
}
concat = p; concat = p;
concat_spelling = c;
if (p == limit) if (p == limit)
error ("`##' at end of macro definition"); error ("`##' at end of macro definition");
} else if (nargs >= 0) { } else if (nargs >= 0) {
/* Single #: stringify following argument ref. /* Single #: stringify following argument ref.
Don't leave the # in the expansion. */ Don't leave the # in the expansion. */
hash_token: sharp_token:
exp_p--; exp_p--;
SKIP_WHITE_SPACE (p); stringify_sharp_token_type = c;
if (is_hor_space[*p]) {
stringify_sharp_token_type++;
p++;
SKIP_WHITE_SPACE (p);
}
if (! is_idstart[*p] || nargs == 0) if (! is_idstart[*p] || nargs == 0)
error ("`#' operator is not followed by a macro argument name"); error ("`#' operator is not followed by a macro argument name");
else { else
stringify = p; stringify = p;
stringify_spelling = c;
}
} }
break; break;
} }
...@@ -5965,11 +5978,13 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5965,11 +5978,13 @@ collect_expansion (buf, end, nargs, arglist)
the pat list */ the pat list */
tpat = (struct reflist *) xmalloc (sizeof (struct reflist)); tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
tpat->next = NULL; tpat->next = NULL;
tpat->raw_before = concat == id_beg ? concat_spelling : 0; tpat->raw_before
tpat->raw_after = 0; = concat == id_beg ? concat_sharp_token_type : NO_SHARP_TOKEN;
tpat->raw_after = NO_SHARP_TOKEN;
tpat->rest_args = arg->rest_args; tpat->rest_args = arg->rest_args;
tpat->stringify = (traditional ? expected_delimiter != '\0' tpat->stringify
: stringify == id_beg) ? stringify_spelling : 0; = ((traditional ? expected_delimiter : stringify == id_beg)
? stringify_sharp_token_type : NO_SHARP_TOKEN);
if (endpat == NULL) if (endpat == NULL)
defn->pattern = tpat; defn->pattern = tpat;
...@@ -5985,7 +6000,7 @@ collect_expansion (buf, end, nargs, arglist) ...@@ -5985,7 +6000,7 @@ collect_expansion (buf, end, nargs, arglist)
if (p1[0]=='#' if (p1[0]=='#'
? p1[1]=='#' ? p1[1]=='#'
: p1[0]=='%' && p1[1]==':' && p1[2]=='%' && p1[3]==':') : p1[0]=='%' && p1[1]==':' && p1[2]=='%' && p1[3]==':')
tpat->raw_after = p1[0]; tpat->raw_after = p1[0] + (p != p1);
} }
lastp = exp_p; /* place to start copying from next time */ lastp = exp_p; /* place to start copying from next time */
skipped_arg = 1; skipped_arg = 1;
...@@ -7105,14 +7120,14 @@ skip_if_group (ip, any, op) ...@@ -7105,14 +7120,14 @@ skip_if_group (ip, any, op)
while (bp[0] == '\\' && bp[1] == '\n') while (bp[0] == '\\' && bp[1] == '\n')
bp += 2; bp += 2;
if (*bp == ':') if (*bp == ':')
goto hash_token; goto sharp_token;
break; break;
case '#': case '#':
/* # keyword: a # must be first nonblank char on the line */ /* # keyword: a # must be first nonblank char on the line */
if (beg_of_line == 0) if (beg_of_line == 0)
break; break;
ip->bufp = bp - 1; ip->bufp = bp - 1;
hash_token: sharp_token:
/* Scan from start of line, skipping whitespace, comments /* Scan from start of line, skipping whitespace, comments
and backslash-newlines, and see if we reach this #. and backslash-newlines, and see if we reach this #.
If not, this # is not special. */ If not, this # is not special. */
...@@ -9153,15 +9168,41 @@ dump_single_macro (hp, of) ...@@ -9153,15 +9168,41 @@ dump_single_macro (hp, of)
if (!traditional) { if (!traditional) {
if (ap->nchars != 0) if (ap->nchars != 0)
concat = 0; concat = 0;
if (ap->stringify) if (ap->stringify) {
fprintf (of, ap->stringify == '#' ? " #" : " %:"); switch (ap->stringify) {
if (ap->raw_before && !concat) case SHARP_TOKEN: fprintf (of, "#"); break;
fprintf (of, ap->raw_before == '#' ? " ## " : " %:%: "); case WHITE_SHARP_TOKEN: fprintf (of, "# "); break;
case PERCENT_COLON_TOKEN: fprintf (of, "%:"); break;
case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%: "); break;
}
}
if (ap->raw_before) {
if (concat) {
switch (ap->raw_before) {
case WHITE_SHARP_TOKEN:
case WHITE_PERCENT_COLON_TOKEN:
fprintf (of, " ");
break;
}
} else {
switch (ap->raw_before) {
case SHARP_TOKEN: fprintf (of, "##"); break;
case WHITE_SHARP_TOKEN: fprintf (of, "## "); break;
case PERCENT_COLON_TOKEN: fprintf (of, "%:%:"); break;
case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%:%: "); break;
}
}
}
concat = 0; concat = 0;
} }
dump_arg_n (defn, ap->argno, of); dump_arg_n (defn, ap->argno, of);
if (!traditional && ap->raw_after) { if (!traditional && ap->raw_after) {
fprintf (of, ap->raw_after == '#' ? " ## " : " %:%: "); switch (ap->raw_after) {
case SHARP_TOKEN: fprintf (of, "##"); break;
case WHITE_SHARP_TOKEN: fprintf (of, " ##"); break;
case PERCENT_COLON_TOKEN: fprintf (of, "%:%:"); break;
case WHITE_PERCENT_COLON_TOKEN: fprintf (of, " %:%:"); break;
}
concat = 1; concat = 1;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment