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