|
|
1.1 root 1: #include <stdio.h>
2: #include <signal.h>
3: #include "m4.h"
4:
5: #define match(c,s) (c==*s && (!s[1] || inpmatch(s+1)))
6:
7: char *xcalloc();
8:
9:
10: main(argc,argv)
11: char **argv;
12: {
13: register t;
14:
15: {
16: static sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0};
17: for (t=0; sigs[t]; ++t)
18: if (signal(sigs[t], SIG_IGN) != SIG_IGN)
19: signal(sigs[t],catchsig);
20: }
21:
22: tempname = mktemp("/tmp/m4aXXXXXX");
23: close(creat(tempname,0));
24:
25: procnam = argv[0];
26: getflags(&argc,&argv);
27: initalloc();
28:
29: setfname("-");
30: if (argc>1) {
31: --argc;
32: ++argv;
33: if (strcmp(argv[0],"-")) {
34: ifile[ifx] = xfopen(argv[0],"r");
35: setfname(argv[0]);
36: }
37: }
38:
39: for (;;) {
40: token[0] = t = getchr();
41: token[1] = EOS;
42:
43: if (t==EOF) {
44: if (ifx > 0) {
45: fclose(ifile[ifx]);
46: ipflr = ipstk[--ifx];
47: continue;
48: }
49:
50: getflags(&argc,&argv);
51:
52: if (argc<=1)
53: if (Wrapstr) {
54: pbstr(Wrapstr);
55: Wrapstr = NULL;
56: continue;
57: } else
58: break;
59:
60: --argc;
61: ++argv;
62:
63: if (ifile[ifx]!=stdin)
64: fclose(ifile[ifx]);
65:
66: if (*argv[0]=='-')
67: ifile[ifx] = stdin;
68: else
69: ifile[ifx] = xfopen(argv[0],"r");
70:
71: setfname(argv[0]);
72: continue;
73: }
74:
75: if (isalpha(t)) {
76: register char *tp = token+1;
77: register tlim = toksize;
78:
79: while (alphanum(*tp++=getchr()))
80: if (--tlim<=0)
81: error2("more than %d chars in word",
82: toksize);
83:
84: putbak(*--tp);
85: *tp = EOS;
86:
87: if (((struct nlist *)(*((struct nlist **)Ap)=lookup(token)))->def) {
88: if (++Ap >= astklm) {
89: --Ap;
90: error2(astkof,stksize);
91: }
92:
93: if (Cp++==NULL)
94: Cp = callst;
95:
96: Cp->argp = Ap;
97: *Ap++ = op;
98: puttok(token);
99: stkchr(EOS);
100: t = getchr();
101: putbak(t);
102:
103: if (t!='(')
104: pbstr("()");
105: else /* try to fix arg count */
106: *Ap++ = op;
107:
108: Cp->plev = 0;
109: } else {
110: puttok(token);
111: }
112: } else if (match(t,lquote)) {
113: register qlev = 1;
114:
115: for (;;) {
116: token[0] = t = getchr();
117: token[1] = EOS;
118:
119: if (match(t,rquote)) {
120: if (--qlev > 0)
121: puttok(token);
122: else
123: break;
124: } else if (match(t,lquote)) {
125: ++qlev;
126: puttok(token);
127: } else {
128: if (t==EOF)
129: error("EOF in quote");
130:
131: putchr(t);
132: }
133: }
134: } else if (match(t,lcom)) {
135: puttok(token);
136:
137: for (;;) {
138: token[0] = t = getchr();
139: token[1] = EOS;
140:
141: if (match(t,rcom)) {
142: puttok(token);
143: break;
144: } else {
145: if (t==EOF)
146: error("EOF in comment");
147: putchr(t);
148: }
149: }
150: } else if (Cp==NULL) {
151: putchr(t);
152: } else if (t=='(') {
153: if (Cp->plev)
154: stkchr(t);
155: else {
156: /* skip white before arg */
157: while (isspace(t=getchr()))
158: ;
159:
160: putbak(t);
161: }
162:
163: ++Cp->plev;
164: } else if (t==')') {
165: --Cp->plev;
166:
167: if (Cp->plev==0) {
168: stkchr(EOS);
169: expand(Cp->argp,Ap-Cp->argp-1);
170: op = *Cp->argp;
171: Ap = Cp->argp-1;
172:
173: if (--Cp < callst)
174: Cp = NULL;
175: } else
176: stkchr(t);
177: } else if (t==',' && Cp->plev<=1) {
178: stkchr(EOS);
179: *Ap = op;
180:
181: if (++Ap >= astklm) {
182: --Ap;
183: error2(astkof,stksize);
184: }
185:
186: while (isspace(t=getchr()))
187: ;
188:
189: putbak(t);
190: } else
191: stkchr(t);
192: }
193:
194: if (Cp!=NULL)
195: error("EOF in argument list");
196:
197: delexit(OK);
198: }
199:
200: char *
201: inpmatch(s)
202: register char *s;
203: {
204: register char *tp = token+1;
205:
206: while (*s) {
207: *tp = getchr();
208:
209: if (*tp++ != *s++) {
210: *tp = EOS;
211: pbstr(token+1);
212: return 0;
213: }
214: }
215:
216: *tp = EOS;
217: return token;
218: }
219:
220: getflags(xargc,xargv)
221: register int *xargc;
222: register char ***xargv;
223: {
224: while (*xargc > 1) {
225: register char *arg = (*xargv)[1];
226:
227: if (arg[0]!='-' || arg[1]==EOS)
228: break;
229:
230: switch (arg[1]) {
231: case 'B':
232: bufsize = atoi(&arg[2]);
233: break;
234: case 'D':
235: {
236: register char *t;
237: char *s[2];
238:
239: initalloc();
240:
241: for (t = s[0] = &arg[2]; *t; t++)
242: if (*t=='=') {
243: *t++ = EOS;
244: break;
245: }
246:
247: s[1] = t;
248: dodef(&s[-1],2);
249: break;
250: }
251: case 'H':
252: hshsize = atoi(&arg[2]);
253: break;
254: case 'S':
255: stksize = atoi(&arg[2]);
256: break;
257: case 'T':
258: toksize = atoi(&arg[2]);
259: break;
260: case 'U':
261: {
262: char *s[1];
263:
264: initalloc();
265: s[0] = &arg[2];
266: doundef(&s[-1],1);
267: break;
268: }
269: case 'e':
270: setbuf(stdout,NULL);
271: signal(SIGINT,SIG_IGN);
272: break;
273: case 's':
274: /* turn on line sync */
275: sflag = 1;
276: break;
277: default:
278: fprintf(stderr,"%s: bad option: %s\n",
279: procnam,arg);
280: delexit(NOT_OK);
281: }
282:
283: (*xargv)++;
284: --(*xargc);
285: }
286:
287: return;
288: }
289:
290: initalloc()
291: {
292: static done = 0;
293: register t;
294:
295: if (done++)
296: return;
297:
298: hshtab = (struct nlist **)xcalloc(hshsize,sizeof(struct nlist *));
299: callst = (struct call *)xcalloc(stksize/3+1,sizeof(struct call));
300: Ap = argstk = (char **)xcalloc(stksize+3,sizeof(char *));
301: ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1,sizeof(char));
302: op = obuf = xcalloc(bufsize+1,sizeof(char));
303: token = xcalloc(toksize+1,sizeof(char));
304:
305: astklm = &argstk[stksize];
306: ibuflm = &ibuf[bufsize];
307: obuflm = &obuf[bufsize];
308: toklm = &token[toksize];
309:
310: for (t=0; barray[t].bname; ++t) {
311: static char p[2] = {0, EOS};
312:
313: p[0] = t|~LOW7;
314: install(barray[t].bname,p,NOPUSH);
315: }
316:
317: install("unix",nullstr,NOPUSH);
318: }
319:
320: /*struct nlist * */
321: install(nam,val,mode)
322: char *nam;
323: register char *val;
324: {
325: register struct nlist *np;
326: register char *cp;
327: int l;
328:
329: if (mode==PUSH)
330: lookup(nam); /* lookup sets hshval */
331: else
332: while (undef(nam)) /* undef calls lookup */
333: ;
334:
335: np = (struct nlist *)xcalloc(1,sizeof(*np));
336: np->name = copy(nam);
337: np->next = hshtab[hshval];
338: hshtab[hshval] = np;
339:
340: cp = xcalloc((l=strlen(val))+1,sizeof(*val));
341: np->def = cp;
342: cp = &cp[l];
343:
344: while (*val)
345: *--cp = *val++;
346: }
347:
348: struct nlist *
349: lookup(str)
350: char *str;
351: {
352: register char *s1, *s2;
353: register struct nlist *np;
354: static struct nlist nodef;
355:
356: s1 = str;
357:
358: for (hshval = 0; *s1; )
359: hshval += *s1++;
360:
361: hshval %= hshsize;
362:
363: for (np = hshtab[hshval]; np!=NULL; np = np->next) {
364: s1 = str;
365: s2 = np->name;
366: while (*s1++==*s2)
367: if (*s2++==EOS)
368: return(np);
369: }
370:
371: return(&nodef);
372: }
373:
374: expand(a1,c)
375: char **a1;
376: {
377: register char *dp;
378: register struct nlist *sp;
379:
380: sp = (struct nlist *)a1[-1];
381:
382: if (sp->tflag || trace) {
383: int i;
384:
385: fprintf(stderr,"Trace(%d): %s",Cp-callst,a1[0]);
386:
387: if (c > 0) {
388: fprintf(stderr,"(%s",chkbltin(a1[1]));
389: for (i=2; i<=c; ++i)
390: fprintf(stderr,",%s",chkbltin(a1[i]));
391: fprintf(stderr,")");
392: }
393:
394: fprintf(stderr,"\n");
395: }
396:
397: dp = sp->def;
398:
399: for (; *dp; ++dp) {
400: if (*dp&~LOW7) {
401: (*barray[*dp&LOW7].bfunc)(a1,c);
402: } else if (dp[1]=='$') {
403: if (isdigit(*dp)) {
404: register n;
405: if ((n = *dp-'0') <= c)
406: pbstr(a1[n]);
407: ++dp;
408: } else if (*dp=='#') {
409: pbnum((long) c);
410: ++dp;
411: } else if (*dp=='*' || *dp=='@') {
412: register i = c;
413: char **a = a1;
414:
415: if (i > 0)
416: for (;;) {
417: if (*dp=='@')
418: pbstr(rquote);
419:
420: pbstr(a[i--]);
421:
422: if (*dp=='@')
423: pbstr(lquote);
424:
425: if (i <= 0)
426: break;
427:
428: pbstr(",");
429: }
430: ++dp;
431: } else
432: putbak(*dp);
433: } else
434: putbak(*dp);
435: }
436: }
437:
438: setfname(s)
439: register char *s;
440: {
441: strcpy(fname[ifx],s);
442: fname[ifx+1] = fname[ifx]+strlen(s)+1;
443: fline[ifx] = 1;
444: nflag = 1;
445: lnsync(stdout);
446: }
447:
448: lnsync(iop)
449: register FILE *iop;
450: {
451: static int cline = 0;
452: static int cfile = 0;
453:
454: if (!sflag || iop!=stdout)
455: return;
456:
457: if (nflag || ifx!=cfile) {
458: nflag = 0;
459: cfile = ifx;
460: fprintf(iop,"#line %d \"",cline = fline[ifx]);
461: fpath(iop);
462: fprintf(iop,"\"\n");
463: } else if (++cline != fline[ifx])
464: fprintf(iop,"#line %d\n",cline = fline[ifx]);
465: }
466:
467: fpath(iop)
468: register FILE *iop;
469: {
470: register i;
471:
472: fprintf(iop,"%s",fname[0]);
473:
474: for (i=1; i<=ifx; ++i)
475: fprintf(iop,":%s",fname[i]);
476: }
477:
478: catchsig()
479: {
480: signal(SIGHUP,SIG_IGN);
481: signal(SIGINT,SIG_IGN);
482:
483: delexit(NOT_OK);
484: }
485:
486: delexit(code)
487: {
488: register i;
489:
490: cf = stdout;
491:
492: /* if (ofx != 0) { /* quitting in middle of diversion */
493: /* ofx = 0;
494: /* code = NOT_OK;
495: /* }
496: */
497: ofx = 0; /* ensure that everything comes out */
498: for (i=1; i<10; i++)
499: undiv(i,code);
500:
501: tempname[7] = 'a';
502: unlink(tempname);
503:
504: if (code==OK)
505: exit(code);
506:
507: _exit(code);
508: }
509:
510: puttok(tp)
511: register char *tp;
512: {
513: if (Cp) {
514: while (*tp)
515: stkchr(*tp++);
516: } else if (cf)
517: while (*tp)
518: sputchr(*tp++,cf);
519: }
520:
521: pbstr(str)
522: register char *str;
523: {
524: register char *p;
525:
526: p = str;
527:
528: while (*p++)
529: ;
530:
531: --p;
532:
533: while (p > str)
534: putbak(*--p);
535: }
536:
537: undiv(i,code)
538: register i;
539: {
540: register FILE *fp;
541: register c;
542:
543: if (i<1 || i>9 || i==ofx || !ofile[i])
544: return;
545:
546: fclose(ofile[i]);
547: tempname[7] = 'a'+i;
548:
549: if (code==OK && cf) {
550: fp = xfopen(tempname,"r");
551:
552: while ((c=getc(fp)) != EOF)
553: sputchr(c,cf);
554:
555: fclose(fp);
556: }
557:
558: unlink(tempname);
559: ofile[i] = NULL;
560: }
561:
562: char *copy(s)
563: register char *s;
564: {
565: register char *p, *s1;
566:
567: p = s1 = xcalloc(strlen(s)+1,1);
568:
569: while (*s1++ = *s++)
570: ;
571:
572: return(p);
573: }
574:
575: pbnum(num)
576: long num;
577: {
578: pbnbr(num,10,1);
579: }
580:
581: pbnbr(nbr,base,len)
582: long nbr;
583: register base, len;
584: {
585: register neg = 0;
586:
587: if (base<=0)
588: return;
589:
590: if (nbr<0) {
591: neg = 1;
592: nbr = -nbr;
593: }
594:
595: while (nbr>0) {
596: int i;
597: if (base>1) {
598: i = nbr%base;
599: nbr /= base;
600: } else {
601: i = 1;
602: --nbr;
603: }
604: putbak(itochr(i));
605: --len;
606: }
607:
608: while (--len >= 0)
609: putbak('0');
610:
611: if (neg)
612: putbak('-');
613: }
614:
615: itochr(i)
616: register i;
617: {
618: if (i>9)
619: return i-10+'A';
620: else
621: return i+'0';
622: }
623:
624: long ctol(str)
625: register char *str;
626: {
627: register sign;
628: long num;
629:
630: while (isspace(*str))
631: ++str;
632: num = 0;
633: if (*str=='-') {
634: sign = -1;
635: ++str;
636: }
637: else
638: sign = 1;
639: while (isdigit(*str))
640: num = num*10 + *str++ - '0';
641: return(sign * num);
642: }
643:
644: min(a,b)
645: {
646: if (a>b)
647: return(b);
648: return(a);
649: }
650:
651: FILE *
652: xfopen(name,mode)
653: char *name,
654: *mode;
655: {
656: FILE *fp;
657:
658: if ((fp=fopen(name,mode))==NULL)
659: error(badfile);
660:
661: return fp;
662: }
663:
664: char *
665: xcalloc(nbr,size)
666: {
667: register char *ptr;
668:
669: if ((ptr=calloc(nbr,size)) == NULL)
670: error(nocore);
671:
672: return ptr;
673: }
674:
675: error(str)
676: char *str;
677: {
678: fprintf(stderr,"\n%s:",procnam);
679: fpath(stderr);
680: fprintf(stderr,":%d %s\n",fline[ifx],str);
681: if (Cp) {
682: register struct call *mptr;
683:
684: /* fix limit */
685: *op = EOS;
686: (Cp+1)->argp = Ap+1;
687:
688: for (mptr=callst; mptr<=Cp; ++mptr) {
689: register char **aptr, **lim;
690:
691: aptr = mptr->argp;
692: lim = (mptr+1)->argp-1;
693: if (mptr==callst)
694: fputs(*aptr,stderr);
695: ++aptr;
696: fputs("(",stderr);
697: if (aptr < lim)
698: for (;;) {
699: fputs(*aptr++,stderr);
700: if (aptr >= lim)
701: break;
702: fputs(",",stderr);
703: }
704: }
705: while (--mptr >= callst)
706: fputs(")",stderr);
707:
708: fputs("\n",stderr);
709: }
710: delexit(NOT_OK);
711: }
712:
713: error2(str,num)
714: char *str;
715: int num;
716: {
717: char buf[500];
718:
719: fprintf(buf,str,num);
720: error(buf);
721: }
722:
723: char *
724: chkbltin(s)
725: char *s;
726: {
727: static char buf[24];
728:
729: if (*s&~LOW7) {
730: sprintf(buf,"<%s>",barray[*s&LOW7].bname);
731: return buf;
732: }
733: return s;
734: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.