59 *
60 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR
65 * ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
69 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
70 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
71 * POSSIBILITY OF SUCH DAMAGE.
72 */
73 #include <stdio.h>
74 #include <unistd.h>
75 #include <stdlib.h>
76 #include <fcntl.h>
77 #include <string.h>
78 #include <stdarg.h>
79
80 #include "cpp.h"
81
82 #define SYMLEN 128
83 static int symlen = SYMLEN;
84
85
86 #define SALT '#'
87 #ifndef BUFSIZ
88 #define BUFSIZ 512
89 #endif
90
91 static char *pbeg;
92 static char *pbuf;
93 static char *pend;
94 char *outp,*inp;
95 char *newp;
96 static char cinit;
97
98 /* some code depends on whether characters are sign or zero extended */
619 while (isid(*p++));
620 if (eob(--p)) {refill(p); p=inp+1; continue;}
621 goto lokid;
622 endid:
623 if (eob(--p)) {refill(p); p=inp+1; continue;}
624 tmac2(p[-1],0,-1+(p-inp));
625 lokid:
626 slookup(inp,p,0); if (newp) {p=newp; goto again;}
627 else break;
628 nomac:
629 while (isid(*p++));
630 if (eob(--p)) {p=refill(p); goto nomac;}
631 else break;
632 } break;
633 } /* end of switch */
634
635 if (isslo) return(p);
636 } /* end of infinite loop */
637 }
638
639 char *
640 skipbl(p) register char *p; {/* get next non-blank token */
641 do {
642 outp=inp=p;
643 p=cotoken(p);
644 } while ((toktyp+COFF)[(int)*inp]==BLANK);
645 return(p);
646 }
647
648 static char *
649 unfill(p) register char *p; {
650 /*
651 * take <= BUFFERSIZ chars from right end of buffer and put them on instack .
652 * slide rest of buffer to the right, update pointers, return new p.
653 */
654 register char *np,*op; register int d;
655 if (mactop>=MAXFRE) {
656 pperror("%s: too much pushback",macnam);
657 p=inp=pend; dump(); /* begin flushing pushback */
658 while (mactop>inctop[ifno]) {p=refill(p); p=inp=pend; dump();}
1176 if (++maclvl>symsiz && !rflag) {
1177 pperror("%s: macro recursion",sp->name);
1178 return(p);
1179 }
1180 } else {
1181 maclvl=0; /* level decreased */
1182 }
1183 macforw=p; macdam=0; /* new target for decrease in level */
1184 macnam=sp->name;
1185 /* flush all buffered output prior to the expansion */
1186 dump();
1187 if (sp==ulnloc) {
1188 vp=acttxt; *vp++='\0';
1189 sprintf(vp,"%d",lineno[ifno]); while (*vp++);
1190 } else if (sp==uflloc) {
1191 vp=acttxt; *vp++='\0';
1192 sprintf(vp,"\"%s\"",fnames[ifno]); while (*vp++);
1193 }
1194 if (0!=(params= *--vp&0xFF)) {/* definition calls for params */
1195 register char **pa;
1196 ca=acttxt; pa=actual;
1197 if (params==0xFF)
1198 params=1; /* #define foo() ... */
1199 sloscan();
1200 ++flslvl; /* no expansion during search for actuals */
1201 plvl= -1;
1202 do p=skipbl(p); while (*inp=='\n'); /* skip \n too */
1203 if (*inp=='(') {
1204 maclin=lineno[ifno]; macfil=fnames[ifno];
1205 for (plvl=1; plvl!=0; ) {
1206 *ca++='\0';
1207 for (;;) {
1208 outp=inp=p; p=cotoken(p);
1209 if (*inp=='(') ++plvl;
1210 if (*inp==')' && --plvl==0) {
1211 --params;
1212 break;
1213 }
1214 if (plvl==1 && *inp==',') {
1215 --params;
1216 break;
1217 }
1218 while (inp<p) {
1219 /*
1220 * Sun cpp compatibility.
1221 * Needed for kernel assembler
1222 * preprocessing.
1238 * escaped newlines, the \ is
1239 * removed, and the newline
1240 * otherwise treated
1241 * identically to in #1.
1242 */
1243 if (*inp == '\n' &&
1244 inp[-1] != '\\')
1245 *inp = ' ';
1246 *ca++= *inp++;
1247 }
1248 if (ca> &acttxt[BUFFERSIZ])
1249 pperror("%s: actuals too long",
1250 sp->name);
1251 }
1252 if (pa>= &actual[MAXFRM])
1253 ppwarn("%s: argument mismatch" ,
1254 sp->name);
1255 else
1256 *pa++=ca;
1257 }
1258 }
1259 if (params!=0)
1260 ppwarn("%s: argument mismatch", sp->name);
1261 while (--params>=0)
1262 *pa++=""+1; /* null string for missing actuals */
1263 --flslvl; fasscan();
1264 }
1265
1266 for (;;) {/* push definition onto front of input stack */
1267 /*
1268 * Loop until we hit the end of the macro, or a parameter
1269 * placement. Note that we expand the macro into the input
1270 * backwards (so it replays forwards.)
1271 */
1272 while (!iswarn(*--vp)) {
1273 if (bob(p)) {outp=inp=p; p=unfill(p);}
1274
1275 /* Unless we are mid-paste, swallow all spaces */
1276 if (state == TRAIL) {
1277 while (isspace(*vp) && !iswarn(*vp))
|
59 *
60 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR
65 * ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
69 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
70 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
71 * POSSIBILITY OF SUCH DAMAGE.
72 */
73 #include <stdio.h>
74 #include <unistd.h>
75 #include <stdlib.h>
76 #include <fcntl.h>
77 #include <string.h>
78 #include <stdarg.h>
79 #include <ctype.h>
80
81 #include "cpp.h"
82
83 #define SYMLEN 128
84 static int symlen = SYMLEN;
85
86
87 #define SALT '#'
88 #ifndef BUFSIZ
89 #define BUFSIZ 512
90 #endif
91
92 static char *pbeg;
93 static char *pbuf;
94 static char *pend;
95 char *outp,*inp;
96 char *newp;
97 static char cinit;
98
99 /* some code depends on whether characters are sign or zero extended */
620 while (isid(*p++));
621 if (eob(--p)) {refill(p); p=inp+1; continue;}
622 goto lokid;
623 endid:
624 if (eob(--p)) {refill(p); p=inp+1; continue;}
625 tmac2(p[-1],0,-1+(p-inp));
626 lokid:
627 slookup(inp,p,0); if (newp) {p=newp; goto again;}
628 else break;
629 nomac:
630 while (isid(*p++));
631 if (eob(--p)) {p=refill(p); goto nomac;}
632 else break;
633 } break;
634 } /* end of switch */
635
636 if (isslo) return(p);
637 } /* end of infinite loop */
638 }
639
640 /*
641 * XXX: This unconditionally consumes one token (presuming it's blank? that we
642 * already consumed it?). That's pretty terrible, but it's also very fragile,
643 * and I don't want to change it.
644 */
645 char *
646 skipbl(p) register char *p; {/* get next non-blank token */
647 do {
648 outp=inp=p;
649 p=cotoken(p);
650 } while ((toktyp+COFF)[(int)*inp]==BLANK);
651 return(p);
652 }
653
654 static char *
655 unfill(p) register char *p; {
656 /*
657 * take <= BUFFERSIZ chars from right end of buffer and put them on instack .
658 * slide rest of buffer to the right, update pointers, return new p.
659 */
660 register char *np,*op; register int d;
661 if (mactop>=MAXFRE) {
662 pperror("%s: too much pushback",macnam);
663 p=inp=pend; dump(); /* begin flushing pushback */
664 while (mactop>inctop[ifno]) {p=refill(p); p=inp=pend; dump();}
1182 if (++maclvl>symsiz && !rflag) {
1183 pperror("%s: macro recursion",sp->name);
1184 return(p);
1185 }
1186 } else {
1187 maclvl=0; /* level decreased */
1188 }
1189 macforw=p; macdam=0; /* new target for decrease in level */
1190 macnam=sp->name;
1191 /* flush all buffered output prior to the expansion */
1192 dump();
1193 if (sp==ulnloc) {
1194 vp=acttxt; *vp++='\0';
1195 sprintf(vp,"%d",lineno[ifno]); while (*vp++);
1196 } else if (sp==uflloc) {
1197 vp=acttxt; *vp++='\0';
1198 sprintf(vp,"\"%s\"",fnames[ifno]); while (*vp++);
1199 }
1200 if (0!=(params= *--vp&0xFF)) {/* definition calls for params */
1201 register char **pa;
1202 char *savp, *savinp, *savoutp;
1203 ca=acttxt; pa=actual;
1204 if (params==0xFF)
1205 params=1; /* #define foo() ... */
1206 sloscan();
1207 ++flslvl; /* no expansion during search for actuals */
1208 plvl= -1;
1209 /*
1210 * Skip any blanks (including \n), until we hit the macro
1211 * arguments.
1212 *
1213 * save our state so we can roll back if none are called.
1214 */
1215 savp = p;
1216 savinp = inp;
1217 savoutp = outp;
1218 do {
1219 p=skipbl(p);
1220 } while (*inp=='\n'); /* skip \n too */
1221
1222 if (*inp=='(') {
1223 maclin=lineno[ifno]; macfil=fnames[ifno];
1224 for (plvl=1; plvl!=0; ) {
1225 *ca++='\0';
1226 for (;;) {
1227 outp=inp=p; p=cotoken(p);
1228 if (*inp=='(') ++plvl;
1229 if (*inp==')' && --plvl==0) {
1230 --params;
1231 break;
1232 }
1233 if (plvl==1 && *inp==',') {
1234 --params;
1235 break;
1236 }
1237 while (inp<p) {
1238 /*
1239 * Sun cpp compatibility.
1240 * Needed for kernel assembler
1241 * preprocessing.
1257 * escaped newlines, the \ is
1258 * removed, and the newline
1259 * otherwise treated
1260 * identically to in #1.
1261 */
1262 if (*inp == '\n' &&
1263 inp[-1] != '\\')
1264 *inp = ' ';
1265 *ca++= *inp++;
1266 }
1267 if (ca> &acttxt[BUFFERSIZ])
1268 pperror("%s: actuals too long",
1269 sp->name);
1270 }
1271 if (pa>= &actual[MAXFRM])
1272 ppwarn("%s: argument mismatch" ,
1273 sp->name);
1274 else
1275 *pa++=ca;
1276 }
1277 } else {
1278 /*
1279 * Didn't find any parameters, rollback our state so
1280 * we don't chew more output than necessary
1281 */
1282 p = savp;
1283 inp = savinp;
1284 outp = savoutp;
1285 }
1286 if (params!=0)
1287 ppwarn("%s: argument mismatch", sp->name);
1288 while (--params>=0)
1289 *pa++=""+1; /* null string for missing actuals */
1290 --flslvl; fasscan();
1291 }
1292
1293 for (;;) {/* push definition onto front of input stack */
1294 /*
1295 * Loop until we hit the end of the macro, or a parameter
1296 * placement. Note that we expand the macro into the input
1297 * backwards (so it replays forwards.)
1298 */
1299 while (!iswarn(*--vp)) {
1300 if (bob(p)) {outp=inp=p; p=unfill(p);}
1301
1302 /* Unless we are mid-paste, swallow all spaces */
1303 if (state == TRAIL) {
1304 while (isspace(*vp) && !iswarn(*vp))
|