xref: /AOO41X/main/soltools/cpp/_cpp.c (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir #include <stdio.h>
2*cdf0e10cSrcweir #include <stdlib.h>
3*cdf0e10cSrcweir #include <string.h>
4*cdf0e10cSrcweir #include <time.h>
5*cdf0e10cSrcweir #include <stdarg.h>
6*cdf0e10cSrcweir #include "cpp.h"
7*cdf0e10cSrcweir 
8*cdf0e10cSrcweir #define	OUTS	16384
9*cdf0e10cSrcweir char outbuf[OUTS];
10*cdf0e10cSrcweir char *outptr = outbuf;
11*cdf0e10cSrcweir Source *cursource;
12*cdf0e10cSrcweir int nerrs;
13*cdf0e10cSrcweir struct token nltoken = {NL, 0, 0, 1, (uchar *) "\n", 0};
14*cdf0e10cSrcweir char *curtime;
15*cdf0e10cSrcweir int incdepth;
16*cdf0e10cSrcweir int ifdepth;
17*cdf0e10cSrcweir int ifsatisfied[NIF];
18*cdf0e10cSrcweir int skipping;
19*cdf0e10cSrcweir 
20*cdf0e10cSrcweir char rcsid[] = "$Version 1.2 $ $Revision: 1.5 $ $Date: 2006-06-20 05:05:46 $";
21*cdf0e10cSrcweir 
22*cdf0e10cSrcweir int
23*cdf0e10cSrcweir #ifdef _WIN32
24*cdf0e10cSrcweir __cdecl
25*cdf0e10cSrcweir #endif // _WIN32
26*cdf0e10cSrcweir 	main(int argc, char **argv)
27*cdf0e10cSrcweir {
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir 	Tokenrow tr;
30*cdf0e10cSrcweir 	time_t t;
31*cdf0e10cSrcweir 	char ebuf[BUFSIZ];
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir     setbuf(stderr, ebuf);
34*cdf0e10cSrcweir     t = time(NULL);
35*cdf0e10cSrcweir     curtime = ctime(&t);
36*cdf0e10cSrcweir     maketokenrow(3, &tr);
37*cdf0e10cSrcweir     expandlex();
38*cdf0e10cSrcweir     setup(argc, argv);
39*cdf0e10cSrcweir     fixlex();
40*cdf0e10cSrcweir     if (!Pflag)
41*cdf0e10cSrcweir         genline();
42*cdf0e10cSrcweir     process(&tr);
43*cdf0e10cSrcweir     flushout();
44*cdf0e10cSrcweir     fflush(stderr);
45*cdf0e10cSrcweir     exit(nerrs > 0);
46*cdf0e10cSrcweir }
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir void
49*cdf0e10cSrcweir     process(Tokenrow * trp)
50*cdf0e10cSrcweir {
51*cdf0e10cSrcweir     int anymacros = 0;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir     for (;;)
54*cdf0e10cSrcweir     {
55*cdf0e10cSrcweir         if (trp->tp >= trp->lp)
56*cdf0e10cSrcweir         {
57*cdf0e10cSrcweir             trp->tp = trp->lp = trp->bp;
58*cdf0e10cSrcweir             outptr = outbuf;
59*cdf0e10cSrcweir             anymacros |= gettokens(trp, 1);
60*cdf0e10cSrcweir             trp->tp = trp->bp;
61*cdf0e10cSrcweir         }
62*cdf0e10cSrcweir         if (trp->tp->type == END)
63*cdf0e10cSrcweir         {
64*cdf0e10cSrcweir             if (--incdepth >= 0)
65*cdf0e10cSrcweir             {
66*cdf0e10cSrcweir                 if (cursource->ifdepth)
67*cdf0e10cSrcweir                     error(ERROR,
68*cdf0e10cSrcweir                           "Unterminated conditional in #include");
69*cdf0e10cSrcweir                 unsetsource();
70*cdf0e10cSrcweir                 cursource->line += cursource->lineinc;
71*cdf0e10cSrcweir                 trp->tp = trp->lp;
72*cdf0e10cSrcweir                 if (!Pflag)
73*cdf0e10cSrcweir                     genline();
74*cdf0e10cSrcweir                 continue;
75*cdf0e10cSrcweir             }
76*cdf0e10cSrcweir             if (ifdepth)
77*cdf0e10cSrcweir                 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
78*cdf0e10cSrcweir             break;
79*cdf0e10cSrcweir         }
80*cdf0e10cSrcweir         if (trp->tp->type == SHARP)
81*cdf0e10cSrcweir         {
82*cdf0e10cSrcweir             trp->tp += 1;
83*cdf0e10cSrcweir             control(trp);
84*cdf0e10cSrcweir         }
85*cdf0e10cSrcweir         else
86*cdf0e10cSrcweir             if (!skipping && anymacros)
87*cdf0e10cSrcweir                 expandrow(trp, NULL);
88*cdf0e10cSrcweir         if (skipping)
89*cdf0e10cSrcweir             setempty(trp);
90*cdf0e10cSrcweir         puttokens(trp);
91*cdf0e10cSrcweir         anymacros = 0;
92*cdf0e10cSrcweir         cursource->line += cursource->lineinc;
93*cdf0e10cSrcweir         if (cursource->lineinc > 1)
94*cdf0e10cSrcweir         {
95*cdf0e10cSrcweir             if (!Pflag)
96*cdf0e10cSrcweir                 genline();
97*cdf0e10cSrcweir         }
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir void
102*cdf0e10cSrcweir     control(Tokenrow * trp)
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir     Nlist *np;
105*cdf0e10cSrcweir     Token *tp;
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir     tp = trp->tp;
108*cdf0e10cSrcweir     if (tp->type != NAME)
109*cdf0e10cSrcweir     {
110*cdf0e10cSrcweir         if (tp->type == NUMBER)
111*cdf0e10cSrcweir             goto kline;
112*cdf0e10cSrcweir         if (tp->type != NL)
113*cdf0e10cSrcweir             error(ERROR, "Unidentifiable control line");
114*cdf0e10cSrcweir         return;                         /* else empty line */
115*cdf0e10cSrcweir     }
116*cdf0e10cSrcweir     if ((np = lookup(tp, 0)) == NULL || ((np->flag & ISKW) == 0 && !skipping))
117*cdf0e10cSrcweir     {
118*cdf0e10cSrcweir         error(WARNING, "Unknown preprocessor control %t", tp);
119*cdf0e10cSrcweir         return;
120*cdf0e10cSrcweir     }
121*cdf0e10cSrcweir     if (skipping)
122*cdf0e10cSrcweir     {
123*cdf0e10cSrcweir         switch (np->val)
124*cdf0e10cSrcweir         {
125*cdf0e10cSrcweir             case KENDIF:
126*cdf0e10cSrcweir                 if (--ifdepth < skipping)
127*cdf0e10cSrcweir                     skipping = 0;
128*cdf0e10cSrcweir                 --cursource->ifdepth;
129*cdf0e10cSrcweir                 setempty(trp);
130*cdf0e10cSrcweir                 return;
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir             case KIFDEF:
133*cdf0e10cSrcweir             case KIFNDEF:
134*cdf0e10cSrcweir             case KIF:
135*cdf0e10cSrcweir                 if (++ifdepth >= NIF)
136*cdf0e10cSrcweir                     error(FATAL, "#if too deeply nested");
137*cdf0e10cSrcweir                 ++cursource->ifdepth;
138*cdf0e10cSrcweir                 return;
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir             case KELIF:
141*cdf0e10cSrcweir             case KELSE:
142*cdf0e10cSrcweir                 if (ifdepth <= skipping)
143*cdf0e10cSrcweir                     break;
144*cdf0e10cSrcweir                 return;
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir             default:
147*cdf0e10cSrcweir                 return;
148*cdf0e10cSrcweir         }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir     switch (np->val)
151*cdf0e10cSrcweir     {
152*cdf0e10cSrcweir         case KDEFINE:
153*cdf0e10cSrcweir             dodefine(trp);
154*cdf0e10cSrcweir             break;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir         case KUNDEF:
157*cdf0e10cSrcweir             tp += 1;
158*cdf0e10cSrcweir             if (tp->type != NAME || trp->lp - trp->bp != 4)
159*cdf0e10cSrcweir             {
160*cdf0e10cSrcweir                 error(ERROR, "Syntax error in #undef");
161*cdf0e10cSrcweir                 break;
162*cdf0e10cSrcweir             }
163*cdf0e10cSrcweir             if ((np = lookup(tp, 0)) != NULL)
164*cdf0e10cSrcweir 			{
165*cdf0e10cSrcweir                 np->flag &= ~ISDEFINED;
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 				if (Mflag)
168*cdf0e10cSrcweir 				{
169*cdf0e10cSrcweir 					if (np->ap)
170*cdf0e10cSrcweir 						error(INFO, "Macro deletion of %s(%r)", np->name, np->ap);
171*cdf0e10cSrcweir 					else
172*cdf0e10cSrcweir 						error(INFO, "Macro deletion of %s", np->name);
173*cdf0e10cSrcweir 				}
174*cdf0e10cSrcweir 			}
175*cdf0e10cSrcweir             break;
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir         case KPRAGMA:
178*cdf0e10cSrcweir         case KIDENT:
179*cdf0e10cSrcweir 			for (tp = trp->tp - 1; ((tp->type != NL) && (tp < trp->lp)); tp++)
180*cdf0e10cSrcweir 				tp->type = UNCLASS;
181*cdf0e10cSrcweir             return;
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir         case KIFDEF:
184*cdf0e10cSrcweir         case KIFNDEF:
185*cdf0e10cSrcweir         case KIF:
186*cdf0e10cSrcweir             if (++ifdepth >= NIF)
187*cdf0e10cSrcweir                 error(FATAL, "#if too deeply nested");
188*cdf0e10cSrcweir             ++cursource->ifdepth;
189*cdf0e10cSrcweir             ifsatisfied[ifdepth] = 0;
190*cdf0e10cSrcweir             if (eval(trp, np->val))
191*cdf0e10cSrcweir                 ifsatisfied[ifdepth] = 1;
192*cdf0e10cSrcweir             else
193*cdf0e10cSrcweir                 skipping = ifdepth;
194*cdf0e10cSrcweir             break;
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir         case KELIF:
197*cdf0e10cSrcweir             if (ifdepth == 0)
198*cdf0e10cSrcweir             {
199*cdf0e10cSrcweir                 error(ERROR, "#elif with no #if");
200*cdf0e10cSrcweir                 return;
201*cdf0e10cSrcweir             }
202*cdf0e10cSrcweir             if (ifsatisfied[ifdepth] == 2)
203*cdf0e10cSrcweir                 error(ERROR, "#elif after #else");
204*cdf0e10cSrcweir             if (eval(trp, np->val))
205*cdf0e10cSrcweir             {
206*cdf0e10cSrcweir                 if (ifsatisfied[ifdepth])
207*cdf0e10cSrcweir                     skipping = ifdepth;
208*cdf0e10cSrcweir                 else
209*cdf0e10cSrcweir                 {
210*cdf0e10cSrcweir                     skipping = 0;
211*cdf0e10cSrcweir                     ifsatisfied[ifdepth] = 1;
212*cdf0e10cSrcweir                 }
213*cdf0e10cSrcweir             }
214*cdf0e10cSrcweir             else
215*cdf0e10cSrcweir                 skipping = ifdepth;
216*cdf0e10cSrcweir             break;
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir         case KELSE:
219*cdf0e10cSrcweir             if (ifdepth == 0 || cursource->ifdepth == 0)
220*cdf0e10cSrcweir             {
221*cdf0e10cSrcweir                 error(ERROR, "#else with no #if");
222*cdf0e10cSrcweir                 return;
223*cdf0e10cSrcweir             }
224*cdf0e10cSrcweir             if (ifsatisfied[ifdepth] == 2)
225*cdf0e10cSrcweir                 error(ERROR, "#else after #else");
226*cdf0e10cSrcweir             if (trp->lp - trp->bp != 3)
227*cdf0e10cSrcweir                 error(ERROR, "Syntax error in #else");
228*cdf0e10cSrcweir             skipping = ifsatisfied[ifdepth] ? ifdepth : 0;
229*cdf0e10cSrcweir             ifsatisfied[ifdepth] = 2;
230*cdf0e10cSrcweir             break;
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir         case KENDIF:
233*cdf0e10cSrcweir             if (ifdepth == 0 || cursource->ifdepth == 0)
234*cdf0e10cSrcweir             {
235*cdf0e10cSrcweir                 error(ERROR, "#endif with no #if");
236*cdf0e10cSrcweir                 return;
237*cdf0e10cSrcweir             }
238*cdf0e10cSrcweir             --ifdepth;
239*cdf0e10cSrcweir             --cursource->ifdepth;
240*cdf0e10cSrcweir             if (trp->lp - trp->bp != 3)
241*cdf0e10cSrcweir                 error(WARNING, "Syntax error in #endif");
242*cdf0e10cSrcweir             break;
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir         case KERROR:
245*cdf0e10cSrcweir             trp->tp = tp + 1;
246*cdf0e10cSrcweir             error(WARNING, "#error directive: %r", trp);
247*cdf0e10cSrcweir             break;
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir         case KLINE:
250*cdf0e10cSrcweir             trp->tp = tp + 1;
251*cdf0e10cSrcweir             expandrow(trp, "<line>");
252*cdf0e10cSrcweir             tp = trp->bp + 2;
253*cdf0e10cSrcweir     kline:
254*cdf0e10cSrcweir             if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp
255*cdf0e10cSrcweir                 || (tp + 3 == trp->lp
256*cdf0e10cSrcweir                     && ((tp + 1)->type != STRING || *(tp + 1)->t == 'L')))
257*cdf0e10cSrcweir             {
258*cdf0e10cSrcweir                 error(ERROR, "Syntax error in #line");
259*cdf0e10cSrcweir                 return;
260*cdf0e10cSrcweir             }
261*cdf0e10cSrcweir             cursource->line = atol((char *) tp->t) - 1;
262*cdf0e10cSrcweir             if (cursource->line < 0 || cursource->line >= 32768)
263*cdf0e10cSrcweir                 error(WARNING, "#line specifies number out of range");
264*cdf0e10cSrcweir             tp = tp + 1;
265*cdf0e10cSrcweir             if (tp + 1 < trp->lp)
266*cdf0e10cSrcweir                 cursource->filename = (char *) newstring(tp->t + 1, tp->len - 2, 0);
267*cdf0e10cSrcweir             return;
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir         case KDEFINED:
270*cdf0e10cSrcweir             error(ERROR, "Bad syntax for control line");
271*cdf0e10cSrcweir             break;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 		case KIMPORT:
274*cdf0e10cSrcweir             doinclude(trp, -1, 1);
275*cdf0e10cSrcweir             trp->lp = trp->bp;
276*cdf0e10cSrcweir 			return;
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir         case KINCLUDE:
279*cdf0e10cSrcweir             doinclude(trp, -1, 0);
280*cdf0e10cSrcweir             trp->lp = trp->bp;
281*cdf0e10cSrcweir             return;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir         case KINCLUDENEXT:
284*cdf0e10cSrcweir             doinclude(trp, cursource->pathdepth, 0);
285*cdf0e10cSrcweir             trp->lp = trp->bp;
286*cdf0e10cSrcweir             return;
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir         case KEVAL:
289*cdf0e10cSrcweir             eval(trp, np->val);
290*cdf0e10cSrcweir             break;
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir         default:
293*cdf0e10cSrcweir             error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
294*cdf0e10cSrcweir             break;
295*cdf0e10cSrcweir     }
296*cdf0e10cSrcweir     setempty(trp);
297*cdf0e10cSrcweir     return;
298*cdf0e10cSrcweir }
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir void *
301*cdf0e10cSrcweir     domalloc(int size)
302*cdf0e10cSrcweir {
303*cdf0e10cSrcweir     void *p = malloc(size);
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir     if (p == NULL)
306*cdf0e10cSrcweir         error(FATAL, "Out of memory from malloc");
307*cdf0e10cSrcweir     return p;
308*cdf0e10cSrcweir }
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir void
311*cdf0e10cSrcweir     dofree(void *p)
312*cdf0e10cSrcweir {
313*cdf0e10cSrcweir     free(p);
314*cdf0e10cSrcweir }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir void
317*cdf0e10cSrcweir     error(enum errtype type, char *string,...)
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir     va_list ap;
320*cdf0e10cSrcweir     char c, *cp, *ep;
321*cdf0e10cSrcweir     Token *tp;
322*cdf0e10cSrcweir     Tokenrow *trp;
323*cdf0e10cSrcweir     Source *s;
324*cdf0e10cSrcweir     int i;
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir     fprintf(stderr, "cpp: ");
327*cdf0e10cSrcweir     for (s = cursource; s; s = s->next)
328*cdf0e10cSrcweir         if (*s->filename)
329*cdf0e10cSrcweir             fprintf(stderr, "%s:%d ", s->filename, s->line);
330*cdf0e10cSrcweir     va_start(ap, string);
331*cdf0e10cSrcweir     for (ep = string; *ep; ep++)
332*cdf0e10cSrcweir     {
333*cdf0e10cSrcweir         if (*ep == '%')
334*cdf0e10cSrcweir         {
335*cdf0e10cSrcweir             switch (*++ep)
336*cdf0e10cSrcweir             {
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir                 case 'c':
339*cdf0e10cSrcweir                     c = (char) va_arg(ap, int);
340*cdf0e10cSrcweir                     fprintf(stderr, "%c", c);
341*cdf0e10cSrcweir                     break;
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir 				case 's':
344*cdf0e10cSrcweir                     cp = va_arg(ap, char *);
345*cdf0e10cSrcweir                     fprintf(stderr, "%s", cp);
346*cdf0e10cSrcweir                     break;
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir                 case 'd':
349*cdf0e10cSrcweir                     i = va_arg(ap, int);
350*cdf0e10cSrcweir                     fprintf(stderr, "%d", i);
351*cdf0e10cSrcweir                     break;
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir                 case 't':
354*cdf0e10cSrcweir                     tp = va_arg(ap, Token *);
355*cdf0e10cSrcweir                     fprintf(stderr, "%.*s", (int)tp->len, tp->t);
356*cdf0e10cSrcweir                     break;
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir                 case 'r':
359*cdf0e10cSrcweir                     trp = va_arg(ap, Tokenrow *);
360*cdf0e10cSrcweir                     for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++)
361*cdf0e10cSrcweir                     {
362*cdf0e10cSrcweir                         if (tp > trp->tp && tp->wslen)
363*cdf0e10cSrcweir                             fputc(' ', stderr);
364*cdf0e10cSrcweir                         fprintf(stderr, "%.*s", (int)tp->len, tp->t);
365*cdf0e10cSrcweir                     }
366*cdf0e10cSrcweir                     break;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir                 default:
369*cdf0e10cSrcweir                     fputc(*ep, stderr);
370*cdf0e10cSrcweir                     break;
371*cdf0e10cSrcweir             }
372*cdf0e10cSrcweir         }
373*cdf0e10cSrcweir         else
374*cdf0e10cSrcweir             fputc(*ep, stderr);
375*cdf0e10cSrcweir     }
376*cdf0e10cSrcweir     va_end(ap);
377*cdf0e10cSrcweir     fputc('\n', stderr);
378*cdf0e10cSrcweir     if (type == FATAL)
379*cdf0e10cSrcweir         exit(1);
380*cdf0e10cSrcweir     if (type != WARNING)
381*cdf0e10cSrcweir         nerrs = 1;
382*cdf0e10cSrcweir     fflush(stderr);
383*cdf0e10cSrcweir }
384