Print this page
cpp: only consider macro calls unterminated if they ever began
We should only error about an unterminated macro parameter list if a
parameter list was begun.  If we never even seen the _first_
parenthesis, there is nothing to terminate.
Previously, we would set the parenthesis level to -1 when expecting
parameters (such that when we saw the opening paren it became the 0th
level), but when checking for unterminated expansion we would strictly
compare to 0, and thus flag a macro which needed parameters but lacked
them as having an unterminated parameter list.

Split Close
Expand all
Collapse all
          --- old/cpp/cpp.c
          +++ new/cpp/cpp.c
↓ open down ↓ 390 lines elided ↑ open up ↑
 391  391                          if (fretop<MAXFRE) bufstack[fretop++]=instack[mactop];
 392  392                          return(p);
 393  393                  } else {/* get more text from file(s) */
 394  394                          maclvl=0;
 395  395                          if (0<(ninbuf=read(fin,pbuf,BUFFERSIZ))) {
 396  396                                  pend=pbuf+ninbuf; *pend='\0';
 397  397                                  return(p);
 398  398                          }
 399  399                          /* end of #include file */
 400  400                          if (ifno==0) {/* end of input */
 401      -                                if (plvl!=0) {
      401 +                                if (plvl > 0) {
 402  402                                          int n=plvl,tlin=lineno[ifno];
 403  403                                          char *tfil=fnames[ifno];
 404  404                                          lineno[ifno]=maclin;
 405  405                                          fnames[ifno]=macfil;
 406  406                                          pperror("%s: unterminated macro call",
 407  407                                              macnam);
 408  408                                          lineno[ifno]=tlin; fnames[ifno]=tfil;
 409  409                                          np=p;
 410  410                                          /*
 411  411                                           * shut off unterminated quoted string
↓ open down ↓ 745 lines elided ↑ open up ↑
1157 1157          return(np);
1158 1158  }
1159 1159  
1160 1160  /*
1161 1161   * When a macro substitution must happen, arrange the input stack based on the
1162 1162   * macro definition and any parameters such that the expanded macro is what is
1163 1163   * next read by the preprocessor as if it were input
1164 1164   */
1165 1165  static char *
1166 1166  subst(p,sp) register char *p; struct symtab *sp; {
1167      -        static char match[]="%s: argument mismatch";
1168 1167          register char *ca,*vp; int params;
1169 1168          char *actual[MAXFRM]; /* actual[n] is text of nth actual */
1170 1169          char acttxt[BUFFERSIZ]; /* space for actuals */
1171 1170          /* State while pasting, TRAIL is trailing space, INTRA is in the body */
1172 1171          enum { TRAIL, INTRA } state = TRAIL;
1173 1172          int pasted = 0;         /* # of character pasted */
1174 1173  
1175 1174          if (0==(vp=sp->value)) return(p);
1176 1175          if ((p-macforw)<=macdam) {
1177 1176                  if (++maclvl>symsiz && !rflag) {
↓ open down ↓ 66 lines elided ↑ open up ↑
1244 1243                                                  if (*inp == '\n' &&
1245 1244                                                      inp[-1] != '\\')
1246 1245                                                          *inp = ' ';
1247 1246                                                  *ca++= *inp++;
1248 1247                                          }
1249 1248                                          if (ca> &acttxt[BUFFERSIZ])
1250 1249                                                  pperror("%s: actuals too long",
1251 1250                                                      sp->name);
1252 1251                                  }
1253 1252                                  if (pa>= &actual[MAXFRM])
1254      -                                        ppwarn(match,sp->name);
     1253 +                                        ppwarn("%s: argument mismatch" ,
     1254 +                                            sp->name);
1255 1255                                  else
1256 1256                                          *pa++=ca;
1257 1257                          }
1258 1258                  }
1259 1259                  if (params!=0)
1260      -                        ppwarn(match,sp->name);
     1260 +                        ppwarn("%s: argument mismatch", sp->name);
1261 1261                  while (--params>=0)
1262 1262                          *pa++=""+1;     /* null string for missing actuals */
1263 1263                  --flslvl; fasscan();
1264 1264          }
1265 1265  
1266 1266          for (;;) {/* push definition onto front of input stack */
1267 1267                  /*
1268 1268                   * Loop until we hit the end of the macro, or a parameter
1269 1269                   * placement.  Note that we expand the macro into the input
1270 1270                   * backwards (so it replays forwards.)
↓ open down ↓ 301 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX