Commit d0691cfb by Richard Stallman

(macroexpand): Before concatenated empty rest arg,

do copy constant chars, but delete last run of nonwhitespace chars.
(rescan): Handle Newline-Hyphen in expand_to_temp_buffer
as well as when scanning a macro body.

(main): If we are creating a new dependency file with -MD
or -MMD, use "w" fopen mode instead of "a".

(rescan): Prevent token pasting before macro call.
(macroexpand): Prevent token pasting around an arg unless it's raw.

(main): Implement -iwithprefix.

(check_preconditions, do_error, do_warning, do_xifdef):
Don't use signed chars to index into arrays; they might be negative.

From-SVN: r3199
parent df8b4049
...@@ -963,6 +963,8 @@ main (argc, argv) ...@@ -963,6 +963,8 @@ main (argc, argv)
/* File name which deps are being written to. /* File name which deps are being written to.
This is 0 if deps are being written to stdout. */ This is 0 if deps are being written to stdout. */
char *deps_file = 0; char *deps_file = 0;
/* Fopen file mode to open deps_file with. */
char *deps_mode = "a";
/* Stream on which to print the dependency information. */ /* Stream on which to print the dependency information. */
FILE *deps_stream = 0; FILE *deps_stream = 0;
/* Target-name to write with the dependency information. */ /* Target-name to write with the dependency information. */
...@@ -1035,22 +1037,45 @@ main (argc, argv) ...@@ -1035,22 +1037,45 @@ main (argc, argv)
case 'i': case 'i':
if (!strcmp (argv[i], "-include")) { if (!strcmp (argv[i], "-include")) {
if (i + 1 == argc) if (i + 1 == argc)
fatal ("Filename missing after -include option"); fatal ("Filename missing after `-include' option");
else else
pend_includes[i] = argv[i+1], i++; pend_includes[i] = argv[i+1], i++;
} }
if (!strcmp (argv[i], "-imacros")) { if (!strcmp (argv[i], "-imacros")) {
if (i + 1 == argc) if (i + 1 == argc)
fatal ("Filename missing after -imacros option"); fatal ("Filename missing after `-imacros' option");
else else
pend_files[i] = argv[i+1], i++; pend_files[i] = argv[i+1], i++;
} }
if (!strcmp (argv[i], "-iprefix")) { if (!strcmp (argv[i], "-iprefix")) {
if (i + 1 == argc) if (i + 1 == argc)
fatal ("Filename missing after -iprefix option"); fatal ("Filename missing after `-iprefix' option");
else else
include_prefix = argv[++i]; include_prefix = argv[++i];
} }
/* Add directory to end of path for includes,
with the default prefix at the front of its name. */
if (!strcmp (argv[i], "-iwithprefix")) {
struct file_name_list *dirtmp;
dirtmp = (struct file_name_list *)
xmalloc (sizeof (struct file_name_list));
dirtmp->next = 0; /* New one goes on the end */
dirtmp->control_macro = 0;
if (i + 1 == argc)
fatal ("Directory name missing after `-iwithprefix' option");
dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
+ strlen (include_prefix) + 1);
strcpy (dirtmp->fname, include_prefix);
strcat (dirtmp->fname, argv[++i]);
if (after_include == 0)
after_include = dirtmp;
else
last_after_include->next = dirtmp;
last_after_include = dirtmp; /* Tail follows the last one */
}
/* Add directory to end of path for includes. */ /* Add directory to end of path for includes. */
if (!strcmp (argv[i], "-idirafter")) { if (!strcmp (argv[i], "-idirafter")) {
struct file_name_list *dirtmp; struct file_name_list *dirtmp;
...@@ -1060,7 +1085,7 @@ main (argc, argv) ...@@ -1060,7 +1085,7 @@ main (argc, argv)
dirtmp->next = 0; /* New one goes on the end */ dirtmp->next = 0; /* New one goes on the end */
dirtmp->control_macro = 0; dirtmp->control_macro = 0;
if (i + 1 == argc) if (i + 1 == argc)
fatal ("Directory name missing after -idirafter option"); fatal ("Directory name missing after `-idirafter' option");
else else
dirtmp->fname = argv[++i]; dirtmp->fname = argv[++i];
...@@ -1179,6 +1204,7 @@ main (argc, argv) ...@@ -1179,6 +1204,7 @@ main (argc, argv)
|| !strcmp (argv[i], "-MMD")) { || !strcmp (argv[i], "-MMD")) {
i++; i++;
deps_file = argv[i]; deps_file = argv[i];
deps_mode = "w";
} else { } else {
/* For -M and -MM, write deps on standard output /* For -M and -MM, write deps on standard output
and suppress the usual output. */ and suppress the usual output. */
...@@ -1656,6 +1682,7 @@ main (argc, argv) ...@@ -1656,6 +1682,7 @@ main (argc, argv)
} }
deps_file = output_file; deps_file = output_file;
deps_mode = "a";
} }
/* For -M, print the expected object file name /* For -M, print the expected object file name
...@@ -1822,7 +1849,7 @@ main (argc, argv) ...@@ -1822,7 +1849,7 @@ main (argc, argv)
if (print_deps) { if (print_deps) {
/* Don't actually write the deps file if compilation has failed. */ /* Don't actually write the deps file if compilation has failed. */
if (errors == 0) { if (errors == 0) {
if (deps_file && ! (deps_stream = fopen (deps_file, "a"))) if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode)))
pfatal_with_name (deps_file); pfatal_with_name (deps_file);
fputs (deps_buffer, deps_stream); fputs (deps_buffer, deps_stream);
putc ('\n', deps_stream); putc ('\n', deps_stream);
...@@ -2621,30 +2648,34 @@ do { ip = &instack[indepth]; \ ...@@ -2621,30 +2648,34 @@ do { ip = &instack[indepth]; \
break; break;
case '\n': case '\n':
if (ip->fname == 0 && *ibp == '-') {
/* Newline - inhibits expansion of preceding token.
If expanding a macro arg, we keep the newline -.
In final output, it is deleted.
We recognize Newline - in macro bodies and macro args. */
if (! concatenated) {
ident_length = 0;
hash = 0;
}
ibp++;
if (!output_marks) {
obp--;
} else {
/* If expanding a macro arg, keep the newline -. */
*obp++ = '-';
}
break;
}
/* If reprocessing a macro expansion, newline is a special marker. */ /* If reprocessing a macro expansion, newline is a special marker. */
if (ip->macro != 0) { else if (ip->macro != 0) {
/* Newline White is a "funny space" to separate tokens that are /* Newline White is a "funny space" to separate tokens that are
supposed to be separate but without space between. supposed to be separate but without space between.
Here White means any whitespace character. Here White means any whitespace character.
Newline - marks a recursive macro use that is not Newline - marks a recursive macro use that is not
supposed to be expandable. */ supposed to be expandable. */
if (*ibp == '-') { if (is_space[*ibp]) {
/* Newline - inhibits expansion of preceding token.
If expanding a macro arg, we keep the newline -.
In final output, it is deleted. */
if (! concatenated) {
ident_length = 0;
hash = 0;
}
ibp++;
if (!output_marks) {
obp--;
} else {
/* If expanding a macro arg, keep the newline -. */
*obp++ = '-';
}
} else if (is_space[*ibp]) {
/* Newline Space does not prevent expansion of preceding token /* Newline Space does not prevent expansion of preceding token
so expand the preceding token and then come back. */ so expand the preceding token and then come back. */
if (ident_length > 0) if (ident_length > 0)
...@@ -2918,7 +2949,20 @@ startagain: ...@@ -2918,7 +2949,20 @@ startagain:
along with any following whitespace just copied. */ along with any following whitespace just copied. */
obp = op->buf + obufp_before_macroname; obp = op->buf + obufp_before_macroname;
op->lineno = op_lineno_before_macroname; op->lineno = op_lineno_before_macroname;
/* Prevent accidental token-pasting with a character
before the macro call. */
if (!traditional && obp != op->buf
&& (obp[-1] == '-' || obp[1] == '+' || obp[1] == '&'
|| obp[-1] == '|' || obp[1] == '<' || obp[1] == '>')) {
/* If we are expanding a macro arg, make a newline marker
to separate the tokens. If we are making real output,
a plain space will do. */
if (output_marks)
*obp++ = '\n';
*obp++ = ' ';
}
/* Expand the macro, reading arguments as needed, /* Expand the macro, reading arguments as needed,
and push the expansion on the input stack. */ and push the expansion on the input stack. */
ip->bufp = ibp; ip->bufp = ibp;
...@@ -4390,10 +4434,10 @@ check_preconditions (prec) ...@@ -4390,10 +4434,10 @@ check_preconditions (prec)
int len; int len;
prec += 5; prec += 5;
while (is_hor_space[*prec]) while (is_hor_space[(U_CHAR) *prec])
prec++; prec++;
name = prec; name = prec;
while (is_idchar[*prec]) while (is_idchar[(U_CHAR) *prec])
prec++; prec++;
len = prec - name; len = prec - name;
...@@ -5840,7 +5884,7 @@ do_error (buf, limit, op, keyword) ...@@ -5840,7 +5884,7 @@ do_error (buf, limit, op, keyword)
struct directive *keyword; struct directive *keyword;
{ {
int length = limit - buf; int length = limit - buf;
char *copy = (char *) xmalloc (length + 1); U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
bcopy (buf, copy, length); bcopy (buf, copy, length);
copy[length] = 0; copy[length] = 0;
SKIP_WHITE_SPACE (copy); SKIP_WHITE_SPACE (copy);
...@@ -5863,7 +5907,7 @@ do_warning (buf, limit, op, keyword) ...@@ -5863,7 +5907,7 @@ do_warning (buf, limit, op, keyword)
struct directive *keyword; struct directive *keyword;
{ {
int length = limit - buf; int length = limit - buf;
char *copy = (char *) xmalloc (length + 1); U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
bcopy (buf, copy, length); bcopy (buf, copy, length);
copy[length] = 0; copy[length] = 0;
SKIP_WHITE_SPACE (copy); SKIP_WHITE_SPACE (copy);
...@@ -6107,7 +6151,7 @@ do_xifdef (buf, limit, op, keyword) ...@@ -6107,7 +6151,7 @@ do_xifdef (buf, limit, op, keyword)
if (ip->fname != 0 && keyword->type == T_IFNDEF) { if (ip->fname != 0 && keyword->type == T_IFNDEF) {
U_CHAR *p = ip->buf; U_CHAR *p = ip->buf;
while (p != directive_start) { while (p != directive_start) {
char c = *p++; U_CHAR c = *p++;
if (is_space[c]) if (is_space[c])
; ;
else if (c == '/' && p != ip->bufp && *p == '*') { else if (c == '/' && p != ip->bufp && *p == '*') {
...@@ -7010,7 +7054,9 @@ macroexpand (hp, op) ...@@ -7010,7 +7054,9 @@ macroexpand (hp, op)
if (ap->stringify) if (ap->stringify)
xbuf_len += args[ap->argno].stringified_length; xbuf_len += args[ap->argno].stringified_length;
else if (ap->raw_before || ap->raw_after || traditional) else if (ap->raw_before || ap->raw_after || traditional)
xbuf_len += args[ap->argno].raw_length; /* Add 4 for two newline-space markers to prevent
token concatenation. */
xbuf_len += args[ap->argno].raw_length + 4;
else { else {
/* We have an ordinary (expanded) occurrence of the arg. /* We have an ordinary (expanded) occurrence of the arg.
So compute its expansion, if we have not already. */ So compute its expansion, if we have not already. */
...@@ -7025,7 +7071,9 @@ macroexpand (hp, op) ...@@ -7025,7 +7071,9 @@ macroexpand (hp, op)
args[ap->argno].free2 = obuf.buf; args[ap->argno].free2 = obuf.buf;
} }
xbuf_len += args[ap->argno].expand_length; /* Add 4 for two newline-space markers to prevent
token concatenation. */
xbuf_len += args[ap->argno].expand_length + 4;
} }
if (args[ap->argno].use_count < 10) if (args[ap->argno].use_count < 10)
args[ap->argno].use_count++; args[ap->argno].use_count++;
...@@ -7042,13 +7090,28 @@ macroexpand (hp, op) ...@@ -7042,13 +7090,28 @@ macroexpand (hp, op)
for (last_ap = NULL, ap = defn->pattern; ap != NULL; for (last_ap = NULL, ap = defn->pattern; ap != NULL;
last_ap = ap, ap = ap->next) { last_ap = ap, ap = ap->next) {
register struct argdata *arg = &args[ap->argno]; register struct argdata *arg = &args[ap->argno];
int count_before = totlen;
/* add chars to XBUF unless rest_args was zero with concatenation */ /* Add chars to XBUF. */
for (i = 0; i < ap->nchars; i++, offset++) for (i = 0; i < ap->nchars; i++, offset++)
if (! (rest_zero && ((ap->rest_args && ap->raw_before) xbuf[totlen++] = exp[offset];
|| (last_ap != NULL && last_ap->rest_args
&& last_ap->raw_after)))) /* If followed by an empty rest arg with concatenation,
xbuf[totlen++] = exp[offset]; delete the last run of nonwhite chars. */
if (rest_zero && totlen > count_before
&& ((ap->rest_args && ap->raw_before)
|| (last_ap != NULL && last_ap->rest_args
&& last_ap->raw_after))) {
/* Delete final whitespace. */
while (totlen > count_before && is_space[xbuf[totlen - 1]]) {
totlen--;
}
/* Delete the nonwhites before them. */
while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) {
totlen--;
}
}
if (ap->stringify != 0) { if (ap->stringify != 0) {
int arglen = arg->raw_length; int arglen = arg->raw_length;
...@@ -7128,6 +7191,11 @@ macroexpand (hp, op) ...@@ -7128,6 +7191,11 @@ macroexpand (hp, op)
if the argument is concatenated with what precedes it. */ if the argument is concatenated with what precedes it. */
if (p1[0] == '\n' && p1[1] == '-') if (p1[0] == '\n' && p1[1] == '-')
p1 += 2; p1 += 2;
} else if (!traditional) {
/* Ordinary expanded use of the argument.
Put in newline-space markers to prevent token pasting. */
xbuf[totlen++] = '\n';
xbuf[totlen++] = ' ';
} }
if (ap->raw_after) { if (ap->raw_after) {
/* Arg is concatenated after: delete trailing whitespace, /* Arg is concatenated after: delete trailing whitespace,
...@@ -7147,11 +7215,28 @@ macroexpand (hp, op) ...@@ -7147,11 +7215,28 @@ macroexpand (hp, op)
else break; else break;
} }
} }
bcopy (p1, xbuf + totlen, l1 - p1); bcopy (p1, xbuf + totlen, l1 - p1);
totlen += l1 - p1; totlen += l1 - p1;
if (!traditional && !ap->raw_after) {
/* Ordinary expanded use of the argument.
Put in newline-space markers to prevent token pasting. */
xbuf[totlen++] = '\n';
xbuf[totlen++] = ' ';
}
} else { } else {
/* Ordinary expanded use of the argument.
Put in newline-space markers to prevent token pasting. */
if (!traditional) {
xbuf[totlen++] = '\n';
xbuf[totlen++] = ' ';
}
bcopy (arg->expanded, xbuf + totlen, arg->expand_length); bcopy (arg->expanded, xbuf + totlen, arg->expand_length);
totlen += arg->expand_length; totlen += arg->expand_length;
if (!traditional) {
xbuf[totlen++] = '\n';
xbuf[totlen++] = ' ';
}
/* If a macro argument with newlines is used multiple times, /* If a macro argument with newlines is used multiple times,
then only expand the newlines once. This avoids creating output then only expand the newlines once. This avoids creating output
lines which don't correspond to any input line, which confuses lines which don't correspond to any input line, which confuses
......
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