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