Annotation of OpenXM_contrib2/asir2000/parse/cpp.c, Revision 1.6
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.6 ! fujimoto 48: * $OpenXM: OpenXM_contrib2/asir2000/parse/cpp.c,v 1.5 2015/08/06 10:01:53 fujimoto Exp $
1.2 noro 49: */
1.1 noro 50: #include <stdio.h>
51: #include <ctype.h>
52: #include <setjmp.h>
53: jmp_buf cpp_env;
54:
55: #if 0
56: #include "accum.h"
57: #include "expr.h"
58: #include "if.h"
59: #include "io.h"
60: #include "is.h"
61: #include "malloc.h"
62: #include "stats.h"
63: #include "symtbl.h"
64: #include "unctrl.h"
65: #endif
66:
67:
68: #include "cpp.h"
69:
70: char *init_accum(void)
71: {
72: ACCUM *a;
73:
74: a = NEW(ACCUM);
75: check_malloc(a);
76: a->used = 0;
77: a->have = 8;
78: a->buf = malloc(8);
79: check_malloc(a->buf);
80: return((char *)a);
81: }
82:
83: void accum_char(char *A, char c)
84:
85: #define a ((ACCUM *)A)
86:
87: {
88: while (a->used >= a->have)
89: { a->buf = realloc(a->buf,a->have+=8);
90: check_malloc(a->buf);
91: }
92: a->buf[a->used++] = c;
93: }
94: #undef a
95:
96: char accum_regret(char *A)
97:
98: #define a ((ACCUM *)A)
99: {
100: if (a->used > 0)
101: { return(a->buf[--a->used]);
102: }
103: else
104: { return(0);
105: }
106: }
107: #undef a
108:
109: char *accum_result(char *A)
110:
111: #define a ((ACCUM *)A)
112: {
113: char *cp;
114:
115: cp = realloc(a->buf,a->used+1);
116: check_malloc(cp);
117: cp[a->used] = '\0';
118: OLD(a);
119: return(cp);
120: }
121: #undef a
122:
123: char *accum_sofar(char *A)
124:
125: #define a ((ACCUM *)A)
126: {
127: char *cp;
128:
129: cp = malloc(a->used+1);
130: check_malloc(cp);
131: Bcopy(a->buf,cp,a->used);
132: cp[a->used] = '\0';
133: return(cp);
134: }
135: #undef a
136:
137: char *accum_buf(char *A)
138:
139: #define a ((ACCUM *)A)
140: {
141: return(a->buf);
142: }
143: #undef a
144:
145: int accum_howfar(char *A)
146:
147: #define a ((ACCUM *)A)
148: {
149: return(a->used);
150: }
151: #undef a
152:
153: void do_at(void)
154: {
155: char *w;
156:
157: w = read_ctrl();
158: if (strcmp(w,"include") == 0)
159: { do_include(0);
160: }
161: else if (strcmp(w,"define") == 0)
162: { do_define(0,0);
163: }
164: else if (strcmp(w,"undef") == 0)
165: { do_undef(0);
166: }
167: else if (strcmp(w,"redefine") == 0)
168: { do_define(0,1);
169: }
170: else if (strcmp(w,"ifdef") == 0)
171: { do_ifdef(0);
172: }
173: else if (strcmp(w,"ifndef") == 0)
174: { do_ifndef(0);
175: }
176: else if (strcmp(w,"if") == 0)
177: { do_if(0);
178: }
179: else if (strcmp(w,"else") == 0)
180: { do_else(0);
181: }
182: else if (strcmp(w,"elif") == 0)
183: { do_elif(0);
184: }
185: else if (strcmp(w,"endif") == 0)
186: { do_endif(0);
187: }
188: else if (strcmp(w,"set") == 0)
189: { do_set();
190: }
191: else if (strcmp(w,"while") == 0)
192: { do_while();
193: }
194: else if (strcmp(w,"endwhile") == 0)
195: { do_endwhile();
196: }
197: else if (strcmp(w,"dump") == 0)
198: { do_dump();
199: }
200: else if (strcmp(w,"debug") == 0)
201: { do_debug();
202: }
203: else if (strcmp(w,"eval") == 0)
204: { do_eval();
205: }
206: else
207: { if (! in_false_if())
208: { err_head();
209: fprintf(stderr,"unknown control `%s'\n",w);
1.6 ! fujimoto 210: #if defined(__MINGW32__) || defined(__MINGW64__)
! 211: fflush(stderr);
! 212: #endif
1.1 noro 213: }
214: }
215: free(w);
216: }
217:
218: static char *temp;
219:
220: void autodef_file(char *f)
221: {
222: int i;
223:
224: i = strlen(f);
225: temp = malloc(i+2+1);
226: check_malloc(temp);
227: sprintf(temp,"\"%s\"",f);
228: undef("__FILE__");
229: define("__FILE__",-1,(unsigned char *)temp,0);
230: }
231:
232: void autodef_line(int l)
233: {
234: defd("__LINE__",l);
235: }
236:
237: char *copyofstr(char *str)
238: {
239: char *cp;
240:
241: if (str == 0)
242: { return(0);
243: }
244: cp = malloc(strlen(str)+1);
245: if (cp == 0)
246: { return(0);
247: }
248: strcpy(cp,str);
249: return(cp);
250: }
251:
252: char *copyofblk(char *blk, int len)
253: {
254: char *cp;
255:
256: if (blk == 0)
257: { return(0);
258: }
259: cp = malloc(len);
260: if (cp == 0)
261: { return(0);
262: }
263: Bcopy(blk,cp,len);
264: return(cp);
265: }
266:
267: /* these really don't beint here; they should be in their own file */
268:
269: #if 0
270: char *malloc(nb)
271: #undef malloc
272: int nb;
273: {
274: extern char *malloc();
275:
276: return(malloc(nb?nb:1));
277: }
278:
279: char *realloc(old,nb)
280: #undef realloc
281: char *old;
282: int nb;
283: {
284: extern char *realloc();
285:
286: return(realloc(old,(nb?nb:1)));
287: }
288: #endif
289:
290: static char buf[BUFSIZ];
291:
292: int debugging = 0;
293:
294: void do_debug(void)
295: {
296: char c;
297:
298: fflush(outfile);
299: c = getnonspace();
300: switch (c)
301: { case '1':
302: case 'y':
303: case 'Y':
304: debugging = 1;
305: break;
306: default:
307: debugging = 0;
308: break;
309: }
310: setbuf(outfile,debugging?NULL:buf);
311: }
312:
313: static int nargs;
314: static int nfound;
315: static char **argnames;
316:
317: void read_formals(void)
318: {
319: char *arg;
320: char c;
321:
322: nargs = 0;
323: argnames = (char **) malloc(1);
324: check_malloc(argnames);
325: while (1)
326: { arg = read_ident();
327: if (arg)
328: { argnames = (char **) realloc((char *)argnames,(nargs+1)*sizeof(char *));
329: check_malloc(argnames);
330: argnames[nargs] = arg;
331: nargs ++;
332: c = getnonspace();
333: if (c == ')')
334: { return;
335: }
336: else if (c != ',')
337: { err_head();
338: fprintf(stderr,"invalid macro parameter delimiter\n");
339: }
340: }
341: else
342: { c = Get();
343: if ((c == ')') && (nargs == 0))
344: { return;
345: }
346: else
347: { Push(c);
348: }
349: err_head();
350: fprintf(stderr,"missing/illegal macro parameter\n");
351: while (1)
352: { c = Get();
353: if (c == ')')
354: { return;
355: }
356: if (isbsymchar(c))
357: { Push(c);
358: break;
359: }
360: }
361: }
1.6 ! fujimoto 362: #if defined(__MINGW32__) || defined(__MINGW64__)
! 363: fflush(stderr);
! 364: #endif
1.1 noro 365: }
366: }
367:
368: void do_define(int sharp, int redef)
369: {
370: char *mac;
371: char c;
372: char *acc;
373: unsigned char *repl;
374: int quoted;
375: int incomment;
376: unsigned char *f;
377: unsigned char *t;
378: unsigned char *g;
379: int i;
380:
381: if (in_false_if())
382: { char e = '\0';
383: if (sharp)
384: { while (1)
385: { c = e;
386: e = Get();
387: if (e == '\n')
388: { if (c == '\\')
389: { maybe_print('\n');
390: }
391: else
392: { break;
393: }
394: }
395: }
396: }
397: else
398: { do
399: { c = e;
400: e = Get();
401: } while ((c != '@') || (e == '@'));
402: Push(e);
403: }
404: return;
405: }
406: mac = read_ident();
407: if (! mac)
408: { err_head();
409: fprintf(stderr,"missing/illegal macro name\n");
1.6 ! fujimoto 410: #if defined(__MINGW32__) || defined(__MINGW64__)
! 411: fflush(stderr);
! 412: #endif
1.1 noro 413: flush_sharp_line();
414: return;
415: }
416: c = Get();
417: if (c == '(')
418: { read_formals();
419: nfound = nargs;
420: if (nargs > 128)
421: { err_head();
422: fprintf(stderr,"too many macro formals, more than 128 ignored\n");
1.6 ! fujimoto 423: #if defined(__MINGW32__) || defined(__MINGW64__)
! 424: fflush(stderr);
! 425: #endif
1.1 noro 426: nargs = 128;
427: }
428: }
429: else
430: { argnames = 0;
431: nargs = -1;
432: nfound = -1;
433: if ((c != ' ') && (c != '\t'))
434: { Push(c);
435: }
436: }
437: quoted = 0;
438: incomment = 0;
439: acc = init_accum();
440: if (sharp)
441: { while (1)
442: { c = Get();
443: if (quoted && (c == '\n'))
444: { quoted = 0;
445: maybe_print('\n');
446: }
447: else if (quoted)
448: { accum_char(acc,'\\');
449: accum_char(acc,c);
450: quoted = 0;
451: }
452: else if (c == '/')
453: { char d = Get();
454: accum_char(acc,'/');
455: if (d == '*')
456: { accum_char(acc,'*');
457: incomment = 1;
458: }
459: else
460: { Push(d);
461: }
462: }
463: else if (incomment)
464: { accum_char(acc,c);
465: if (c == '*')
466: { char d = Get();
467: if (d == '/')
468: { accum_char(acc,'/');
469: incomment = 0;
470: }
471: else
472: { Push(d);
473: }
474: }
475: else if (c == '\n')
476: { maybe_print('\n');
477: }
478: }
479: else if (c == '\\')
480: { quoted = 1;
481: }
482: else if (c == '\n')
483: { break;
484: }
485: else
486: { accum_char(acc,c);
487: }
488: }
489: }
490: else
491: { while (1)
492: { c = Get();
493: if (quoted && (c == '@'))
494: { accum_char(acc,'@');
495: quoted = 0;
496: }
497: else if (quoted)
498: { Push(c);
499: break;
500: }
501: else if (c == '/')
502: { char d = Get();
503: accum_char(acc,'/');
504: if (d == '*')
505: { accum_char(acc,'*');
506: incomment = 1;
507: }
508: else
509: { Push(d);
510: }
511: }
512: else if (incomment)
513: { accum_char(acc,c);
514: if (c == '*')
515: { char d = Get();
516: if (d == '/')
517: { accum_char(acc,'/');
518: incomment = 0;
519: }
520: else
521: { Push(d);
522: }
523: }
524: else if (c == '\n')
525: { maybe_print('\n');
526: }
527: }
528: else if (c == '@')
529: { quoted = 1;
530: }
531: else
532: { if (c == '\n')
533: { maybe_print('\n');
534: }
535: accum_char(acc,c);
536: }
537: }
538: }
539: repl = (unsigned char *) accum_result(acc);
540: f = repl;
541: t = repl;
542: while (*f)
543: { if (isbsymchar(*f) && !incomment)
544: { for (g=f;issymchar(*g);g++) ;
545: c = *g;
546: *g = '\0';
547: for (i=0;i<nargs;i++)
548: { if (strcmp((char *)f,argnames[i]) == 0)
549: { break;
550: }
551: }
552: if (i < nargs)
553: { *t++ = 0x80 | i;
554: f = g;
555: }
556: else
557: { while (*t++ = *f++) ;
558: f --;
559: t --;
560: }
561: *g = c;
562: }
563: else if ((f[0] == '/') && (f[1] == '*'))
564: { f += 2;
565: *t++ = '/';
566: *t++ = '*';
567: incomment = 1;
568: }
569: else if (incomment && (f[0] == '*') && (f[1] == '/'))
570: { f += 2;
571: *t++ = '*';
572: *t++ = '/';
573: incomment = 0;
574: }
575: else
576: { *t++ = *f++;
577: }
578: }
579: *t++ = '\0';
580: repl = (unsigned char *) realloc((char *)repl,t-repl);
581: check_malloc(repl);
582: if (redef)
583: { undef(mac);
584: }
585: n_defines ++;
586: define(mac,nargs,repl,DEF_DEFINE);
587: if (argnames)
588: { for (i=0;i<nfound;i++)
589: { free(argnames[i]);
590: }
591: free((char *)argnames);
592: }
593: free(mac);
594: }
595:
596: void do_dump(void)
597: {
598: int i;
599: DEF *d;
600: extern char *cur_incldir;
601: extern char *incldir[];
602: extern int fstackdepth;
603:
604: fprintf(stderr,
605: "\n\n\tDump of definition table (%d entries in %d buckets):\n\n",
606: n_in_table,symtbl_size);
607: for (i=0;i<symtbl_size;i++)
608: { fprintf(stderr,"Bucket %d:\n",i);
609: for (d=symtbl[i];d;d=d->link)
610: { dump_single(d);
611: putc('\n',stderr);
612: }
613: }
614: fprintf(stderr,"\n\tInclude directory stack:\n\n");
615: for (i=0;i<fstackdepth;i++)
616: { fprintf(stderr,"\t\t%s\n",incldir[i]);
617: }
618: fprintf(stderr,"\t\t%s\n",cur_incldir);
1.6 ! fujimoto 619: #if defined(__MINGW32__) || defined(__MINGW64__)
! 620: fflush(stderr);
! 621: #endif
1.1 noro 622: }
623:
624: void dump_single(DEF *d)
625: {
626: unsigned char *cp;
627:
628: fprintf(stderr,"\t%s",d->name);
629: if (d->nargs == 0)
630: { fprintf(stderr,"()");
631: }
632: else if (d->nargs > 0)
633: { int i;
634: for (i=0;i<d->nargs;i++)
635: { fprintf(stderr,"%c#%d",i?',':'(',i);
636: }
637: putc(')',stderr);
638: }
639: putc(' ',stderr);
640: for (cp=d->repl;*cp;cp++)
641: { if (*cp & 0x80)
642: { fprintf(stderr,"#%d",(*cp)&~0x80);
643: }
644: else
645: { putc(*cp,stderr);
646: }
647: }
1.6 ! fujimoto 648: #if defined(__MINGW32__) || defined(__MINGW64__)
! 649: fflush(stderr);
! 650: #endif
1.1 noro 651: }
652:
653: void err_head(void)
654: {
655: fprintf(stderr,"\"%s\", line %d: ",curfile(),curline());
1.6 ! fujimoto 656: #if defined(__MINGW32__) || defined(__MINGW64__)
! 657: fflush(stderr);
! 658: #endif
1.1 noro 659: }
660:
661: void Check_malloc(char *ptr)
662: {
663: if (ptr == 0)
664: { fprintf(stderr,"out of memory!\n");
1.6 ! fujimoto 665: #if defined(__MINGW32__) || defined(__MINGW64__)
! 666: fflush(stderr);
! 667: #endif
1.1 noro 668: abort();
669: }
670: }
671:
672: void do_eval(void)
673: {
674: char c;
675: char temp[64];
676: int i;
677:
678: if (! in_false_if())
679: { c = getnonspace();
680: if (c != '(')
681: { err_head();
682: fprintf(stderr,"@eval must have ()s\n");
683: Push(c);
684: return;
685: }
686: sprintf(temp,"%d",eval_expr(0,1));
687: for (i=strlen(temp)-1;i>=0;i--)
688: { Push(temp[i]);
689: }
1.6 ! fujimoto 690: #if defined(__MINGW32__) || defined(__MINGW64__)
! 691: fflush(stderr);
! 692: #endif
1.1 noro 693: }
694: }
695:
696: #define DEBUG_EXPAND/**/
697:
698: #ifdef DEBUG_EXPAND
699: extern int debugging;
700: #endif
701:
702: extern int keep_comments;
703:
704: static char **actuals;
705: static int *actlens;
706:
707: void read_actuals(DEF *d)
708: {
709: int n;
710: int i;
711: int pc;
712: char c;
713: char last;
714: char quote;
715: int backslash;
716: int comment;
717: char *acc;
718:
719: n = d->nargs;
720: actuals = (char **) malloc(n*sizeof(char *));
721: check_malloc(actuals);
722: actlens = (int *) malloc(n*sizeof(int));
723: check_malloc(actlens);
724: c = getnonspace();
725: if (c != '(')
726: { err_head();
727: if (n == 0)
728: { fprintf(stderr,"missing () on %s\n",d->name);
729: }
730: else
731: { fprintf(stderr,"missing argument%s to %s\n",(n==1)?"":"s",d->name);
732: }
733: for (i=0;i<n;i++)
734: { actuals[i] = copyofstr("");
735: check_malloc(actuals[i]);
736: actlens[i] = 0;
737: }
738: Push(c);
739: return;
740: }
741: if (n == 0)
742: { c = getnonspace();
743: if (c != ')')
744: { err_head();
745: fprintf(stderr,"unwanted argument to %s\n",d->name);
746: Push(c);
747: }
748: return;
749: }
750: i = 0;
751: while (1)
752: { pc = 0;
753: quote = 0;
754: backslash = 0;
755: comment = 0;
756: c = 0;
757: acc = init_accum();
758: while (1)
759: { last = c;
760: c = Get();
761: accum_char(acc,c);
762: if (comment)
763: { if ((last == '*') && (c == '/'))
764: { comment = 0;
765: }
766: }
767: else
768: { if (backslash)
769: { backslash = 0;
770: }
771: else if (quote && (c == quote))
772: { quote = 0;
773: }
774: else if (c == '\\')
775: { backslash = 1;
776: }
777: else if (quote)
778: {
779: }
780: else if ((last == '/') && (c == '*'))
781: { comment = 1;
782: }
783: else if ((c == '\'') || (c == '"'))
784: { quote = c;
785: }
786: else if (c == '(')
787: { pc ++;
788: }
789: else if (c == ')')
790: { if (pc > 0)
791: { pc --;
792: }
793: else
794: { accum_regret(acc);
795: break;
796: }
797: }
798: else if ((c == ',') && (pc == 0))
799: { accum_regret(acc);
800: break;
801: }
802: }
803: }
804: if (i < n)
805: { actuals[i] = accum_result(acc);
806: actlens[i] = strlen(actuals[i]);
807: i ++;
808: }
809: else if (i == n)
810: { err_head();
811: fprintf(stderr,"too many arguments to %s\n",d->name);
812: i ++;
813: }
814: if (c == ')')
815: { break;
816: }
817: }
818: if (i < n)
819: { err_head();
820: fprintf(stderr,"too few arguments to %s\n",d->name);
821: for (;i<n;i++)
822: { actuals[i] = copyofstr("");
823: check_malloc(actuals[i]);
824: actlens[i] = 0;
825: }
826: }
1.6 ! fujimoto 827: #if defined(__MINGW32__) || defined(__MINGW64__)
! 828: fflush(stderr);
! 829: #endif
1.1 noro 830: }
831:
832: void expand_def(DEF *d)
833: {
834: unsigned char *cp;
835: char *dp;
836: char *ep;
837: char *result;
838: int ok;
839: int incomm;
840: char last;
841:
842: if (d->nargs >= 0)
843: { read_actuals(d);
844: }
845: #ifdef DEBUG_EXPAND
846: if (debugging)
847: { char *cp;
848: outputs("~EXPAND:");
849: outputs(d->name);
850: if (d->nargs == 0)
851: { outputs("()");
852: }
853: else if (d->nargs > 0)
854: { int i;
855: for (i=0;i<d->nargs;i++)
856: { outputc((char)(i?',':'('));
857: outputs(actuals[i]);
858: }
859: outputc(')');
860: }
861: outputs("-->");
862: for (cp=(char *)d->repl;*cp;cp++)
863: { outputs(unctrl(*cp));
864: }
865: outputc('~');
866: }
867: #endif
868: result = init_accum();
869: for (cp=d->repl;*cp;cp++)
870: { if (*cp & 0x80)
871: { char *dp;
872: int i;
873: i = *cp & ~0x80;
874: for (dp=actuals[i];*dp;dp++)
875: { accum_char(result,*dp);
876: }
877: }
878: else
879: { accum_char(result,*cp);
880: }
881: }
882: dp = accum_result(result);
883: #ifdef DEBUG_EXPAND
884: if (debugging)
885: { outputs("first:");
886: for (ep=dp;*ep;ep++)
887: { outputs(unctrl(*ep));
888: }
889: outputc('~');
890: }
891: #endif
892: result = init_accum();
893: last = '\0';
894: ok = 1;
895: incomm = 0;
896: for (ep=dp;*ep;ep++)
897: { if (!incomm && (last == '/') && (*ep == '*'))
898: { incomm = 1;
899: if (!keep_comments || (strncmp(ep,"**/",3) == 0))
900: { accum_regret(result);
901: ok = 0;
902: }
903: }
904: if (ok)
905: { accum_char(result,*ep);
906: }
907: if ((last == '*') && (*ep == '/'))
908: { incomm = 0;
909: ok = 1;
910: }
911: last = *ep;
912: }
913: free(dp);
914: result = accum_result(result);
915: #ifdef DEBUG_EXPAND
916: if (debugging)
917: { outputs("/**/strip:");
918: outputs(result);
919: outputc('~');
920: }
921: #endif
922: for (dp=result+strlen(result)-1;dp>=result;dp--)
923: { Push(*dp);
924: }
925: free(result);
926: if (d->nargs >= 0)
927: { int i;
928: for (i=0;i<d->nargs;i++)
929: { free(actuals[i]);
930: }
931: free((char *)actuals);
932: }
933: }
934:
935: #define DEBUG_EXPR/**/
936:
937: #define TWOCHAR(c1,c2) (((c1)<<8)|(c2))
938: #define LSH TWOCHAR('<','<')
939: #define RSH TWOCHAR('>','>')
940: #define LEQ TWOCHAR('<','=')
941: #define GEQ TWOCHAR('>','=')
942: #define EQL TWOCHAR('=','=')
943: #define NEQ TWOCHAR('!','=')
944: #define AND TWOCHAR('&','&')
945: #define OR TWOCHAR('|','|')
946:
947: #define ALLBINS \
948: BIN('*',*) \
949: BIN('/',/) \
950: BIN('%',%) \
951: BIN('+',+) \
952: BIN(LSH,<<) \
953: BIN(RSH,>>) \
954: BIN('<',<) \
955: BIN('>',>) \
956: BIN(LEQ,<=) \
957: BIN(GEQ,>=) \
958: BIN(EQL,==) \
959: BIN(NEQ,!=) \
960: BIN('&',&) \
961: BIN('^',^) \
962: BIN('|',|) \
963: BIN(AND,&&) \
964: BIN(OR ,||)
965:
966: char *Index(char *s, int c);
967:
968: static NODE *expr;
969: int expr_sharp;
970: #define sharp expr_sharp
971: static int complain;
972:
973: #ifdef DEBUG_EXPR
974: extern int debugging;
975: #endif
976:
977: void free_expr(NODE *n)
978: {
979: switch (n->op)
980: { case 0:
981: break;
982: case '-':
983: if (n->left)
984: { free_expr(n->left);
985: }
986: free_expr(n->right);
987: break;
988: case '!':
989: case '~':
990: free_expr(n->right);
991: break;
992: case 'd':
993: free(n->name);
994: break;
995: default:
996: free_expr(n->left);
997: free_expr(n->right);
998: break;
999: }
1000: OLD(n);
1001: }
1002:
1003: int exec_free(NODE *n)
1004: {
1005: int rv;
1006: int l;
1007: int r;
1008:
1009: switch (n->op)
1010: { case 0:
1011: rv = n->leaf;
1012: break;
1013: case '-':
1014: if (n->left)
1015: { rv = exec_free(n->left);
1016: }
1017: else
1018: { rv = 0;
1019: }
1020: rv -= exec_free(n->right);
1021: break;
1022: case '!':
1023: rv = ! exec_free(n->right);
1024: break;
1025: case '~':
1026: rv = ~ exec_free(n->right);
1027: break;
1028: case 'd':
1029: rv = !! find_def(n->name);
1030: free(n->name);
1031: break;
1032: #define BIN(key,op) case key:l=exec_free(n->left);r=exec_free(n->right);rv=l op r;break;
1033: ALLBINS
1034: #undef BIN
1035: }
1036: OLD(n);
1037: return(rv);
1038: }
1039:
1040: int exec_nofree(NODE *n)
1041: {
1042: int rv;
1043:
1044: switch (n->op)
1045: { case 0:
1046: rv = n->leaf;
1047: break;
1048: case '-':
1049: if (n->left)
1050: { rv = exec_nofree(n->left);
1051: }
1052: else
1053: { rv = 0;
1054: }
1055: rv -= exec_nofree(n->right);
1056: break;
1057: case '!':
1058: rv = ! exec_nofree(n->right);
1059: break;
1060: case '~':
1061: rv = ~ exec_nofree(n->right);
1062: break;
1063: case 'd':
1064: rv = !! find_def(n->name);
1065: free(n->name);
1066: break;
1067: #define BIN(key,op) case key:rv=(exec_nofree(n->left)op exec_nofree(n->right));break;
1068: ALLBINS
1069: #undef BIN
1070: }
1071: return(rv);
1072: }
1073:
1074: NODE *newnode(NODE *l, int c, NODE *r)
1075: {
1076: NODE *n;
1077:
1078: n = NEW(NODE);
1079: check_malloc(n);
1080: n->left = l;
1081: n->right = r;
1082: n->op = c;
1083: return(n);
1084: }
1085:
1086: NODE *newleaf(int v)
1087: {
1088: NODE *n;
1089:
1090: n = NEW(NODE);
1091: check_malloc(n);
1092: n->op = 0;
1093: n->left = 0;
1094: n->right = 0;
1095: n->leaf = v;
1096: return(n);
1097: }
1098:
1099: NODE *newname(char *name)
1100: {
1101: NODE *n;
1102:
1103: n = NEW(NODE);
1104: check_malloc(n);
1105: n->op = 'd';
1106: n->name = copyofstr(name);
1107: check_malloc(n->name);
1108: return(n);
1109: }
1110:
1111: int get_quote_char(void)
1112: {
1113: char c;
1114: char d;
1115:
1116: c = Get();
1117: if (c == '\'')
1118: { return(-1);
1119: }
1120: if (c == '\n')
1121: { err_head();
1122: fprintf(stderr,"newline in character constant\n");
1.6 ! fujimoto 1123: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1124: fflush(stderr);
! 1125: #endif
1.1 noro 1126: return(-1);
1127: }
1128: if (c != '\\')
1129: { return(0xff&(int)c);
1130: }
1131: c = Get();
1132: if ((c >= '0') && (c <= '7'))
1133: { d = c - '0';
1134: c = Get();
1135: if ((c >= '0') && (c <= '7'))
1136: { d = (d << 3) + c - '0';
1137: c = Get();
1138: if ((c >= '0') && (c <= '7'))
1139: { d = (d << 3) + c - '0';
1140: }
1141: else
1142: { Push(c);
1143: }
1144: }
1145: else
1146: { Push(c);
1147: }
1148: return(0xff&(int)d);
1149: }
1150: switch (c)
1151: { case 'n':
1152: return('\n');
1153: break;
1154: case 'r':
1155: return('\r');
1156: break;
1157: case 'e':
1158: return('\033');
1159: break;
1160: case 'f':
1161: return('\f');
1162: break;
1163: case 't':
1164: return('\t');
1165: break;
1166: case 'b':
1167: return('\b');
1168: break;
1169: case 'v':
1170: return('\v');
1171: break;
1172: default:
1173: return(0xff&(int)c);
1174: break;
1175: }
1176: }
1177:
1178: NODE *read_expr_11(void)
1179: {
1180: char c;
1181:
1182: #ifdef DEBUG_EXPR
1183: if (debugging)
1184: { outputs("~E11:");
1185: }
1186: #endif
1187: while (1)
1188: { c = getnhsexpand();
1189: if (c == '(')
1190: { NODE *n;
1191: NODE *read_expr_(void);
1192: #ifdef DEBUG_EXPR
1193: if (debugging)
1194: { outputs("()");
1195: }
1196: #endif
1197: n = read_expr_();
1198: c = getnhsexpand();
1199: if (c != ')')
1200: { err_head();
1201: fprintf(stderr,"expression syntax error -- missing ) supplied\n");
1.6 ! fujimoto 1202: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1203: fflush(stderr);
! 1204: #endif
1.1 noro 1205: Push(c);
1206: }
1207: #ifdef DEBUG_EXPR
1208: if (debugging)
1209: { outputs("~");
1210: }
1211: #endif
1212: return(n);
1213: }
1214: else if (isdigit(c))
1215: { int base;
1216: static char digits[] = "0123456789abcdefABCDEF";
1217: static char values[] =
1218: "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\12\13\14\15\16\17";
1219: char *d;
1220: int v;
1221: #ifdef DEBUG_EXPR
1222: if (debugging)
1223: { outputs("N");
1224: }
1225: #endif
1226: base = 10;
1227: if (c == '0')
1228: { base = 8;
1229: c = Get();
1230: if ((c == 'x') || (c == 'X'))
1231: { base = 16;
1232: c = Get();
1233: }
1234: }
1235: v = 0;
1236: while (1)
1237: { d = Index(digits,c);
1238: if (d == 0)
1239: { Push(c);
1240: #ifdef DEBUG_EXPR
1241: if (debugging)
1242: { outputd(v);
1243: outputs("~");
1244: }
1245: #endif
1246: return(newleaf(v));
1247: }
1248: else if (values[d-digits] >= base)
1249: { err_head();
1250: fprintf(stderr,"warning: illegal %sdigit `%c'\n",
1251: (base==16)?"hex ":(base==8)?"octal ":"",c);
1.6 ! fujimoto 1252: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1253: fflush(stderr);
! 1254: #endif
1.1 noro 1255: }
1256: v = (v * base) + values[d-digits];
1257: c = Get();
1258: }
1259: }
1260: else if (c == '\'')
1261: { int i;
1262: int j;
1263: int n;
1264: i = 0;
1265: n = 0;
1266: while (1)
1267: { j = get_quote_char();
1268: if (j < 0)
1269: { break;
1270: }
1271: i = (i << 8) | j;
1272: n ++;
1273: }
1274: if (n > 4)
1275: { err_head();
1276: fprintf(stderr,"warning: too many characters in character constant\n");
1.6 ! fujimoto 1277: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1278: fflush(stderr);
! 1279: #endif
1.1 noro 1280: }
1281: return(newleaf(i));
1282: }
1283: else if ((c == '\n') && !sharp)
1284: {
1285: }
1286: else
1287: { char *id;
1288: if (complain)
1289: { err_head();
1290: fprintf(stderr,"expression syntax error -- number expected\n");
1.6 ! fujimoto 1291: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1292: fflush(stderr);
! 1293: #endif
1.1 noro 1294: }
1295: if (isbsymchar(c))
1296: { Push(c);
1297: id = read_ident();
1298: }
1299: else
1300: { id = 0;
1301: }
1302: #ifdef DEBUG_EXPR
1303: if (debugging)
1304: { outputs("0(");
1305: outputc(c);
1306: outputs(":");
1307: outputs(id?id:"(none)");
1308: outputs(")~");
1309: }
1310: #endif
1311: if (id)
1312: { free(id);
1313: }
1314: return(newleaf(0));
1315: }
1316: }
1317: }
1318:
1319: NODE *read_expr_10(void)
1320: {
1321: char c;
1322: char *w;
1323: NODE *n;
1324:
1325: #ifdef DEBUG_EXPR
1326: if (debugging)
1327: { outputs("~E10:");
1328: }
1329: #endif
1330: while (1)
1331: { c = getnhsexpand();
1332: switch (c)
1333: { case '-':
1334: case '~':
1335: case '!':
1336: #ifdef DEBUG_EXPR
1337: if (debugging)
1338: { outputc(c);
1339: }
1340: #endif
1341: n = read_expr_10();
1342: #ifdef DEBUG_EXPR
1343: if (debugging)
1344: { outputs("~");
1345: }
1346: #endif
1347: return(newnode(0,c,n));
1348: break;
1349: case 'd':
1350: Push(c);
1351: input_mark();
1352: w = read_ident();
1353: if (strcmp(w,"defined") == 0)
1354: { c = getnonspace();
1355: if (c == '(')
1356: { char *id;
1357: id = read_ident();
1358: if (id)
1359: { c = getnonspace();
1360: if (c == ')')
1361: { input_unmark();
1362: #ifdef DEBUG_EXPR
1363: if (debugging)
1364: { outputs("ifdef");
1365: }
1366: #endif
1367: return(newname(id));
1368: }
1369: }
1370: }
1371: else if (isbsymchar(c))
1372: { char *id;
1373: Push(c);
1374: id = read_ident();
1375: if (id)
1376: { input_unmark();
1377: #ifdef DEBUG_EXPR
1378: if (debugging)
1379: { outputs("ifdef");
1380: }
1381: #endif
1382: return(newname(id));
1383: }
1384: }
1385: }
1386: input_recover();
1387: n = read_expr_11();
1388: #ifdef DEBUG_EXPR
1389: if (debugging)
1390: { outputs("~");
1391: }
1392: #endif
1393: return(n);
1394: break;
1395: default:
1396: Push(c);
1397: n = read_expr_11();
1398: #ifdef DEBUG_EXPR
1399: if (debugging)
1400: { outputs("~");
1401: }
1402: #endif
1403: return(n);
1404: break;
1405: }
1406: }
1407: }
1408:
1409: NODE *read_expr_9(void)
1410: {
1411: NODE *l;
1412: NODE *r;
1413: char c;
1414:
1415: #ifdef DEBUG_EXPR
1416: if (debugging)
1417: { outputs("~E9:");
1418: }
1419: #endif
1420: l = read_expr_10();
1421: while (1)
1422: { c = getnhsexpand();
1423: switch (c)
1424: { case '*':
1425: case '/':
1426: case '%':
1427: #ifdef DEBUG_EXPR
1428: if (debugging)
1429: { outputc(c);
1430: }
1431: #endif
1432: r = read_expr_10();
1433: l = newnode(l,c,r);
1434: break;
1435: default:
1436: #ifdef DEBUG_EXPR
1437: if (debugging)
1438: { outputs("~");
1439: }
1440: #endif
1441: Push(c);
1442: return(l);
1443: break;
1444: }
1445: }
1446: }
1447:
1448: NODE *read_expr_8(void)
1449: {
1450: NODE *l;
1451: NODE *r;
1452: char c;
1453:
1454: #ifdef DEBUG_EXPR
1455: if (debugging)
1456: { outputs("~E8:");
1457: }
1458: #endif
1459: l = read_expr_9();
1460: while (1)
1461: { c = getnhsexpand();
1462: switch (c)
1463: { case '+':
1464: case '-':
1465: #ifdef DEBUG_EXPR
1466: if (debugging)
1467: { outputc(c);
1468: }
1469: #endif
1470: r = read_expr_9();
1471: l = newnode(l,c,r);
1472: break;
1473: default:
1474: #ifdef DEBUG_EXPR
1475: if (debugging)
1476: { outputs("~");
1477: }
1478: #endif
1479: Push(c);
1480: return(l);
1481: break;
1482: }
1483: }
1484: }
1485:
1486: NODE *read_expr_7(void)
1487: {
1488: NODE *l;
1489: NODE *r;
1490: char c;
1491: char d;
1492:
1493: #ifdef DEBUG_EXPR
1494: if (debugging)
1495: { outputs("~E7:");
1496: }
1497: #endif
1498: l = read_expr_8();
1499: while (1)
1500: { c = getnhsexpand();
1501: switch (c)
1502: { case '<':
1503: case '>':
1504: d = Get();
1505: if (d == c)
1506: {
1507: #ifdef DEBUG_EXPR
1508: if (debugging)
1509: { outputc(c);
1510: outputc(d);
1511: }
1512: #endif
1513: r = read_expr_8();
1514: l = newnode(l,(c=='<')?LSH:RSH,r);
1515: break;
1516: }
1517: Push(d);
1518: /* fall through ... */
1519: default:
1520: #ifdef DEBUG_EXPR
1521: if (debugging)
1522: { outputs("~");
1523: }
1524: #endif
1525: Push(c);
1526: return(l);
1527: break;
1528: }
1529: }
1530: }
1531:
1532: NODE *read_expr_6(void)
1533: {
1534: NODE *l;
1535: NODE *r;
1536: char c;
1537: char d;
1538:
1539: #ifdef DEBUG_EXPR
1540: if (debugging)
1541: { outputs("~E6:");
1542: }
1543: #endif
1544: l = read_expr_7();
1545: while (1)
1546: { c = getnhsexpand();
1547: switch (c)
1548: { case '<':
1549: case '>':
1550: d = Get();
1551: if (d == '=')
1552: {
1553: #ifdef DEBUG_EXPR
1554: if (debugging)
1555: { outputc(c);
1556: outputc(d);
1557: }
1558: #endif
1559: r = read_expr_7();
1560: l = newnode(l,(c=='<')?LEQ:GEQ,r);
1561: }
1562: else
1563: {
1564: #ifdef DEBUG_EXPR
1565: if (debugging)
1566: { outputc(c);
1567: }
1568: #endif
1569: Push(d);
1570: r = read_expr_7();
1571: l = newnode(l,c,r);
1572: }
1573: break;
1574: default:
1575: #ifdef DEBUG_EXPR
1576: if (debugging)
1577: { outputs("~");
1578: }
1579: #endif
1580: Push(c);
1581: return(l);
1582: break;
1583: }
1584: }
1585: }
1586:
1587: NODE *read_expr_5(void)
1588: {
1589: NODE *l;
1590: NODE *r;
1591: char c;
1592: char d;
1593:
1594: #ifdef DEBUG_EXPR
1595: if (debugging)
1596: { outputs("~E5:");
1597: }
1598: #endif
1599: l = read_expr_6();
1600: while (1)
1601: { c = getnhsexpand();
1602: switch (c)
1603: { case '=':
1604: case '!':
1605: d = Get();
1606: if (d == '=')
1607: {
1608: #ifdef DEBUG_EXPR
1609: if (debugging)
1610: { outputc(c);
1611: outputc(d);
1612: }
1613: #endif
1614: r = read_expr_6();
1615: l = newnode(l,(c=='=')?EQL:NEQ,r);
1616: break;
1617: }
1618: Push(d);
1619: /* fall through ... */
1620: default:
1621: #ifdef DEBUG_EXPR
1622: if (debugging)
1623: { outputs("~");
1624: }
1625: #endif
1626: Push(c);
1627: return(l);
1628: break;
1629: }
1630: }
1631: }
1632:
1633: NODE *read_expr_4(void)
1634: {
1635: NODE *l;
1636: NODE *r;
1637: char c;
1638: char d;
1639:
1640: #ifdef DEBUG_EXPR
1641: if (debugging)
1642: { outputs("~E4:");
1643: }
1644: #endif
1645: l = read_expr_5();
1646: while (1)
1647: { c = getnhsexpand();
1648: switch (c)
1649: { case '&':
1650: d = Get();
1651: if (d != '&')
1652: {
1653: #ifdef DEBUG_EXPR
1654: if (debugging)
1655: { outputc(c);
1656: outputc(d);
1657: }
1658: #endif
1659: r = read_expr_5();
1660: l = newnode(l,c,r);
1661: break;
1662: }
1663: Push(d);
1664: /* fall through ... */
1665: default:
1666: #ifdef DEBUG_EXPR
1667: if (debugging)
1668: { outputs("~");
1669: }
1670: #endif
1671: Push(c);
1672: return(l);
1673: break;
1674: }
1675: }
1676: }
1677:
1678: NODE *read_expr_3(void)
1679: {
1680: NODE *l;
1681: NODE *r;
1682: char c;
1683:
1684: #ifdef DEBUG_EXPR
1685: if (debugging)
1686: { outputs("~E3:");
1687: }
1688: #endif
1689: l = read_expr_4();
1690: while (1)
1691: { c = getnhsexpand();
1692: switch (c)
1693: { case '^':
1694: #ifdef DEBUG_EXPR
1695: if (debugging)
1696: { outputc(c);
1697: }
1698: #endif
1699: r = read_expr_4();
1700: l = newnode(l,c,r);
1701: break;
1702: default:
1703: #ifdef DEBUG_EXPR
1704: if (debugging)
1705: { outputs("~");
1706: }
1707: #endif
1708: Push(c);
1709: return(l);
1710: break;
1711: }
1712: }
1713: }
1714:
1715: NODE *read_expr_2(void)
1716: {
1717: NODE *l;
1718: NODE *r;
1719: char c;
1720: char d;
1721:
1722: #ifdef DEBUG_EXPR
1723: if (debugging)
1724: { outputs("~E2:");
1725: }
1726: #endif
1727: l = read_expr_3();
1728: while (1)
1729: { c = getnhsexpand();
1730: switch (c)
1731: { case '|':
1732: d = Get();
1733: if (d != '|')
1734: { Push(d);
1735: #ifdef DEBUG_EXPR
1736: if (debugging)
1737: { outputc(c);
1738: }
1739: #endif
1740: r = read_expr_3();
1741: l = newnode(l,c,r);
1742: break;
1743: }
1744: Push(d);
1745: /* fall through ... */
1746: default:
1747: #ifdef DEBUG_EXPR
1748: if (debugging)
1749: { outputs("~");
1750: }
1751: #endif
1752: Push(c);
1753: return(l);
1754: break;
1755: }
1756: }
1757: }
1758:
1759: NODE *read_expr_1(void)
1760: {
1761: NODE *l;
1762: NODE *r;
1763: char c;
1764: char d;
1765:
1766: #ifdef DEBUG_EXPR
1767: if (debugging)
1768: { outputs("~E1:");
1769: }
1770: #endif
1771: l = read_expr_2();
1772: while (1)
1773: { c = getnhsexpand();
1774: switch (c)
1775: { case '&':
1776: d = Get();
1777: if (d == c)
1778: {
1779: #ifdef DEBUG_EXPR
1780: if (debugging)
1781: { outputc(c);
1782: outputc(d);
1783: }
1784: #endif
1785: r = read_expr_2();
1786: l = newnode(l,AND,r);
1787: break;
1788: }
1789: Push(d);
1790: /* fall through ... */
1791: default:
1792: #ifdef DEBUG_EXPR
1793: if (debugging)
1794: { outputs("~");
1795: }
1796: #endif
1797: Push(c);
1798: return(l);
1799: break;
1800: }
1801: }
1802: }
1803:
1804: NODE *read_expr_0(void)
1805: {
1806: NODE *l;
1807: NODE *r;
1808: char c;
1809: char d;
1810:
1811: #ifdef DEBUG_EXPR
1812: if (debugging)
1813: { outputs("~E0:");
1814: }
1815: #endif
1816: l = read_expr_1();
1817: while (1)
1818: { c = getnhsexpand();
1819: switch (c)
1820: { case '|':
1821: d = Get();
1822: if (d == c)
1823: {
1824: #ifdef DEBUG_EXPR
1825: if (debugging)
1826: { outputc(c);
1827: outputc(d);
1828: }
1829: #endif
1830: r = read_expr_1();
1831: l = newnode(l,OR,r);
1832: break;
1833: }
1834: Push(d);
1835: /* fall through ... */
1836: default:
1837: #ifdef DEBUG_EXPR
1838: if (debugging)
1839: { outputs("~");
1840: }
1841: #endif
1842: Push(c);
1843: return(l);
1844: break;
1845: }
1846: }
1847: }
1848:
1849: NODE *read_expr_(void)
1850: {
1851: NODE *l;
1852: NODE *r;
1853: char c;
1854:
1855: #ifdef DEBUG_EXPR
1856: if (debugging)
1857: { outputs("~E");
1858: }
1859: #endif
1860: l = read_expr_0();
1861: while (1)
1862: { c = getnhsexpand();
1863: switch (c)
1864: { case '\n':
1865: case ')':
1866: Push(c);
1867: return(l);
1868: break;
1869: case ',':
1870: r = read_expr_0();
1871: l = newnode(l,c,r);
1872: break;
1873: default:
1874: err_head();
1875: fprintf(stderr,"expression syntax error -- bad operator `%c'\n",c);
1.6 ! fujimoto 1876: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1877: fflush(stderr);
! 1878: #endif
1.1 noro 1879: return(l);
1880: break;
1881: }
1882: }
1883: }
1884:
1885: NODE *read_expr_p(void)
1886: {
1887: char c;
1888: NODE *rv;
1889:
1890: sharp = 0;
1891: complain = 1;
1892: c = getnonspace();
1893: if (c != '(')
1894: { Push(c);
1895: return(0);
1896: }
1897: rv = read_expr_();
1898: c = getnonspace();
1899: if (c != ')')
1900: { err_head();
1901: fprintf(stderr,"junk after expression\n");
1.6 ! fujimoto 1902: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1903: fflush(stderr);
! 1904: #endif
1.1 noro 1905: }
1906: return(rv);
1907: }
1908:
1909: int eval_expr(int Sharp, int Complain)
1910: {
1911: char c;
1912: char d;
1913: int rv;
1914:
1915: sharp = Sharp;
1916: complain = Complain;
1917: expr = read_expr_();
1918: if (sharp)
1919: { c = getnonhspace();
1920: d = '\n';
1921: }
1922: else
1923: { c = getnonspace();
1924: d = ')';
1925: }
1926: if (c != d)
1927: { if (complain)
1928: { err_head();
1929: fprintf(stderr,"expression syntax error -- junk after expression\n");
1.6 ! fujimoto 1930: #if defined(__MINGW32__) || defined(__MINGW64__)
! 1931: fflush(stderr);
! 1932: #endif
1.1 noro 1933: }
1934: while (Get() != d) ;
1935: }
1936: #ifdef DEBUG_EXPR
1937: if (debugging)
1938: { outputc('<');
1939: dump_expr(expr);
1940: outputc('=');
1941: rv = exec_free(expr);
1942: outputd(rv);
1943: outputc('>');
1944: }
1945: else
1946: { rv = exec_free(expr);
1947: }
1948: return(rv);
1949: #else
1950: return(exec_free(expr));
1951: #endif
1952: }
1953:
1954: #ifdef DEBUG_EXPR
1955: void dump_expr(NODE *n)
1956: {
1957: switch (n->op)
1958: { case 0:
1959: outputd(n->leaf);
1960: break;
1961: case '-':
1962: if (n->left)
1963: { dump_expr(n->left);
1964: }
1965: outputc('-');
1966: dump_expr(n->right);
1967: break;
1968: case '!':
1969: outputc('!');
1970: dump_expr(n->right);
1971: break;
1972: case '~':
1973: outputc('~');
1974: dump_expr(n->right);
1975: break;
1976: case 'd':
1977: outputs("defined(");
1978: outputs(n->name);
1979: outputc(')');
1980: break;
1981: #define BIN(key,op) case key:dump_expr(n->left);\
1982: putx(key);\
1983: dump_expr(n->right);\
1984: break;
1985: ALLBINS
1986: #undef BIN
1987: }
1988: }
1989:
1990: void putx(int i)
1991: {
1992: if (i > 0xff) outputc((char)(i>>8));
1993: outputc((char)(i&0xff));
1994: }
1995: #endif
1996:
1997: /*#define DEBUG_IF/**/
1998:
1999: #ifdef DEBUG_IF
2000: extern int debugging;
2001: #endif
2002:
2003: void do_if(int expr_sharp)
2004: {
2005: char c;
2006: char d;
2007:
2008: #ifdef DEBUG_IF
2009: if (debugging)
2010: { outputc('<');
2011: outputc(sharp?'#':'@');
2012: outputs("if: ");
2013: fflush(outfile);
2014: }
2015: #endif
2016: if (in_false_if())
2017: { n_skipped_ifs ++;
2018: #ifdef DEBUG_IF
2019: if (debugging)
2020: { outputs("in-false, skipped>");
2021: fflush(outfile);
2022: }
2023: #endif
2024: if (sharp)
2025: { d = '\0';
2026: do
2027: { c = d;
2028: d = Get();
2029: } while ((c == '\\') || (d != '\n'));
2030: }
2031: return;
2032: }
2033: if (! sharp)
2034: { c = getnonspace();
2035: if (c != '(')
2036: { err_head();
2037: fprintf(stderr,"@if must have ()s\n");
1.6 ! fujimoto 2038: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2039: fflush(stderr);
! 2040: #endif
1.1 noro 2041: Push(c);
2042: iffalse();
2043: #ifdef DEBUG_IF
2044: if (debugging)
2045: { outputc('>');
2046: fflush(outfile);
2047: }
2048: #endif
2049: return;
2050: }
2051: }
2052: if (eval_expr(sharp,0))
2053: { iftrue();
2054: }
2055: else
2056: { iffalse();
2057: }
2058: #ifdef DEBUG_IF
2059: if (debugging)
2060: { outputc('>');
2061: fflush(outfile);
2062: }
2063: #endif
2064: }
2065:
2066: void do_ifdef(int expr_sharp)
2067: {
2068: char *w;
2069:
2070: #ifdef DEBUG_IF
2071: if (debugging)
2072: { outputc('<');
2073: outputc(sharp?'#':'@');
2074: outputs("ifdef: ");
2075: fflush(outfile);
2076: }
2077: #endif
2078: if (in_false_if())
2079: { n_skipped_ifs ++;
2080: #ifdef DEBUG_IF
2081: if (debugging)
2082: { outputs("in-false, skipped>");
2083: fflush(outfile);
2084: }
2085: #endif
2086: }
2087: else
2088: { w = read_ident();
2089: if (! w)
2090: {
2091: #ifdef DEBUG_IF
2092: if (debugging)
2093: { outputs("no ident ");
2094: fflush(outfile);
2095: }
2096: #endif
2097: iffalse();
2098: }
2099: else
2100: {
2101: #ifdef DEBUG_IF
2102: if (debugging)
2103: { outputs(w);
2104: outputc(' ');
2105: fflush(outfile);
2106: }
2107: #endif
2108: if (find_def(w))
2109: { iftrue();
2110: }
2111: else
2112: { iffalse();
2113: }
2114: free(w);
2115: }
2116: #ifdef DEBUG_IF
2117: if (debugging)
2118: { outputc('>');
2119: fflush(outfile);
2120: }
2121: #endif
2122: }
2123: if (sharp)
2124: { flush_sharp_line();
2125: }
2126: }
2127:
2128: void do_ifndef(int expr_sharp)
2129: {
2130: char *w;
2131:
2132: #ifdef DEBUG_IF
2133: if (debugging)
2134: { outputc('<');
2135: outputc(sharp?'#':'@');
2136: outputs("ifndef: ");
2137: fflush(outfile);
2138: }
2139: #endif
2140: if (in_false_if())
2141: { n_skipped_ifs ++;
2142: #ifdef DEBUG_IF
2143: if (debugging)
2144: { outputs("in-false, skipped>");
2145: fflush(outfile);
2146: }
2147: #endif
2148: }
2149: else
2150: { w = read_ident();
2151: if (! w)
2152: {
2153: #ifdef DEBUG_IF
2154: if (debugging)
2155: { outputs("no ident ");
2156: fflush(outfile);
2157: }
2158: #endif
2159: iftrue();
2160: }
2161: else
2162: {
2163: #ifdef DEBUG_IF
2164: if (debugging)
2165: { outputs(w);
2166: outputc(' ');
2167: fflush(outfile);
2168: }
2169: #endif
2170: if (find_def(w))
2171: { iffalse();
2172: }
2173: else
2174: { iftrue();
2175: }
2176: free(w);
2177: }
2178: #ifdef DEBUG_IF
2179: if (debugging)
2180: { outputc('>');
2181: fflush(outfile);
2182: }
2183: #endif
2184: }
2185: if (sharp)
2186: { flush_sharp_line();
2187: }
2188: }
2189:
2190: void do_else(int expr_sharp)
2191: {
2192: #ifdef DEBUG_IF
2193: if (debugging)
2194: { outputc('<');
2195: outputc(sharp?'#':'@');
2196: outputs("else: ");
2197: fflush(outfile);
2198: }
2199: #endif
2200: if (n_skipped_ifs == 0)
2201: { if (ifstack)
2202: {
2203: #ifdef DEBUG_IF
2204: if (debugging)
2205: { outputs("top ");
2206: output_ifstate(ifstack->condstate);
2207: fflush(outfile);
2208: }
2209: #endif
2210: switch (ifstack->condstate)
2211: { case IFSTATE_TRUE:
2212: ifstack->condstate = IFSTATE_STAYFALSE;
2213: break;
2214: case IFSTATE_FALSE:
2215: ifstack->condstate = IFSTATE_TRUE;
2216: break;
2217: }
2218: #ifdef DEBUG_IF
2219: if (debugging)
2220: { outputs(" now ");
2221: output_ifstate(ifstack->condstate);
2222: outputc('>');
2223: fflush(outfile);
2224: }
2225: #endif
2226: }
2227: else
2228: {
2229: #ifdef DEBUG_IF
2230: if (debugging)
2231: { outputs(" no if>");
2232: fflush(outfile);
2233: }
2234: #endif
2235: err_head();
2236: fprintf(stderr,"if-less else\n");
1.6 ! fujimoto 2237: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2238: fflush(stderr);
! 2239: #endif
1.1 noro 2240: }
2241: }
2242: else
2243: {
2244: #ifdef DEBUG_IF
2245: if (debugging)
2246: { outputs("in-false, forgetting>");
2247: fflush(outfile);
2248: }
2249: #endif
2250: }
2251: if (sharp)
2252: { flush_sharp_line();
2253: }
2254: }
2255:
2256: #ifdef DEBUG_IF
2257: void output_ifstate(state)
2258: int state;
2259: {
2260: switch (state)
2261: { case IFSTATE_TRUE:
2262: outputs("TRUE");
2263: break;
2264: case IFSTATE_FALSE:
2265: outputs("FALSE");
2266: break;
2267: case IFSTATE_STAYFALSE:
2268: outputs("STAYFALSE");
2269: break;
2270: default:
2271: outputs("BAD");
2272: outputd(state);
2273: break;
2274: }
2275: }
2276: #endif
2277:
2278: void do_elif(int expr_sharp)
2279: {
2280: char c;
2281: char d;
2282: int e;
2283:
2284: #ifdef DEBUG_IF
2285: if (debugging)
2286: { outputc('<');
2287: outputc(sharp?'#':'@');
2288: outputs("elif: ");
2289: fflush(outfile);
2290: }
2291: #endif
2292: if (ifstack == 0)
2293: { err_head();
2294: fprintf(stderr,"if-less elif converted to normal if\n");
1.6 ! fujimoto 2295: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2296: fflush(stderr);
! 2297: #endif
1.1 noro 2298: iffalse();
2299: }
2300: if (n_skipped_ifs > 0)
2301: {
2302: #ifdef DEBUG_IF
2303: if (debugging)
2304: { outputs("being skipped, ignoring>");
2305: fflush(outfile);
2306: }
2307: #endif
2308: if (sharp)
2309: { d = '\0';
2310: do
2311: { c = d;
2312: d = Get();
2313: } while ((c == '\\') || (d != '\n'));
2314: }
2315: return;
2316: }
2317: if (! sharp)
2318: { c = getnonspace();
2319: if (c != '(')
2320: { err_head();
2321: fprintf(stderr,"@elif must have ()s\n");
1.6 ! fujimoto 2322: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2323: fflush(stderr);
! 2324: #endif
1.1 noro 2325: Push(c);
2326: ifstack->condstate = IFSTATE_STAYFALSE;
2327: #ifdef DEBUG_IF
2328: if (debugging)
2329: { outputs("forcing STAYFALSE>");
2330: fflush(outfile);
2331: }
2332: #endif
2333: return;
2334: }
2335: }
2336: e = eval_expr(sharp,0);
2337: #ifdef DEBUG_IF
2338: if (debugging)
2339: { outputs("expr ");
2340: outputd(e);
2341: outputc(' ');
2342: fflush(outfile);
2343: }
2344: #endif
2345: #ifdef DEBUG_IF
2346: if (debugging)
2347: { outputs(" top ");
2348: output_ifstate(ifstack->condstate);
2349: fflush(outfile);
2350: }
2351: #endif
2352: switch (ifstack->condstate)
2353: { case IFSTATE_TRUE:
2354: ifstack->condstate = IFSTATE_STAYFALSE;
2355: break;
2356: case IFSTATE_FALSE:
2357: if (e)
2358: { ifstack->condstate = IFSTATE_TRUE;
2359: }
2360: break;
2361: }
2362: #ifdef DEBUG_IF
2363: if (debugging)
2364: { outputs(" now ");
2365: output_ifstate(ifstack->condstate);
2366: outputc('>');
2367: fflush(outfile);
2368: }
2369: #endif
2370: }
2371:
2372: void do_endif(int expr_sharp)
2373: {
2374: IF *i;
2375:
2376: #ifdef DEBUG_IF
2377: if (debugging)
2378: { outputc('<');
2379: outputc(sharp?'#':'@');
2380: outputs("endif: ");
2381: fflush(outfile);
2382: }
2383: #endif
2384: if (n_skipped_ifs > 0)
2385: { n_skipped_ifs --;
2386: #ifdef DEBUG_IF
2387: if (debugging)
2388: { outputs("n_skipped -->");
2389: fflush(outfile);
2390: }
2391: #endif
2392: }
2393: else if (ifstack)
2394: { i = ifstack->next;
2395: OLD(ifstack);
2396: ifstack = i;
2397: #ifdef DEBUG_IF
2398: if (debugging)
2399: { outputs("popping stack>");
2400: fflush(outfile);
2401: }
2402: #endif
2403: }
2404: else
2405: { err_head();
2406: fprintf(stderr,"if-less endif\n");
1.6 ! fujimoto 2407: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2408: fflush(stderr);
! 2409: #endif
1.1 noro 2410: #ifdef DEBUG_IF
2411: if (debugging)
2412: { outputc('>');
2413: fflush(outfile);
2414: }
2415: #endif
2416: }
2417: if (sharp)
2418: { flush_sharp_line();
2419: }
2420: }
2421:
2422: void iftrue(void)
2423: {
2424: IF *i;
2425:
2426: i = NEW(IF);
2427: check_malloc(i);
2428: i->next = ifstack;
2429: ifstack = i;
2430: i->condstate = IFSTATE_TRUE;
2431: #ifdef DEBUG_IF
2432: if (debugging)
2433: { outputs("IFTRUE");
2434: fflush(outfile);
2435: }
2436: #endif
2437: }
2438:
2439: void iffalse(void)
2440: {
2441: IF *i;
2442:
2443: i = NEW(IF);
2444: check_malloc(i);
2445: i->next = ifstack;
2446: ifstack = i;
2447: i->condstate = IFSTATE_FALSE;
2448: #ifdef DEBUG_IF
2449: if (debugging)
2450: { outputs("IFFALSE");
2451: fflush(outfile);
2452: }
2453: #endif
2454: }
2455:
2456: int in_false_if(void)
2457: {
2458: return(ifstack && (ifstack->condstate != IFSTATE_TRUE));
2459: }
2460:
2461: void maybe_print(char c)
2462: {
2463: extern int incldep;
2464:
2465: if (incldep)
2466: { return;
2467: }
2468: if ((c == '\n') || !in_false_if())
2469: { outputc(c);
2470: }
2471: }
2472:
2473: char *Rindex(char *s, int c);
2474:
2475: int nIfiles;
2476: char **Ifiles;
2477:
2478: void init_include(void)
2479: {
2480: nIfiles = 0;
2481: Ifiles = (char **) malloc(1);
2482: check_malloc(Ifiles);
2483: }
2484:
2485: void Ifile(char *f)
2486: {
2487: Ifiles = (char **) realloc((char *)Ifiles,(nIfiles+1)*sizeof(char *));
2488: check_malloc(Ifiles);
2489: Ifiles[nIfiles] = copyofstr(f);
2490: check_malloc(Ifiles[nIfiles]);
2491: nIfiles ++;
2492: }
2493:
2494: void do_include(int expr_sharp)
2495: {
2496: char c;
2497: char *acc;
2498:
2499: if (in_false_if())
2500: { if (sharp)
2501: { flush_sharp_line();
2502: }
2503: return;
2504: }
2505: while (1)
2506: { c = getnonspace();
2507: if (isbsymchar(c))
2508: { char *cp;
2509: DEF *d;
2510: cp = init_accum();
2511: while (issymchar(c))
2512: { accum_char(cp,c);
2513: c = Get();
2514: }
2515: Push(c);
2516: cp = accum_result(cp);
2517: d = find_def(cp);
2518: if (d)
2519: { expand_def(d);
2520: n_hits ++;
2521: }
2522: else
2523: { char *dp;
2524: for (dp=cp+strlen(cp);dp>cp;dp--) Push(*dp);
2525: n_misses ++;
2526: }
2527: }
2528: else
2529: { break;
2530: }
2531: }
2532: acc = init_accum();
2533: if (c == '"')
2534: { while (1)
2535: { c = Get();
2536: if (c == '\n')
2537: { Push('\n');
2538: c = '"';
2539: err_head();
2540: fprintf(stderr,"warning: unterminated %cinclude filename\n",
2541: sharp?'#':'@');
1.6 ! fujimoto 2542: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2543: fflush(stderr);
! 2544: #endif
1.1 noro 2545: }
2546: if (c == '"')
2547: { break;
2548: }
2549: accum_char(acc,c);
2550: }
2551: if (sharp)
2552: { flush_sharp_line();
2553: }
2554: read_include_file(accum_result(acc),1,sharp);
2555: }
2556: else if (c == '<')
2557: { while (1)
2558: { c = Get();
2559: if (c == '\n')
2560: { Push('\n');
2561: c = '>';
2562: err_head();
2563: fprintf(stderr,"warning: unterminated %cinclude filename\n",
2564: sharp?'#':'@');
1.6 ! fujimoto 2565: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2566: fflush(stderr);
! 2567: #endif
1.1 noro 2568: }
2569: if (c == '>')
2570: { break;
2571: }
2572: accum_char(acc,c);
2573: }
2574: if (sharp)
2575: { flush_sharp_line();
2576: }
2577: read_include_file(accum_result(acc),0,sharp);
2578: }
2579: else
2580: { free(accum_result(acc));
2581: err_head();
2582: fprintf(stderr,"illegal %cinclude filename delimiter\n",sharp?'#':'@');
1.6 ! fujimoto 2583: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2584: fflush(stderr);
! 2585: #endif
1.1 noro 2586: }
2587: }
2588:
2589: #if defined(SYSV)
2590: #else
2591: #if defined(DELIM)
2592: #undef DELIM
2593: #endif
2594: #define DELIM '/'
2595: #endif
2596:
1.5 fujimoto 2597: #if defined(VISUAL) || defined(__MINGW32__) || defined(__MINGW64__)
1.1 noro 2598: #if defined(DELIM)
2599: #undef DELIM
2600: #endif
2601: #define DELIM '\\'
2602: #endif
2603:
2604: void read_include_file(char *name, int dohere, int expr_sharp)
2605: {
2606: FILE *f;
2607: char *n;
2608: char temp[1024];
2609: char *cp;
2610: extern int incldep;
2611: extern char *incldep_o;
2612:
2613: f = NULL;
2614: if (dohere)
2615: { if ((strcmp(curdir(),".") != 0) && (name[0] != DELIM))
2616: { sprintf(temp,"%s%c%s",curdir(),DELIM,name);
2617: n = temp;
2618: }
2619: else
2620: { n = name;
2621: }
2622: f = fopen(n,"r");
2623: }
2624: if (f == NULL)
2625: { if (name[0] == DELIM)
2626: { f = fopen(name,"r");
2627: n = name;
2628: }
2629: else
2630: { int i;
2631: n = temp;
2632: for (i=0;i<nIfiles;i++)
2633: { sprintf(temp,"%s%c%s",Ifiles[i],DELIM,name);
2634: f = fopen(temp,"r");
2635: if (f != NULL)
2636: { break;
2637: }
2638: }
2639: }
2640: }
2641: if (f == NULL)
2642: { err_head();
2643: fprintf(stderr,"can't find include file %s\n",name);
1.6 ! fujimoto 2644: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2645: fflush(stderr);
! 2646: #endif
1.1 noro 2647: free(name);
2648: return;
2649: }
2650: if (incldep)
2651: { printf("%s: %s\n",incldep_o,n);
2652: }
2653: out_at(!sharp,n);
2654: autodef_file(n);
2655: autodef_line(1);
2656: Push('\n');
2657: Get();
2658: push_new_file(n,f);
2659: cp = Rindex(n,DELIM);
2660: if (cp)
2661: { *cp = '\0';
2662: cp = copyofstr(n);
2663: }
2664: else
2665: { cp = copyofstr(".");
2666: }
2667: check_malloc(cp);
2668: *Curdir() = cp;
2669: free(name);
2670: return;
2671: }
2672:
2673: /*#define DEBUG_IO/**/
2674: /*#define DEBUG_INCL/**/
2675:
2676: #if defined(DEBUG_IO) || defined(DEBUG_INCL)
2677: extern int debugging;
2678: #endif
2679:
2680: extern int no_line_lines;
2681:
2682: int linefirst;
2683: int willbefirst;
2684: int lineno[MAXFILES];
2685: FILE *fstack[MAXFILES];
2686: int fstackdepth;
2687: char *fn[MAXFILES];
2688: int npushed[MAXFILES];
2689: char pushback[MAXFILES][MAX_PUSHBACK];
2690: char *incldir[MAXFILES];
2691: FILE *outfile;
2692:
2693: char *cur_pushback;
2694: int cur_npushed;
2695: FILE *cur_fstack;
2696: char *cur_fn;
2697: char *cur_incldir;
2698: int cur_lineno;
2699:
2700: typedef struct _mark {
2701: struct _mark *link;
2702: char *acc;
2703: int startdepth;
2704: int incs[MAXFILES];
2705: int nincs;
2706: int nignore; } MARK;
2707:
2708: static MARK *marks;
2709: static int atline;
2710: static char *atfile;
2711: static int done_line;
2712: static int nnls;
2713:
2714: /* XXX these definitions assume no input chars are 81, 82, 83 */
2715: #define NOEXPAND ((char)0x81)
2716: #define MARKLINE ((char)0x82)
2717: #define MARKLEND ((char)0x83)
2718:
2719: void init_io(FILE *f, char *fnname)
2720: {
2721: register int i;
2722:
2723: fstackdepth = 0;
2724: cur_pushback = pushback[0];
2725: cur_npushed = 0;
2726: cur_fstack = f;
2727: cur_fn = copyofstr(fnname);
2728: check_malloc(cur_fn);
2729: cur_lineno = 1;
2730: nnls = 0;
2731: atfile = copyofstr("");
2732: check_malloc(atfile);
2733: for (i=0;i<MAXFILES;i++)
2734: { npushed[i] = 0;
2735: }
2736: marks = 0;
2737: }
2738:
2739: void init_incldir(char *d)
2740: {
2741: cur_incldir = copyofstr(d);
2742: check_malloc(cur_incldir);
2743: }
2744:
2745: void change_fstackdepth(int delta)
2746: {
2747: npushed[fstackdepth] = cur_npushed;
2748: fstack[fstackdepth] = cur_fstack;
2749: fn[fstackdepth] = cur_fn;
2750: incldir[fstackdepth] = cur_incldir;
2751: lineno[fstackdepth] = cur_lineno;
2752: fstackdepth += delta;
2753: cur_pushback = pushback[fstackdepth];
2754: cur_npushed = npushed[fstackdepth];
2755: cur_fstack = fstack[fstackdepth];
2756: cur_fn = fn[fstackdepth];
2757: cur_incldir = incldir[fstackdepth];
2758: cur_lineno = lineno[fstackdepth];
2759: }
2760:
2761: #define GET() (cur_pushback[--cur_npushed])
2762: #define PUSH() (cur_pushback[cur_npushed++])
2763:
2764: char Get(void)
2765: {
2766: char c;
2767:
2768: linefirst = willbefirst;
2769: willbefirst = 0;
2770: while (1)
2771: { if (cur_npushed > 0)
2772: { do
2773: { c = GET();
2774: } while (c == NOEXPAND);
2775: if (c == MARKLINE)
2776: { mark_get_line();
2777: continue;
2778: }
2779: mark_got_from_pushback(c);
2780: #ifdef DEBUG_IO
2781: if (debugging)
2782: { outputc('(');
2783: outputs(unctrl(c));
2784: outputc(')');
2785: fflush(outfile);
2786: }
2787: #endif
2788: break;
2789: }
2790: else
2791: { c = getc(cur_fstack);
2792: if (feof(cur_fstack))
2793: { if (fstackdepth > 0)
2794: {
2795: #ifdef DEBUG_INCL
2796: if (debugging)
2797: { outputs("--eof:");
2798: outputs(cur_fn);
2799: outputs("--");
2800: }
2801: #endif
2802: fclose(cur_fstack);
2803: free(cur_fn);
2804: free(cur_incldir);
2805: change_fstackdepth(-1);
2806: mark_file_ending();
2807: out_at(cur_lineno,cur_fn);
2808: autodef_file(curfile());
2809: autodef_line(curline());
2810: continue;
2811: }
2812: else
2813: { flush_final_nl();
2814: save_stats();
2815: #if 0
2816: exit(0);
2817: #endif
2818: longjmp(cpp_env,1);
2819: }
2820: }
2821: mark_got_from_file(c);
2822: #ifdef DEBUG_IO
2823: if (debugging)
2824: { outputc('<');
2825: outputs(unctrl(c));
2826: outputc('>');
2827: fflush(outfile);
2828: }
2829: #endif
2830: break;
2831: }
2832: }
2833: if (c == '\n')
2834: { cur_lineno ++;
2835: autodef_line(curline());
2836: willbefirst = 1;
2837: }
2838: return(c);
2839: }
2840:
2841: void push_new_file(char *name, FILE *f)
2842: {
2843: change_fstackdepth(1);
2844: cur_fn = copyofstr(name);
2845: check_malloc(cur_fn);
2846: cur_lineno = 1;
2847: cur_fstack = f;
2848: cur_npushed = 0;
2849: #ifdef DEBUG_INCL
2850: if (debugging)
2851: { outputs("--newfile:");
2852: outputs(name);
2853: outputs("--");
2854: }
2855: #endif
2856: mark_file_beginning();
2857: }
2858:
2859: void Push(char c)
2860: {
2861: if (cur_npushed > MAX_PUSHBACK)
2862: { fprintf(stderr,"too much pushback\n");
1.6 ! fujimoto 2863: #if defined(__MINGW32__) || defined(__MINGW64__)
! 2864: fflush(stderr);
! 2865: #endif
1.1 noro 2866: cur_npushed = 0;
2867: }
2868: PUSH() = c;
2869: mark_charpushed();
2870: willbefirst = 0;
2871: if (c == '\n')
2872: { cur_lineno --;
2873: autodef_line(curline());
2874: }
2875: #ifdef DEBUG_IO
2876: if (debugging)
2877: { outputc('[');
2878: outputs(unctrl(c));
2879: outputc(']');
2880: fflush(outfile);
2881: }
2882: #endif
2883: }
2884:
2885: char *curfile(void)
2886: {
2887: return(cur_fn);
2888: }
2889:
2890: char **Curfile(void)
2891: {
2892: return(&cur_fn);
2893: }
2894:
2895: int curline(void)
2896: {
2897: return(cur_lineno);
2898: }
2899:
2900: int *Curline(void)
2901: {
2902: return(&cur_lineno);
2903: }
2904:
2905: char *curdir(void)
2906: {
2907: return(cur_incldir);
2908: }
2909:
2910: char **Curdir(void)
2911: {
2912: return(&cur_incldir);
2913: }
2914:
2915: char getnonspace(void)
2916: {
2917: char c;
2918:
2919: while (isspace(c=Get())) ;
2920: return(c);
2921: }
2922:
2923: char getnonhspace(void)
2924: {
2925: char c;
2926:
2927: while (ishspace(c=Get())) ;
2928: return(c);
2929: }
2930:
2931: char getnhsexpand(void)
2932: {
2933: char c;
2934:
2935: while (1)
2936: { c = getexpand();
2937: if (ishspace(c))
2938: { continue;
2939: }
2940: if (expr_sharp && (c == '\\'))
2941: { c = Get();
2942: if (c == '\n')
2943: { continue;
2944: }
2945: else
2946: { Push(c);
2947: c = '\\';
2948: }
2949: }
2950: break;
2951: }
2952: return(c);
2953: }
2954:
2955: char getexpand(void)
2956: {
2957: char c;
2958: char *str;
2959: DEF *d;
2960:
2961: while (1)
2962: { c = Get();
2963: if (c == '/')
2964: { char d;
2965: d = Get();
2966: if (d == '*')
2967: { d = '\0';
2968: do
2969: { c = d;
2970: d = Get();
2971: } while ((c != '*') || (d != '/'));
2972: continue;
2973: }
2974: else
2975: { Push(d);
2976: return('/');
2977: }
2978: }
2979: else if (c == NOEXPAND)
2980: { c = Get();
2981: if (issymchar(c))
2982: { Push(NOEXPAND);
2983: }
2984: return(c);
2985: }
2986: else if (! isbsymchar(c))
2987: {
2988: return(c);
2989: }
2990: str = init_accum();
2991: do
2992: { accum_char(str,c);
2993: } while (issymchar(c=Get()));
2994: Push(c);
2995: str = accum_result(str);
2996: if (d = find_def(str))
2997: { expand_def(d);
2998: free(str);
2999: }
3000: else
3001: { int i;
3002: for (i=strlen(str)-1;i>0;i--)
3003: { Push(str[i]);
3004: }
3005: Push(NOEXPAND);
3006: c = str[0];
3007: free(str);
3008: return(c);
3009: }
3010: }
3011: }
3012:
3013: char *read_ctrl(void)
3014: {
3015: char c;
3016: char *acc;
3017:
3018: acc = init_accum();
3019: while (ishspace(c=Get())) ;
3020: Push(c);
3021: while (1)
3022: { c = Get();
3023: if (islower(c))
3024: { accum_char(acc,c);
3025: }
3026: else
3027: { Push(c);
3028: return(accum_result(acc));
3029: }
3030: }
3031: }
3032:
3033: char *read_ident(void)
3034: {
3035: char *acc;
3036: char c;
3037:
3038: c = getnonspace();
3039: if (! isbsymchar(c))
3040: { Push(c);
3041: return(0);
3042: }
3043: acc = init_accum();
3044: do
3045: { accum_char(acc,c);
3046: } while (issymchar(c=Get()));
3047: Push(c);
3048: return(accum_result(acc));
3049: }
3050:
3051: void out_at(int line, char *file)
3052: {
3053: if ((line-nnls != atline) || strcmp(file,atfile))
3054: { free(atfile);
3055: atline = line - nnls;
3056: atfile = copyofstr(file);
3057: check_malloc(atfile);
3058: done_line = 0;
3059: }
3060: }
3061:
3062: void outputc(char c)
3063: {
3064: extern int incldep;
3065: static char *white = 0;
3066:
3067: if (incldep)
3068: { return;
3069: }
3070: if (c == '\n')
3071: { nnls ++;
3072: if (white)
3073: { free(accum_result(white));
3074: white = 0;
3075: }
3076: }
3077: else if ((nnls > 0) && ((c == ' ') || (c == '\t')))
3078: { if (! white)
3079: { white = init_accum();
3080: }
3081: accum_char(white,c);
3082: }
3083: else
3084: { if ((nnls > 2) || !done_line)
3085: { atline += nnls;
3086: nnls = 0;
3087: if (no_line_lines)
3088: { fprintf(outfile,"\n");
3089: }
3090: else
3091: { fprintf(outfile,"\n# %d \"%s\"\n",atline,atfile);
3092: }
3093: done_line = 1;
3094: }
3095: for (;nnls;nnls--)
3096: { atline ++;
3097: putc('\n',outfile);
3098: }
3099: if (white)
3100: { white = accum_result(white);
3101: fputs(white,outfile);
3102: free(white);
3103: white = 0;
3104: }
3105: putc(c,outfile);
3106: }
3107: }
3108:
3109: void flush_final_nl(void)
3110: {
3111: if (nnls > 0)
3112: { putc('\n',outfile);
3113: }
3114: }
3115:
3116: void outputs(char *s)
3117: {
3118: for (;*s;s++)
3119: { outputc(*s);
3120: }
3121: }
3122:
3123: void outputd(int n)
3124: {
3125: char temp[64];
3126:
3127: sprintf(temp,"%d",n);
3128: outputs(temp);
3129: }
3130:
3131: void mark_push_here(MARK *,int,char *);
3132:
3133: void input_mark(void)
3134: {
3135: MARK *m;
3136:
3137: m = NEW(MARK);
3138: check_malloc(m);
3139: m->link = marks;
3140: marks = m;
3141: m->startdepth = fstackdepth;
3142: m->acc = init_accum();
3143: m->nignore = 0;
3144: m->nincs = 0;
3145: mark_push_here(m,curline(),curfile());
3146: #ifdef DEBUG_IO
3147: if (debugging)
3148: { outputs("~MARK~");
3149: }
3150: #endif
3151: }
3152:
3153: void input_unmark(void)
3154: {
3155: MARK *m;
3156:
3157: if (marks)
3158: { m = marks;
3159: marks = m->link;
3160: free(accum_result(m->acc));
3161: OLD(m);
3162: #ifdef DEBUG_IO
3163: if (debugging)
3164: { outputs("~UNMARK~");
3165: }
3166: #endif
3167: }
3168: }
3169:
3170: void input_recover(void)
3171: {
3172: register MARK *m;
3173: register char *txt;
3174: register int i;
3175: register int l;
3176: char c;
3177:
3178: if (marks)
3179: { m = marks;
3180: marks = m->link;
3181: #ifdef DEBUG_IO
3182: if (debugging)
3183: { outputs("~RECOVER~");
3184: }
3185: #endif
3186: for (;m->nignore>0;m->nignore--)
3187: { accum_regret(m->acc);
3188: }
3189: txt = accum_result(m->acc);
3190: i = strlen(txt) - 1;
3191: while (m->nincs > 0)
3192: { l = m->incs[--m->nincs];
3193: for (;i>=l;i--)
3194: { Push(txt[i]);
3195: }
3196: Push(MARKLEND);
3197: c = txt[i];
3198: for (i--;txt[i]!=c;i--)
3199: { Push(txt[i]);
3200: }
3201: Push('A');
3202: Push('@');
3203: Push('@');
3204: Push('@');
3205: Push('@');
3206: Push('@');
3207: Push('@');
3208: Push('@');
3209: for (;(txt[i]!='#')&&(txt[i]!='@');i--) ;
3210: Push(MARKLINE);
3211: i --;
3212: }
3213: for (;i>=0;i--)
3214: { Push(txt[i]);
3215: }
3216: free(txt);
3217: OLD(m);
3218: }
3219: }
3220:
3221: void mark_file_beginning(void)
3222: {
3223: register MARK *m;
3224:
3225: for (m=marks;m;m=m->link)
3226: { m->incs[m->nincs++] = accum_howfar(m->acc);
3227: }
3228: }
3229:
3230: void mark_file_ending(void)
3231: {
3232: register MARK *m;
3233: register int i;
3234: register int to;
3235: register char *acc;
3236:
3237: for (m=marks;m;m=m->link)
3238: { if (m->startdepth > fstackdepth)
3239: { m->startdepth = fstackdepth;
3240: mark_push_here(m,curline(),curfile());
3241: }
3242: else if (m->nincs <= 0)
3243: { fprintf(stderr,"INTERNAL BUG: nincs<0 in mark_file_ending\n");
1.6 ! fujimoto 3244: #if defined(__MINGW32__) || defined(__MINGW64__)
! 3245: fflush(stderr);
! 3246: #endif
1.1 noro 3247: abort();
3248: }
3249: else
3250: { to = m->incs[--m->nincs];
3251: acc = m->acc;
3252: for (i=accum_howfar(acc);i>to;i--)
3253: { accum_regret(acc);
3254: }
3255: }
3256: }
3257: }
3258:
3259: void mark_charpushed(void)
3260: {
3261: register MARK *m;
3262:
3263: for (m=marks;m;m=m->link)
3264: { m->nignore ++;
3265: }
3266: }
3267:
3268: void mark_got_from_pushback(char c)
3269: {
3270: mark_got(c);
3271: }
3272:
3273: void mark_got_from_file(char c)
3274: {
3275: mark_got(c);
3276: }
3277:
3278: void mark_got(char c)
3279: {
3280: register MARK *m;
3281:
3282: for (m=marks;m;m=m->link)
3283: { if (m->nignore > 0)
3284: { m->nignore --;
3285: }
3286: else
3287: { accum_char(m->acc,c);
3288: }
3289: }
3290: }
3291:
3292: void mark_push_here(MARK *m, int l, char *f)
3293: {
3294: int i;
3295: char c;
3296:
3297: switch (c=accum_regret(m->acc))
3298: { case 0:
3299: break;
3300: case MARKLEND:
3301: while (accum_regret(m->acc) != MARKLINE) ;
3302: break;
3303: default:
3304: accum_char(m->acc,c);
3305: break;
3306: }
3307: accum_char(m->acc,MARKLINE);
3308: for (i=28;i>=0;i-=4)
3309: { accum_char(m->acc,(char)('@'+((l>>i)&0xf)));
3310: }
3311: for (;*f;f++)
3312: { accum_char(m->acc,*f);
3313: }
3314: accum_char(m->acc,MARKLEND);
3315: }
3316:
3317: void mark_get_line(void)
3318: {
3319: int l;
3320: char *f;
3321: int i;
3322: char c;
3323: MARK *m;
3324:
3325: l = 0;
3326: for (i=0;i<8;i++)
3327: { l = (l << 4) + (GET() & 0xf);
3328: }
3329: f = init_accum();
3330: while ((c=GET()) != MARKLEND)
3331: { accum_char(f,c);
3332: }
3333: f = accum_result(f);
3334: out_at(l,f);
3335: for (m=marks;m;m=m->link)
3336: { mark_push_here(m,l,f);
3337: }
3338: free(f);
3339: }
3340:
3341: int ishspace(char c)
3342: {
3343: return((c == ' ') || (c == '\t'));
3344: }
3345:
3346: int isbsymchar(char c)
3347: {
3348: return(isalpha(c) || (c == '_'));
3349: }
3350:
3351: int issymchar(char c)
3352: {
3353: return(isalnum(c) || (c == '_') || (c == '$'));
3354: }
3355:
3356: void do_line(void)
3357: {
3358: char c;
3359:
3360: outputc('#');
3361: while ((c=Get()) != '\n')
3362: { outputc(c);
3363: }
3364: }
3365:
3366: #define DEBUG_MAIN/**/
3367:
3368: extern char **argvec;
3369:
3370: char *Index(char *s, int c);
3371: char *Rindex(char *s, int c);
3372:
3373: #ifdef DEBUG_MAIN
3374: extern int debugging;
3375: #endif
3376:
3377: static char quote;
3378:
3379: IF *ifstack;
3380: int n_skipped_ifs;
3381:
3382: int keep_comments;
3383: int no_line_lines;
3384: int incldep;
3385: char *incldep_o;
3386: int do_at_ctrls;
3387: extern char *predefs[];
3388:
3389: #if defined(SYSV)
3390: void main(ac,av)
3391: #else
3392: void cpp_main(int ac, char **av)
3393: #endif
3394: {
3395: int argno;
3396: int rest;
3397: char *cp;
3398: static FILE *inf;
3399: static FILE *outf;
3400: char *inname;
3401: int backslash;
3402: int i;
3403:
3404: if ( setjmp(cpp_env) ) {
3405: if ( inf != stdin )
3406: fclose(inf);
3407: if ( outf == stdout )
3408: fflush(outf);
3409: else
3410: fclose(outf);
3411: return;
3412: }
3413:
3414: init_symtbl();
3415: #define predef(str) ( (cp=copyofstr("1")), \
3416: check_malloc(cp), \
3417: define((str),-1,(unsigned char *)cp,DEF_PREDEF) )
3418: for (i=0;predefs[i];i++)
3419: { predef(predefs[i]);
3420: }
3421: init_include();
3422: inf = stdin;
3423: outf = stdout;
3424: inname = "";
3425: keep_comments = 0;
3426: no_line_lines = 0;
3427: do_at_ctrls = 0;
3428: incldep = 0;
3429: argno = 0;
3430: for (ac--,av++;ac;ac--,av++)
3431: { if (**av == '-')
3432: { rest = 0;
3433: if (!strcmp(*av,"-undef"))
3434: { undef_predefs();
3435: }
3436: else
3437: { for (++*av;(**av)&&!rest;++*av)
3438: { switch (**av)
3439: { case 'C':
3440: keep_comments = 1;
3441: break;
3442: case 'D':
3443: rest = 1;
3444: ++*av;
3445: if (strcmp(*av,"@") == 0)
3446: { do_at_ctrls = 1;
3447: }
3448: else
3449: { cp = Index(*av,'=');
3450: if (cp)
3451: { if (cp != *av)
3452: { char *dp;
3453: *cp++ = '\0';
3454: dp = copyofstr(cp);
3455: check_malloc(dp);
3456: define(*av,-1,(unsigned char *)dp,DEF_CMDLINE);
3457: }
3458: else
3459: { fprintf(stderr,"Must give a name for -D\n");
3460: }
3461: }
3462: else
3463: { char *dp;
3464: dp = copyofstr("1");
3465: check_malloc(dp);
3466: define(*av,-1,(unsigned char *)dp,DEF_CMDLINE);
3467: }
3468: }
3469: break;
3470: case 'E':
3471: break;
3472: case 'I':
3473: rest = 1;
3474: ++*av;
3475: if (**av)
3476: { Ifile(*av);
3477: }
3478: else
3479: { fprintf(stderr,"Must give a directory name for -I\n");
3480: }
3481: break;
3482: case 'M':
3483: incldep = 1;
3484: break;
3485: case 'P':
3486: no_line_lines = 1;
3487: break;
3488: case 'R':
3489: break;
3490: case 'U':
3491: rest = 1;
3492: ++*av;
3493: if (**av)
3494: { undef(*av);
3495: }
3496: else
3497: { fprintf(stderr,"Must give a name for -U\n");
3498: }
3499: break;
3500: default:
3501: fprintf(stderr,"Unknown flag -%c\n",**av);
3502: break;
3503: }
3504: }
3505: }
3506: }
3507: else
3508: { switch (argno++)
3509: { case 0:
3510: if (strcmp(*av,"-") != 0)
3511: { FILE *f;
3512: f = fopen(*av,"r");
3513: if (f == NULL)
3514: { fprintf(stderr,"Cannot open source file %s\n",*av);
3515: }
3516: else
3517: { inf = f;
3518: inname = *av;
3519: }
3520: }
3521: break;
3522: case 1:
3523: if (strcmp(*av,"-") != 0)
3524: { FILE *f;
3525: f = fopen(*av,"w");
3526: if (f == NULL)
3527: { fprintf(stderr,"Can't create %s\n",*av);
3528: }
3529: else
3530: { outf = f;
3531: }
3532: }
3533: break;
3534: default:
3535: fprintf(stderr,"Extra name %s ignored\n",*av);
3536: break;
3537: }
3538: }
3539: }
3540: if (incldep && !inname[0])
3541: { fprintf(stderr,"No input file for -M flag\n");
3542: #if 0
3543: exit(1);
3544: #endif
3545: longjmp(cpp_env,1);
3546: }
3547: if (do_at_ctrls)
3548: { predef("at_sign_ctrls");
3549: }
3550: Ifile("/local/include");
3551: Ifile("/usr/include");
3552: willbefirst = 1;
3553: quote = 0;
3554: backslash = 0;
3555: init_io(inf,inname);
3556: outfile = outf;
3557: ifstack = 0;
3558: n_skipped_ifs = 0;
3559: cp = Rindex(inname,'/');
3560: if (cp)
3561: { *cp = '\0';
3562: init_incldir(inname);
3563: *cp = '/';
3564: }
3565: else
3566: { init_incldir(".");
3567: }
3568: autodef_file(inname);
3569: autodef_line(1);
3570: out_at(1,inname);
3571: if (incldep)
3572: { char *dp;
3573: cp = Rindex(inname,'/');
3574: if (cp)
3575: { cp ++;
3576: }
3577: else
3578: { cp = inname;
3579: }
3580: dp = cp + strlen(cp) - 2;
3581: if ((dp < cp) || strcmp(dp,".c"))
3582: { fprintf(stderr,"Missing .c in %s\n",inname);
3583: #if 0
3584: exit(1);
3585: #endif
3586: longjmp(cpp_env,1);
3587: }
3588: incldep_o = copyofstr(cp);
3589: incldep_o[dp+1-cp] = 'o';
3590: fprintf(outfile,"%s: ",incldep_o);
3591: fprintf(outfile,"%s\n",inname);
3592: }
3593: init_stats();
3594: while (1)
3595: { char c;
3596: int haddigit;
3597: c = Get();
3598: if (backslash)
3599: { maybe_print(c);
3600: backslash = 0;
3601: continue;
3602: }
3603: if (!incldep && (isdigit(c) || (c == '.')))
3604: { haddigit = 0;
3605: while (isdigit(c) || (c == '.'))
3606: { haddigit |= isdigit(c);
3607: maybe_print(c);
3608: c = Get();
3609: }
3610: if (haddigit && ((c == 'e') || (c == 'E')))
3611: { maybe_print(c);
3612: c = Get();
3613: while (isdigit(c))
3614: { maybe_print(c);
3615: c = Get();
3616: }
3617: }
3618: Push(c);
3619: continue;
3620: }
3621: if (quote)
3622: { if (c == '\\')
3623: { maybe_print(c);
3624: backslash = 1;
3625: continue;
3626: }
3627: else if ((c == quote) || (c == '\n'))
3628: { maybe_print(c);
3629: quote = 0;
3630: continue;
3631: }
3632: else
3633: { maybe_print(c);
3634: continue;
3635: }
3636: }
3637: if (c == '\\') /* this weirdness is Reiser semantics.... */
3638: { backslash = 1;
3639: maybe_print(c);
3640: continue;
3641: }
3642: if ((c == '\'') || (c == '"'))
3643: { quote = c;
3644: maybe_print(c);
3645: }
3646: else if (linefirst && (c == '#'))
3647: { do_sharp();
3648: }
3649: else if (do_at_ctrls && (c == '@'))
3650: { do_at();
3651: }
3652: else if (! incldep)
3653: { if (isbsymchar(c) && !in_false_if())
3654: { char *cp;
3655: DEF *d;
3656: cp = init_accum();
3657: while (issymchar(c))
3658: { accum_char(cp,c);
3659: c = Get();
3660: }
3661: Push(c);
3662: cp = accum_result(cp);
3663: #ifdef DEBUG_MAIN
3664: if (debugging)
3665: { outputs("<word:");
3666: outputs(cp);
3667: outputs(">");
3668: }
3669: #endif
3670: d = find_def(cp);
3671: if (d)
3672: { expand_def(d);
3673: n_hits ++;
3674: }
3675: else
3676: { for (;*cp;cp++)
3677: { maybe_print(*cp);
3678: }
3679: n_misses ++;
3680: }
3681: }
3682: else if (c == '/')
3683: { char d;
3684: d = Get();
3685: if (d == '*')
3686: { d = '\0';
3687: if (keep_comments)
3688: { maybe_print('/');
3689: maybe_print('*');
3690: }
3691: do
3692: { c = d;
3693: d = Get();
3694: if ((d == '\n') || keep_comments)
3695: { maybe_print(d);
3696: }
3697: } while ((c != '*') || (d != '/'));
3698: }
3699: else
3700: { Push(d);
3701: maybe_print(c);
3702: }
3703: }
3704: else
3705: { maybe_print(c);
3706: }
3707: }
3708: }
1.6 ! fujimoto 3709: #if defined(__MINGW32__) || defined(__MINGW64__)
! 3710: fflush(stderr);
! 3711: #endif
1.1 noro 3712: }
3713:
3714: void do_pragma(void)
3715: {
3716: char c;
3717:
3718: if (in_false_if())
3719: { while ((c=Get()) != '\n') ;
3720: }
3721: else
3722: { outputc('#');
3723: outputc('p');
3724: outputc('r');
3725: outputc('a');
3726: outputc('g');
3727: outputc('m');
3728: outputc('a');
3729: outputc(' ');
3730: while ((c=Get()) != '\n')
3731: { outputc(c);
3732: }
3733: }
3734: }
3735:
3736: char *predefs[] = {
3737: "mc68000",
3738: "unix",
3739: "NeXT",
3740: "__MACH__",
3741: 0
3742: };
3743:
3744: void do_set(void)
3745: {
3746: char *mac;
3747: char c;
3748: char temp[64];
3749:
3750: mac = read_ident();
3751: if (! mac)
3752: { err_head();
3753: fprintf(stderr,"@set: missing/illegal macro name\n");
3754: return;
3755: }
3756: if (! in_false_if())
3757: { char *cp;
3758: c = getnonspace();
3759: if (c != '(')
3760: { err_head();
3761: fprintf(stderr,"@set must have ()s\n");
3762: Push(c);
3763: return;
3764: }
3765: sprintf(temp,"%d",eval_expr(0,1));
3766: undef(mac);
3767: cp = copyofstr(temp);
3768: check_malloc(cp);
3769: define(mac,-1,(unsigned char *)cp,DEF_DEFINE);
3770: }
1.6 ! fujimoto 3771: #if defined(__MINGW32__) || defined(__MINGW64__)
! 3772: fflush(stderr);
! 3773: #endif
1.1 noro 3774: free(mac);
3775: }
3776:
3777: void do_sharp(void)
3778: {
3779: char *w;
3780: char c;
3781:
3782: w = read_ctrl();
3783: if (strcmp(w,"ifdef") == 0)
3784: { do_ifdef(1);
3785: }
3786: else if (strcmp(w,"ifndef") == 0)
3787: { do_ifndef(1);
3788: }
3789: else if (strcmp(w,"if") == 0)
3790: { do_if(1);
3791: }
3792: else if (strcmp(w,"else") == 0)
3793: { do_else(1);
3794: }
3795: else if (strcmp(w,"elif") == 0)
3796: { do_elif(1);
3797: }
3798: else if (strcmp(w,"endif") == 0)
3799: { do_endif(1);
3800: }
3801: else if (strcmp(w,"include") == 0)
3802: { do_include(1);
3803: }
3804: else if (strcmp(w,"define") == 0)
3805: { do_define(1,0);
3806: }
3807: else if (strcmp(w,"undef") == 0)
3808: { do_undef(1);
3809: }
3810: else if (strcmp(w,"line") == 0)
3811: { do_line();
3812: }
3813: else if (strcmp(w,"pragma") == 0)
3814: { do_pragma();
3815: }
3816: else if (strcmp(w,"") == 0)
3817: {
3818: }
3819: else
3820: { int isnull;
3821: isnull = 0;
3822: if (strcmp(w,"") == 0)
3823: { c = Get();
3824: if (c != '\n')
3825: { Push(c);
3826: }
3827: else
3828: { isnull = 1;
3829: }
3830: }
3831: if (!isnull && !in_false_if())
3832: { err_head();
3833: fprintf(stderr,"unknown control `%s'\n",w);
3834: flush_sharp_line();
3835: }
3836: }
1.6 ! fujimoto 3837: #if defined(__MINGW32__) || defined(__MINGW64__)
! 3838: fflush(stderr);
! 3839: #endif
1.1 noro 3840: maybe_print('\n');
3841: free(w);
3842: }
3843:
3844: void flush_sharp_line(void)
3845: {
3846: int quote;
3847: int backslash;
3848: int comment;
3849: int lastc;
3850: int c;
3851:
3852: quote = 0;
3853: backslash = 0;
3854: comment = 0;
3855: c = 'x';
3856: while (1)
3857: { lastc = c;
3858: c = Get();
3859: if (backslash)
3860: { backslash = 0;
3861: continue;
3862: }
3863: if (comment)
3864: { if (c == '\\')
3865: { backslash = 1;
3866: }
3867: else if ((c == '/') && (lastc == '*'))
3868: { comment = 0;
3869: }
3870: continue;
3871: }
3872: if (quote)
3873: { if (c == '\\')
3874: { backslash = 1;
3875: }
3876: else if (c == quote)
3877: { quote = 0;
3878: }
3879: }
3880: switch (c)
3881: { case '\\':
3882: backslash = 1;
3883: continue;
3884: break;
3885: case '"': case '\'':
3886: quote = c;
3887: continue;
3888: break;
3889: case '*':
3890: comment = (lastc == '/');
3891: continue;
3892: break;
3893: default:
3894: continue;
3895: break;
3896: case '\n':
3897: break;
3898: }
3899: break;
3900: }
3901: }
3902:
3903:
3904: int n_defines;
3905: int n_undefines;
3906: int n_hits;
3907: int n_misses;
3908:
3909: void init_stats(void)
3910: {
3911: n_defines = 0;
3912: n_undefines = 0;
3913: n_hits = 0;
3914: n_misses = 0;
3915: }
3916:
3917: void save_stats(void)
3918: {
3919: FILE *f;
3920:
3921: f = fopen("/@larry/u1/mouse/Mouse-C/cpp.stats","a");
3922: if (f)
3923: { fprintf(f,"%d def, %d undef, %d hits, %d misses\n",
3924: n_defines,n_undefines,n_hits,n_misses);
3925: fclose(f);
3926: }
3927: }
3928:
3929: DEF **symtbl;
3930: int symtbl_size;
3931: int n_in_table;
3932:
3933: static int size_index;
3934: static int sizes[] = { 7, 37, 179, 719, 2003, 8009, 30011, 120011, 0 };
3935:
3936: static int hash(unsigned char *s)
3937: {
3938: register unsigned int i;
3939:
3940: for (i=0;*s;s++)
3941: { i = (i >> 8) + (i << 3) + *s;
3942: }
3943: i &= ~0x80000000;
3944: return(i%symtbl_size);
3945: }
3946:
3947: void init_symtbl(void)
3948: {
3949: int i;
3950:
3951: symtbl_size = sizes[size_index=0];
3952: symtbl = (DEF **) malloc(symtbl_size*sizeof(DEF *));
3953: check_malloc(symtbl);
3954: for (i=0;i<symtbl_size;i++)
3955: { symtbl[i] = 0;
3956: }
3957: n_in_table = 0;
3958: }
3959:
3960: static void rehash_up(void)
3961: {
3962: int osize;
3963: DEF **otbl;
3964: int i;
3965: DEF *d;
3966: DEF *n;
3967: int h;
3968:
3969: if ((sizes[size_index] == 0) || (sizes[++size_index] == 0))
3970: { return;
3971: }
3972: osize = symtbl_size;
3973: otbl = symtbl;
3974: symtbl_size = sizes[size_index];
3975: symtbl = (DEF **) malloc(symtbl_size*sizeof(DEF *));
3976: check_malloc(symtbl);
3977: for (i=0;i<symtbl_size;i++)
3978: { symtbl[i] = 0;
3979: }
3980: for (i=0;i<osize;i++)
3981: { for (d=otbl[i];d;d=n)
3982: { n = d->link;
3983: h = hash((unsigned char *)d->name);
3984: d->link = symtbl[h];
3985: symtbl[h] = d;
3986: }
3987: }
3988: free((char *)otbl);
3989: }
3990:
3991: void define(char *name, int nargs, unsigned char *repl, int how)
3992: {
3993: int h;
3994: DEF *d;
3995: char *n;
3996:
3997: n = copyofstr(name);
3998: h = hash((unsigned char *)n);
3999: for (d=symtbl[h];d;d=d->link)
4000: { if (strcmp(d->name,n) == 0)
4001: { break;
4002: }
4003: }
4004: if (d)
4005: { if ( (nargs != d->nargs) || strcmp((char *)repl,(char *)d->repl) )
4006: { err_head();
4007: fprintf(stderr,"%s redefined\n",n);
1.6 ! fujimoto 4008: #if defined(__MINGW32__) || defined(__MINGW64__)
! 4009: fflush(stderr);
! 4010: #endif
1.1 noro 4011: }
4012: free((char *)d->repl);
4013: free(d->name);
4014: d->name = n;
4015: d->nargs = nargs;
4016: d->repl = repl;
4017: d->how = how;
4018: }
4019: else
4020: { d = NEW(DEF);
4021: check_malloc(d);
4022: d->name = n;
4023: d->nargs = nargs;
4024: d->repl = repl;
4025: d->how = how;
4026: d->link = symtbl[h];
4027: symtbl[h] = d;
4028: n_in_table ++;
4029: if (n_in_table > 2*symtbl_size)
4030: { rehash_up();
4031: }
4032: }
4033: if (strcmp(n,"at_sign_ctrls") == 0)
4034: { extern int do_at_ctrls;
4035: do_at_ctrls = 1;
4036: }
4037: }
4038:
4039: int undef(char *name)
4040: {
4041: int h;
4042: DEF **D;
4043: DEF *d;
4044: int rv;
4045:
4046: h = hash((unsigned char *)name);
4047: for (D=symtbl+h;*D;D= &(*D)->link)
4048: { if (strcmp((*D)->name,name) == 0)
4049: { break;
4050: }
4051: }
4052: rv = 0;
4053: if (d = *D)
4054: { *D = d->link;
4055: free(d->name);
4056: free((char *)d->repl);
4057: OLD(d);
4058: n_in_table --;
4059: rv = 1;
4060: }
4061: if (strcmp(name,"at_sign_ctrls") == 0)
4062: { extern int do_at_ctrls;
4063: do_at_ctrls = 0;
4064: }
4065: return rv;
4066: }
4067:
4068: DEF *find_def(char *name)
4069: {
4070: int h;
4071: DEF *d;
4072:
4073: h = hash((unsigned char *)name);
4074: for (d=symtbl[h];d;d=d->link)
4075: { if (strcmp(d->name,name) == 0)
4076: { break;
4077: }
4078: }
4079: return(d);
4080: }
4081:
4082: void defd(char *name, int value)
4083: {
4084: char temp[64];
4085: char *cp;
4086:
4087: sprintf(temp,"%d",value);
4088: undef(name);
4089: cp = copyofstr(temp);
4090: check_malloc(cp);
4091: define(name,-1,(unsigned char *)cp,DEF_DEFINE);
4092: }
4093:
4094: void undef_predefs(void)
4095: {
4096: int h;
4097: DEF **D;
4098: DEF *d;
4099:
4100: for (h=symtbl_size-1;h>=0;h--)
4101: { D = symtbl + h;
4102: while (*D)
4103: { d = *D;
4104: if (d->how == DEF_PREDEF)
4105: { free(d->name);
4106: free((char *)d->repl);
4107: *D = d->link;
4108: OLD(d);
4109: n_in_table --;
4110: }
4111: else
4112: { D = &d->link;
4113: }
4114: }
4115: }
4116: }
4117:
4118: char *_unctrl[0400] = { "^@",
4119: "^A",
4120: "^B",
4121: "^C",
4122: "^D",
4123: "^E",
4124: "^F",
4125: "^G",
4126: "^H",
4127: "^I",
4128: "^J",
4129: "^K",
4130: "^L",
4131: "^M",
4132: "^N",
4133: "^O",
4134: "^P",
4135: "^Q",
4136: "^R",
4137: "^S",
4138: "^T",
4139: "^U",
4140: "^V",
4141: "^W",
4142: "^X",
4143: "^Y",
4144: "^Z",
4145: "^[",
4146: "^\\",
4147: "^]",
4148: "^^",
4149: "^_",
4150: " ",
4151: "!",
4152: "\"",
4153: "#",
4154: "$",
4155: "%",
4156: "&",
4157: "'",
4158: "(",
4159: ")",
4160: "*",
4161: "+",
4162: ",",
4163: "-",
4164: ".",
4165: "/",
4166: "0",
4167: "1",
4168: "2",
4169: "3",
4170: "4",
4171: "5",
4172: "6",
4173: "7",
4174: "8",
4175: "9",
4176: ":",
4177: ";",
4178: "<",
4179: "=",
4180: ">",
4181: "?",
4182: "@",
4183: "A",
4184: "B",
4185: "C",
4186: "D",
4187: "E",
4188: "F",
4189: "G",
4190: "H",
4191: "I",
4192: "J",
4193: "K",
4194: "L",
4195: "M",
4196: "N",
4197: "O",
4198: "P",
4199: "Q",
4200: "R",
4201: "S",
4202: "T",
4203: "U",
4204: "V",
4205: "W",
4206: "X",
4207: "Y",
4208: "Z",
4209: "[",
4210: "\\",
4211: "]",
4212: "^",
4213: "_",
4214: "`",
4215: "a",
4216: "b",
4217: "c",
4218: "d",
4219: "e",
4220: "f",
4221: "g",
4222: "h",
4223: "i",
4224: "j",
4225: "k",
4226: "l",
4227: "m",
4228: "n",
4229: "o",
4230: "p",
4231: "q",
4232: "r",
4233: "s",
4234: "t",
4235: "u",
4236: "v",
4237: "w",
4238: "x",
4239: "y",
4240: "z",
4241: "{"/*}*/,
4242: "|",
4243: /*{*/"}",
4244: "~",
4245: "^?",
4246: "|^@",
4247: "|^A",
4248: "|^B",
4249: "|^C",
4250: "|^D",
4251: "|^E",
4252: "|^F",
4253: "|^G",
4254: "|^H",
4255: "|^I",
4256: "|^J",
4257: "|^K",
4258: "|^L",
4259: "|^M",
4260: "|^N",
4261: "|^O",
4262: "|^P",
4263: "|^Q",
4264: "|^R",
4265: "|^S",
4266: "|^T",
4267: "|^U",
4268: "|^V",
4269: "|^W",
4270: "|^X",
4271: "|^Y",
4272: "|^Z",
4273: "|^[",
4274: "|^\\",
4275: "|^]",
4276: "|^^",
4277: "|^_",
4278: "| ",
4279: "|!",
4280: "|\"",
4281: "|#",
4282: "|$",
4283: "|%",
4284: "|&",
4285: "|'",
4286: "|(",
4287: "|)",
4288: "|*",
4289: "|+",
4290: "|,",
4291: "|-",
4292: "|.",
4293: "|/",
4294: "|0",
4295: "|1",
4296: "|2",
4297: "|3",
4298: "|4",
4299: "|5",
4300: "|6",
4301: "|7",
4302: "|8",
4303: "|9",
4304: "|:",
4305: "|;",
4306: "|<",
4307: "|=",
4308: "|>",
4309: "|?",
4310: "|@",
4311: "|A",
4312: "|B",
4313: "|C",
4314: "|D",
4315: "|E",
4316: "|F",
4317: "|G",
4318: "|H",
4319: "|I",
4320: "|J",
4321: "|K",
4322: "|L",
4323: "|M",
4324: "|N",
4325: "|O",
4326: "|P",
4327: "|Q",
4328: "|R",
4329: "|S",
4330: "|T",
4331: "|U",
4332: "|V",
4333: "|W",
4334: "|X",
4335: "|Y",
4336: "|Z",
4337: "|[",
4338: "|\\",
4339: "|]",
4340: "|^",
4341: "|_",
4342: "|`",
4343: "|a",
4344: "|b",
4345: "|c",
4346: "|d",
4347: "|e",
4348: "|f",
4349: "|g",
4350: "|h",
4351: "|i",
4352: "|j",
4353: "|k",
4354: "|l",
4355: "|m",
4356: "|n",
4357: "|o",
4358: "|p",
4359: "|q",
4360: "|r",
4361: "|s",
4362: "|t",
4363: "|u",
4364: "|v",
4365: "|w",
4366: "|x",
4367: "|y",
4368: "|z",
4369: "|{"/*}*/,
4370: "||",
4371: /*{*/"|}",
4372: "|~",
4373: "|^?" };
4374:
4375: char *_Unctrl[0400] = { "^@",
4376: "^A",
4377: "^B",
4378: "^C",
4379: "^D",
4380: "^E",
4381: "^F",
4382: "^G",
4383: "^H",
4384: "^I",
4385: "^J",
4386: "^K",
4387: "^L",
4388: "^M",
4389: "^N",
4390: "^O",
4391: "^P",
4392: "^Q",
4393: "^R",
4394: "^S",
4395: "^T",
4396: "^U",
4397: "^V",
4398: "^W",
4399: "^X",
4400: "^Y",
4401: "^Z",
4402: "^[",
4403: "^\\",
4404: "^]",
4405: "^^",
4406: "^_",
4407: "sp",
4408: "!",
4409: "\"",
4410: "#",
4411: "$",
4412: "%",
4413: "&",
4414: "'",
4415: "(",
4416: ")",
4417: "*",
4418: "+",
4419: ",",
4420: "-",
4421: ".",
4422: "/",
4423: "0",
4424: "1",
4425: "2",
4426: "3",
4427: "4",
4428: "5",
4429: "6",
4430: "7",
4431: "8",
4432: "9",
4433: ":",
4434: ";",
4435: "<",
4436: "=",
4437: ">",
4438: "?",
4439: "@",
4440: "A",
4441: "B",
4442: "C",
4443: "D",
4444: "E",
4445: "F",
4446: "G",
4447: "H",
4448: "I",
4449: "J",
4450: "K",
4451: "L",
4452: "M",
4453: "N",
4454: "O",
4455: "P",
4456: "Q",
4457: "R",
4458: "S",
4459: "T",
4460: "U",
4461: "V",
4462: "W",
4463: "X",
4464: "Y",
4465: "Z",
4466: "[",
4467: "\\",
4468: "]",
4469: "^",
4470: "_",
4471: "`",
4472: "a",
4473: "b",
4474: "c",
4475: "d",
4476: "e",
4477: "f",
4478: "g",
4479: "h",
4480: "i",
4481: "j",
4482: "k",
4483: "l",
4484: "m",
4485: "n",
4486: "o",
4487: "p",
4488: "q",
4489: "r",
4490: "s",
4491: "t",
4492: "u",
4493: "v",
4494: "w",
4495: "x",
4496: "y",
4497: "z",
4498: "{"/*}*/,
4499: "|",
4500: /*{*/"}",
4501: "~",
4502: "^?",
4503: "|^@",
4504: "|^A",
4505: "|^B",
4506: "|^C",
4507: "|^D",
4508: "|^E",
4509: "|^F",
4510: "|^G",
4511: "|^H",
4512: "|^I",
4513: "|^J",
4514: "|^K",
4515: "|^L",
4516: "|^M",
4517: "|^N",
4518: "|^O",
4519: "|^P",
4520: "|^Q",
4521: "|^R",
4522: "|^S",
4523: "|^T",
4524: "|^U",
4525: "|^V",
4526: "|^W",
4527: "|^X",
4528: "|^Y",
4529: "|^Z",
4530: "|^[",
4531: "|^\\",
4532: "|^]",
4533: "|^^",
4534: "|^_",
4535: "|sp",
4536: "|!",
4537: "|\"",
4538: "|#",
4539: "|$",
4540: "|%",
4541: "|&",
4542: "|'",
4543: "|(",
4544: "|)",
4545: "|*",
4546: "|+",
4547: "|,",
4548: "|-",
4549: "|.",
4550: "|/",
4551: "|0",
4552: "|1",
4553: "|2",
4554: "|3",
4555: "|4",
4556: "|5",
4557: "|6",
4558: "|7",
4559: "|8",
4560: "|9",
4561: "|:",
4562: "|;",
4563: "|<",
4564: "|=",
4565: "|>",
4566: "|?",
4567: "|@",
4568: "|A",
4569: "|B",
4570: "|C",
4571: "|D",
4572: "|E",
4573: "|F",
4574: "|G",
4575: "|H",
4576: "|I",
4577: "|J",
4578: "|K",
4579: "|L",
4580: "|M",
4581: "|N",
4582: "|O",
4583: "|P",
4584: "|Q",
4585: "|R",
4586: "|S",
4587: "|T",
4588: "|U",
4589: "|V",
4590: "|W",
4591: "|X",
4592: "|Y",
4593: "|Z",
4594: "|[",
4595: "|\\",
4596: "|]",
4597: "|^",
4598: "|_",
4599: "|`",
4600: "|a",
4601: "|b",
4602: "|c",
4603: "|d",
4604: "|e",
4605: "|f",
4606: "|g",
4607: "|h",
4608: "|i",
4609: "|j",
4610: "|k",
4611: "|l",
4612: "|m",
4613: "|n",
4614: "|o",
4615: "|p",
4616: "|q",
4617: "|r",
4618: "|s",
4619: "|t",
4620: "|u",
4621: "|v",
4622: "|w",
4623: "|x",
4624: "|y",
4625: "|z",
4626: "|{"/*}*/,
4627: "||",
4628: /*{*/"|}",
4629: "|~",
4630: "|^?" };
4631:
4632: void do_undef(int expr_sharp)
4633: {
4634: char *mac;
4635:
4636: if (! in_false_if())
4637: { mac = read_ident();
4638: if (! mac)
4639: { err_head();
4640: fprintf(stderr,"missing/illegal macro name\n");
1.6 ! fujimoto 4641: #if defined(__MINGW32__) || defined(__MINGW64__)
! 4642: fflush(stderr);
! 4643: #endif
1.1 noro 4644: }
4645: else
4646: { if (undef(mac))
4647: { n_undefines ++;
4648: }
4649: }
4650: }
4651: if (sharp)
4652: { flush_sharp_line();
4653: }
4654: }
4655: /*#define DEBUG_WHILE/**/
4656:
4657: #ifdef DEBUG_WHILE
4658: extern int debugging;
4659: #endif
4660:
4661: void do_while(void)
4662: {
4663: input_mark();
4664: do_if(0);
4665: }
4666:
4667: void do_endwhile(void)
4668: {
4669: if (in_false_if())
4670: { do_endif(0);
4671: input_unmark();
4672: #ifdef DEBUG_WHILE
4673: if (debugging)
4674: { outputs("//endwhile:");
4675: outputd(curline());
4676: outputs(",");
4677: outputs(curfile());
4678: outputs("\\\\");
4679: }
4680: #endif
4681: out_at(curline(),curfile());
4682: }
4683: else
4684: { do_endif(0);
4685: input_recover();
4686: input_mark();
4687: do_if(0);
4688: }
4689: }
4690:
4691: char *Index(char *s, int c)
4692: {
4693: return strchr(s,c);
4694: }
4695:
4696: char *Rindex(char *s, int c)
4697: {
4698: return strrchr(s,c);
4699: }
4700:
4701: void Bcopy(char *from, char *to, int len)
4702: {
4703: #if defined(GO32)
4704: bcopy(from,to,len);
4705: #else
4706: memmove((void *)from,(void *)to,(int)len);
4707: #endif
4708: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>