ref: f826b55f340d6d1806060e40c898ec746a96da02
parent: a65f71ddd0bb0fae2868884002807ac166b32909
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Apr 5 02:35:59 EDT 2022
cc1: Don't use yytext to capture macro arguments Macro arguments can be used with the stringfier operator, and it means that we cannot altear the whitespacing between the tokens that are part of the argument. For that reason the argument must be taken directly from the input stream.
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -93,15 +93,8 @@
if (yytoken == EOFTOK)
error("unterminated argument list invoking macro \"%s\"",
mp->sym->name);
- if (yylen + 1 > mp->arglen)
- error("argument overflow invoking macro \"%s\"",
- mp->sym->name);
if (yytoken == IDEN)
yylval.sym->flags |= SUSED;
- memcpy(mp->argp, yytext, yylen);
- mp->argp += yylen;
- mp->arglen -= yylen + 1;
- *mp->argp++ = ' ';
}
static void
@@ -122,14 +115,29 @@
static void
parameter(struct macroctx *mp)
{
+ int siz;
+ char *begin, *end;
+
+ begin = input->begin;
for (;;) {
nextcpp(mp);
switch (yytoken) {
case ')':
case ',':
- /* remove " , " or " ) "*/
- mp->argp -= 3;
+ /* remove "," or ")"*/
+ end = input->begin - 1;
+ while (end > begin && isspace(end[-1]))
+ --end;
+
+ siz = end - begin;
+ if (siz+1 > mp->arglen) {
+ error("argument overflow invoking macro \"%s\"",
+ mp->sym->name);
+ }
+ memcpy(mp->argp, begin, siz);
+ mp->argp += siz;
*mp->argp++ = '\0';
+ mp->arglen -= siz + 1;
return;
case '(':
paren(mp);
--- a/tests/cc/execute/scc-tests.lst
+++ b/tests/cc/execute/scc-tests.lst
@@ -116,7 +116,7 @@
0123-doubleconst.c [TODO]
0124-enumstruct.c
0125-fundcl.c
-0126-macropar.c [TODO]
+0126-macropar.c
0127-doublecte.c [TODO]
0128-kr_names.c
0129-initi.c [TODO]
@@ -178,7 +178,7 @@
0185-esc_macro2.c
0186-dec_ary.c
0187-zero_struct.c
-0188-multi_string.c [TODO]
+0188-multi_string.c
0189-cpp.c [TODO]
0190-enum_ary.c
0191-ary_addr.c
@@ -191,7 +191,7 @@
0198-nullcpp.c
0199-voidpcast.c
0200-cpp.c [TODO]
-0201-cpp.c [TODO]
+0201-cpp.c
0202-variadic.c [TODO]
0203-comment.c
0204-cast.c