1: #ifndef lint
2: static char sccsid[] = "@(#)m4.c 1.3 (Berkeley) 8/11/83";
3: #endif
4:
5: #include <stdio.h>
6: #include <signal.h>
7:
8: #define ERROR NULL
9: #define READ "r"
10: #define WRITE "w"
11:
12: #define EOS 0
13: int lpar = '(';
14: #define LPAR lpar
15: #define RPAR ')'
16: #define COMMA ','
17: #define GRAVE '`'
18: #define ACUTE '\''
19: #define LBRAK '['
20: #define RBRAK ']'
21: #ifdef M4
22: char lquote LBRAK;
23: char rquote RBRAK;
24: #endif
25: #ifndef M4
26: char lquote = GRAVE;
27: char rquote = ACUTE;
28: #endif
29: #define '#'
30: #define ALPH 1
31: #define DIG 2
32:
33: #define HSHSIZ 199 /* prime */
34: #define STACKS 50
35: #define SAVS 4096
36: #define TOKS 128
37:
38: #define putbak(c) *ip++ = c;
39: #define getchr() (ip>cur_ip?*--ip: getc(infile[infptr]))
40: #define putchr(c) if (cp==NULL) {if (curfile)putc(c,curfile);} else *op++ = c
41: char type[] = {
42: 0, 0, 0, 0, 0, 0, 0, 0,
43: 0, 0, 0, 0, 0, 0, 0, 0,
44: 0, 0, 0, 0, 0, 0, 0, 0,
45: 0, 0, 0, 0, 0, 0, 0, 0,
46: 0, 0, 0, 0, 0, 0, 0, 0,
47: 0, 0, 0, 0, 0, 0, 0, 0,
48: DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG,
49: DIG, DIG, 0, 0, 0, 0, 0, 0,
50: 0, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
51: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
52: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
53: ALPH, ALPH, ALPH, 0, 0, 0, 0, ALPH,
54: 0, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
55: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
56: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH,
57: ALPH, ALPH, ALPH, 0, 0, 0, 0, 0,
58: };
59:
60: char token[TOKS];
61: char eoa[] = "\0";
62:
63: #define RESERVED 01 /* This is a reserved word with side action */
64: struct nlist {
65: char *name;
66: char *def;
67: char flag;
68: struct nlist *next;
69: };
70:
71: struct nlist *hshtab[HSHSIZ];
72: char ibuf[SAVS+TOKS];
73: char obuf[SAVS+TOKS];
74: char *op = obuf;
75: char *ip = ibuf;
76: char *ip_stk[10] = {ibuf};
77: char *cur_ip = ibuf;
78: struct call {
79: char **argp;
80: int plev;
81: };
82: struct call *cp = NULL;
83:
84: char *makeloc;
85: char *ifdefloc;
86: char *lenloc;
87: char *undefloc;
88: char *shiftloc;
89: char *cqloc;
90: char *defloc;
91: char *evaloc;
92: char *incrloc;
93: char *substrloc;
94: char *indexloc;
95: char *transloc;
96: char *ifloc;
97: char *divloc;
98: char *divnumloc;
99: char *undivloc;
100: char *dnlloc;
101: char *inclloc;
102: char *sinclloc;
103: char *syscmdloc;
104: char *dumploc;
105: char *errploc;
106:
107: char *tempname;
108: struct nlist *lookup();
109: char *install();
110: char *malloc();
111: char *mktemp();
112: char *copy();
113: long ctol();
114: int hshval;
115: FILE *olist[11] = { stdout };
116: int okret;
117: int curout = 0;
118: FILE *curfile = { stdout };
119: FILE *infile[10] = { stdin };
120: int infptr = 0;
121:
122: main(argc, argv)
123: char **argv;
124: {
125: char *argstk[STACKS+10];
126: struct call callst[STACKS];
127: register char *tp, **ap;
128: int delexit(), catchsig();
129: register t;
130: int i;
131:
132: #ifdef gcos
133: #ifdef M4
134: install("GCOS", eoa, 0);
135: #endif
136: #ifndef M4
137: install("gcos", eoa, 0);
138: #endif
139: #endif
140: #ifdef unix
141: #ifdef M4
142: install("UNIX", eoa, 0);
143: #endif
144: #ifndef M4
145: install("unix", eoa, 0);
146: #endif
147: #endif
148:
149: #ifdef M4
150: makeloc = install("MAKETEMP", eoa, RESERVED);
151: ifdefloc = install("IFDEF", eoa, RESERVED);
152: lenloc = install("LEN", eoa, RESERVED);
153: undefloc = install("UNDEFINE", eoa, RESERVED);
154: shiftloc = install("SHIFT", eoa, RESERVED);
155: cqloc = install("CHANGEQUOTE", eoa, RESERVED);
156: defloc = install("DEFINE", eoa, RESERVED);
157: evaloc = install("EVAL", eoa, RESERVED);
158: inclloc = install("INCLUDE", eoa, RESERVED);
159: sinclloc = install("SINCLUDE", eoa, RESERVED);
160: syscmdloc = install("SYSCMD", eoa, RESERVED);
161: dumploc = install("DUMPDEF", eoa, RESERVED);
162: errploc = install("ERRPRINT", eoa, RESERVED);
163: incrloc = install("INCR", eoa, RESERVED);
164: substrloc = install("SUBSTR", eoa, RESERVED);
165: indexloc = install("INDEX", eoa, RESERVED);
166: transloc = install("TRANSLIT", eoa, RESERVED);
167: ifloc = install("IFELSE", eoa, RESERVED);
168: divloc = install("DIVERT", eoa, RESERVED);
169: divnumloc = install("DIVNUM", eoa, RESERVED);
170: undivloc = install("UNDIVERT", eoa, RESERVED);
171: dnlloc = install("DNL", eoa, RESERVED);
172: #endif
173:
174: #ifndef M4
175: makeloc = install("maketemp", eoa, RESERVED);
176: ifdefloc = install("ifdef", eoa, RESERVED);
177: lenloc = install("len", eoa, RESERVED);
178: undefloc = install("undefine", eoa, RESERVED);
179: shiftloc = install("shift", eoa, RESERVED);
180: cqloc = install("changequote", eoa, RESERVED);
181: defloc = install("define", eoa, RESERVED);
182: evaloc = install("eval", eoa, RESERVED);
183: inclloc = install("include", eoa, RESERVED);
184: sinclloc = install("sinclude", eoa, RESERVED);
185: syscmdloc = install("syscmd", eoa, RESERVED);
186: dumploc = install("dumpdef", eoa, RESERVED);
187: errploc = install("errprint", eoa, RESERVED);
188: incrloc = install("incr", eoa, RESERVED);
189: substrloc = install("substr", eoa, RESERVED);
190: indexloc = install("index", eoa, RESERVED);
191: transloc = install("translit", eoa, RESERVED);
192: ifloc = install("ifelse", eoa, RESERVED);
193: divloc = install("divert", eoa, RESERVED);
194: divnumloc = install("divnum", eoa, RESERVED);
195: undivloc = install("undivert", eoa, RESERVED);
196: dnlloc = install("dnl", eoa, RESERVED);
197: #endif
198: ap = argstk;
199: #ifndef gcos
200: if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
201: signal(SIGHUP, catchsig);
202: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
203: signal(SIGINT, catchsig);
204: tempname = mktemp("/tmp/m4aXXXXX");
205: close(creat(tempname, 0));
206: #endif
207: #ifdef gcos
208: tempname = "m4.tempa";
209: #endif
210: if (argc>1)
211: putbak(0);
212: for (;;) {
213: tp = token;
214: *tp++ = t = getchr();
215: *tp = EOS;
216: if (t<=0) {
217: if (infptr > 0) {
218: fclose(infile[infptr]);
219: infptr--;
220: cur_ip = ip_stk[infptr];
221: continue;
222: }
223: if (argc<=1)
224: break;
225: argc--;
226: argv++;
227: if (infile[infptr]!=stdin)
228: fclose(infile[infptr]);
229: if (**argv=='-')
230: infile[infptr] = stdin;
231: else if ((infile[infptr]=fopen(argv[0], READ))==ERROR) {
232: fprintf(stderr, "m4: file not found: %s\n", argv[0]);
233: delexit();
234: }
235: continue;
236: }
237: if (type[t]==ALPH) {
238: while ((t=type[*tp++=getchr()])==ALPH||t==DIG);
239: putbak(*--tp);
240: *tp = EOS;
241: if (*ap = lookup(token)->def) {
242: if (++ap >= &argstk[STACKS]) {
243: fprintf(stderr, "m4: arg stack overflow\n");
244: delexit();
245: }
246: if (cp==NULL)
247: cp = callst;
248: else if (++cp > &callst[STACKS]) {
249: fprintf(stderr, "m4: call stack overflow\n");
250: delexit();
251: }
252: cp->argp = ap;
253: *ap++ = op;
254: puttok();
255: *op++ = '\0';
256: t = getchr();
257: putbak(t);
258: if (t!=LPAR) {
259: /* if (t!=' ' && t!='\t') */
260: putbak(')');
261: putbak('(');
262: }
263: else /* try to fix arg count */
264: *ap++ = op;
265: cp->plev = 0;
266: } else
267: puttok();
268: } else if (t==lquote) {
269: i = 1;
270: for (;;) {
271: t = getchr();
272: if (t==rquote) {
273: i--;
274: if (i==0)
275: break;
276: } else if (t==lquote)
277: i++;
278: else if (t<0) {
279: fprintf(stderr, "m4: EOF in string\n");
280: delexit();
281: }
282: putchr(t);
283: }
284: } else if (t==COMMENT) {
285: putbak(t);
286: while ((t = getchr())!='\n'&& t>=0)
287: if (cp==NULL)
288: putchr(t);
289: putbak(t);
290: } else if (cp==NULL) {
291: puttok();
292: } else if (t==LPAR) {
293: if (cp->plev)
294: *op++ = t;
295: cp->plev++;
296: while ( (t=getchr())==' ' || t=='\t' || t=='\n')
297: ; /* skip leading white space during arg collection */
298: putbak(t);
299: /*
300: } else if (t==' ' || t=='\t' || t=='\n') {
301: continue;
302: */
303: } else if (t==RPAR) {
304: cp->plev--;
305: if (cp->plev==0) {
306: *op++ = '\0';
307: expand(cp->argp, ap-cp->argp-1);
308: op = *cp->argp;
309: ap = cp->argp-1;
310: cp--;
311: if (cp < callst)
312: cp = NULL;
313: } else
314: *op++ = t;
315: } else if (t==COMMA && cp->plev<=1) {
316: *op++ = '\0';
317: *ap++ = op;
318: while ((t=getchr())==' ' || t=='\t' || t=='\n')
319: ; /* skip leading white space during arg collection */
320: putbak(t);
321: } else
322: *op++ = t;
323: }
324: if (cp!=NULL) {
325: fprintf(stderr, "m4: unexpected EOF\n");
326: delexit();
327: }
328: okret = 1;
329: delexit();
330: }
331:
332: catchsig()
333: {
334: okret = 0;
335: delexit();
336: }
337:
338: delexit()
339: {
340: register FILE *fp;
341: register i, c;
342:
343: if (!okret) {
344: signal(SIGHUP, SIG_IGN);
345: signal(SIGINT, SIG_IGN);
346: }
347: for (i=1; i<10; i++) {
348: if (olist[i]==NULL)
349: continue;
350: fclose(olist[i]);
351: tempname[7] = 'a'+i;
352: if (okret) {
353: fp = fopen(tempname, READ);
354: while ((c = getc(fp)) > 0)
355: putchar(c);
356: fclose(fp);
357: }
358: unlink(tempname);
359: }
360: tempname[7] = 'a';
361: unlink(tempname);
362: exit(1-okret);
363: }
364:
365: puttok()
366: {
367: register char *tp;
368:
369: tp = token;
370: if (cp) {
371: if (op >= &obuf[SAVS]) {
372: fprintf(stderr, "m4: argument overflow\n");
373: delexit();
374: }
375: while (*tp)
376: *op++ = *tp++;
377: } else if (curfile)
378: while (*tp)
379: putc(*tp++, curfile);
380: }
381:
382: pbstr(str)
383: register char *str;
384: {
385: register char *p;
386:
387: p = str;
388: while (*p++);
389: --p;
390: if (ip >= &ibuf[SAVS]) {
391: fprintf(stderr, "m4: pushback overflow\n");
392: delexit();
393: }
394: while (p > str)
395: putbak(*--p);
396: }
397:
398: expand(a1, c)
399: register char **a1;
400: {
401: register char *dp;
402: register n;
403:
404: dp = a1[-1];
405: if (dp==defloc)
406: dodef(a1, c);
407: else if (dp==evaloc)
408: doeval(a1, c);
409: else if (dp==inclloc)
410: doincl(a1, c, 1);
411: else if (dp==sinclloc)
412: doincl(a1, c, 0);
413: else if (dp==makeloc)
414: domake(a1, c);
415: else if (dp==syscmdloc)
416: dosyscmd(a1, c);
417: else if (dp==incrloc)
418: doincr(a1, c);
419: else if (dp==substrloc)
420: dosubstr(a1, c);
421: else if (dp==indexloc)
422: doindex(a1, c);
423: else if (dp==transloc)
424: dotransl(a1, c);
425: else if (dp==ifloc)
426: doif(a1, c);
427: else if (dp==divloc)
428: dodiv(a1, c);
429: else if (dp==divnumloc)
430: dodivnum(a1, c);
431: else if (dp==undivloc)
432: doundiv(a1, c);
433: else if (dp==dnlloc)
434: dodnl(a1, c);
435: else if (dp==dumploc)
436: dodump(a1, c);
437: else if (dp==errploc)
438: doerrp(a1, c);
439: else if (dp==lenloc)
440: dolen(a1, c);
441: else if (dp==ifdefloc)
442: doifdef(a1, c);
443: else if (dp==undefloc)
444: doundef(a1, c);
445: else if (dp==shiftloc)
446: doshift(a1, c);
447: else if (dp==cqloc)
448: docq(a1, c);
449: else {
450: while (*dp++);
451: for (dp--; dp>a1[-1]; ) {
452: if (--dp>a1[-1] && dp[-1]=='$') {
453: n = *dp-'0';
454: if (n>=0 && n<=9) {
455: if (n <= c)
456: pbstr(a1[n]);
457: dp--;
458: } else
459: putbak(*dp);
460: } else
461: putbak(*dp);
462: }
463: }
464: }
465:
466: struct nlist *lookup(str)
467: char *str;
468: {
469: register char *s1, *s2;
470: register struct nlist *np;
471: static struct nlist nodef;
472:
473: s1 = str;
474: for (hshval = 0; *s1; )
475: hshval += *s1++;
476: hshval %= HSHSIZ;
477: for (np = hshtab[hshval]; np!=NULL; np = np->next) {
478: s1 = str;
479: s2 = np->name;
480: while (*s1++ == *s2)
481: if (*s2++ == EOS)
482: return(np);
483: }
484: return(&nodef);
485: }
486:
487: char *install(nam, val, flag)
488: char *nam, *val;
489: char flag;
490: {
491: register struct nlist *np;
492:
493: if ((np = lookup(nam))->name == NULL) {
494: np = (struct nlist *)malloc(sizeof(*np));
495: if (np == NULL) {
496: fprintf(stderr, "m4: no space for alloc\n");
497: exit(1);
498: }
499: np->name = copy(nam);
500: np->def = copy(val);
501: np->next = hshtab[hshval];
502: np->flag = flag;
503: hshtab[hshval] = np;
504: return(np->def);
505: }
506: free(np->def);
507: np->flag = flag;
508: np->def = copy(val);
509: return(np->def);
510: }
511:
512: doundef(ap, c)
513: char **ap;
514: {
515: register struct nlist *np, *tnp;
516:
517: if (c < 1 || (np = lookup(ap[1]))->name == NULL)
518: return;
519: tnp = hshtab[hshval]; /* lookup sets hshval */
520: if (tnp == np) /* it's in first place */
521: hshtab[hshval] = np->next;
522: else {
523: for ( ; tnp->next != np; tnp = tnp->next)
524: ;
525: tnp->next = np->next;
526: }
527: /*
528: * If this is a reserved word, it has been removed from the
529: * hastable. We do not want to actually free the space because
530: * of the code in expand. Expand wants to to pointer compairs
531: * to tell if this is a reserved word (e.g a special action
532: * needs to take place). Thus if we do not free the space,
533: * expand will still work, but the name will never be found
534: * because it out of the symbol table!
535: */
536: if (np->flag&RESERVED == 0) { /* If not reserved free it */
537: free(np->name);
538: free(np->def);
539: free((char *)np);
540: }
541: }
542:
543: char *copy(s)
544: register char *s;
545: {
546: register char *p, *s1;
547:
548: p = s1 = malloc((unsigned)strlen(s)+1);
549: if (p == NULL) {
550: fprintf(stderr, "m4: no space for alloc\n");
551: exit(1);
552: }
553: while (*s1++ = *s++);
554: return(p);
555: }
556:
557: dodef(ap, c)
558: char **ap;
559: {
560: if (c >= 2) {
561: if (strcmp(ap[1], ap[2]) == 0) {
562: fprintf(stderr, "m4: %s defined as itself\n", ap[1]);
563: delexit();
564: }
565: install(ap[1], ap[2], 0);
566: }
567: else if (c == 1)
568: install(ap[1], "", 0);
569: }
570:
571: doifdef(ap, c)
572: char **ap;
573: {
574: register struct nlist *np;
575:
576: if (c < 2)
577: return;
578: if (lookup(ap[1])->name != NULL)
579: pbstr(ap[2]);
580: else if (c >= 3)
581: pbstr(ap[3]);
582: }
583:
584: dolen(ap, c)
585: char **ap;
586: {
587: putnum((long) strlen(ap[1]));
588: }
589:
590: docq(ap, c)
591: char **ap;
592: {
593: if (c > 1) {
594: lquote = *ap[1];
595: rquote = *ap[2];
596: } else if (c == 1) {
597: lquote = rquote = *ap[1];
598: } else {
599: #ifndef M4
600: lquote = GRAVE;
601: rquote = ACUTE;
602: #endif
603: #ifdef M4
604: lquote = LBRAK;
605: rquote = RBRAK;
606: #endif
607: }
608: }
609:
610: doshift(ap, c)
611: char **ap;
612: {
613: fprintf(stderr, "m4: shift not yet implemented\n");
614: }
615:
616: dodump(ap, c)
617: char **ap;
618: {
619: int i;
620: register struct nlist *np;
621:
622: if (c > 0)
623: while (c--) {
624: if ((np = lookup(*++ap))->name != NULL)
625: fprintf(stderr, "`%s' `%s'\n", np->name, np->def);
626: }
627: else
628: for (i=0; i<HSHSIZ; i++)
629: for (np=hshtab[i]; np!=NULL; np=np->next)
630: fprintf(stderr, "`%s' `%s'\n", np->name, np->def);
631: }
632:
633: doerrp(ap, c)
634: char **ap;
635: {
636: if (c > 0) {
637: fprintf(stderr, ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]);
638: fprintf(stderr, "\n");
639: }
640: }
641:
642:
643: long evalval; /* return value from yacc stuff */
644: char *pe; /* used by grammar */
645:
646: doeval(ap, c)
647: char **ap;
648: {
649:
650: if (c > 0) {
651: pe = ap[1];
652: if (yyparse() == 0)
653: putnum(evalval);
654: else
655: fprintf(stderr, "m4: invalid expression in eval: %s\n", ap[1]);
656: }
657: }
658:
659: doincl(ap, c, noisy)
660: char **ap;
661: {
662: if (c > 0 && strlen(ap[1]) > 0) {
663: infptr++;
664: ip_stk[infptr] = cur_ip = ip;
665: if ((infile[infptr] = fopen(ap[1], READ))==ERROR) {
666: if (noisy) {
667: fprintf(stderr, "m4: file not found: %s\n", ap[1]);
668: delexit();
669: }
670: else
671: infptr--;
672: }
673: }
674: }
675:
676: dosyscmd(ap, c)
677: char **ap;
678: {
679: if (c > 0)
680: system(ap[1]);
681: }
682:
683: domake(ap, c)
684: char **ap;
685: {
686: if (c > 0)
687: pbstr(mktemp(ap[1]));
688: }
689:
690: doincr(ap, c)
691: char **ap;
692: {
693: if (c >= 1)
694: putnum(ctol(ap[1])+1);
695: }
696:
697: putnum(num)
698: long num;
699: {
700: register sign;
701:
702: sign = (num < 0) ? '-' : '\0';
703: if (num < 0)
704: num = -num;
705: do {
706: putbak(num%10+'0');
707: num = num/10;
708: } while (num!=0);
709: if (sign == '-')
710: putbak('-');
711: }
712:
713: dosubstr(ap, c)
714: char **ap;
715: {
716: int nc;
717: register char *sp, *fc;
718:
719: if (c<2)
720: return;
721: if (c<3)
722: nc = TOKS;
723: else
724: nc = ctoi(ap[3]);
725: fc = ap[1] + max(0, min(ctoi(ap[2]), strlen(ap[1])));
726: sp = fc + min(nc, strlen(fc));
727: while (sp > fc)
728: putbak(*--sp);
729: }
730:
731: doindex(ap, c)
732: char **ap;
733: {
734: if (c >= 2)
735: putnum((long) strindex(ap[1], ap[2]));
736: }
737:
738: strindex(p1, p2)
739: char *p1, *p2;
740: {
741: register m;
742: register char *s, *t, *p;
743:
744: for (p=p1; *p; p++) {
745: s = p;
746: m = 1;
747: for (t=p2; *t; )
748: if (*t++ != *s++)
749: m = 0;
750: if (m == 1)
751: return(p-p1);
752: }
753: return(-1);
754: }
755:
756: dotransl(ap, c)
757: char **ap;
758: {
759: register char *s, *fr, *to;
760:
761: if (c <= 1) return;
762:
763: if (c == 2) {
764: register int i;
765: to = ap[1];
766: for (s = ap[1]; *s; s++) {
767: i = 0;
768: for (fr = ap[2]; *fr; fr++)
769: if (*s == *fr) {
770: i++;
771: break;
772: }
773: if (i == 0)
774: *to++ = *s;
775: }
776: *to = '\0';
777: }
778:
779: if (c >= 3) {
780: for (s = ap[1]; *s; s++)
781: for (fr = ap[2], to = ap[3]; *fr && *to; fr++, to++)
782: if (*s == *fr)
783: *s = *to;
784: }
785:
786: pbstr(ap[1]);
787: }
788:
789: doif(ap, c)
790: register char **ap;
791: {
792: if (c < 3)
793: return;
794: while (c >= 3) {
795: if (strcmp(ap[1], ap[2]) == 0) {
796: pbstr(ap[3]);
797: return;
798: }
799: c -= 3;
800: ap += 3;
801: }
802: if (c > 0)
803: pbstr(ap[1]);
804: }
805:
806: dodiv(ap, c)
807: register char **ap;
808: {
809: register int f;
810:
811: if (c<1)
812: f = 0;
813: else
814: f = ctoi(ap[1]);
815: if (f>=10 || f<0) {
816: curfile = NULL;
817: return;
818: }
819: tempname[7] = 'a' + f;
820: if (olist[f] || (olist[f]=fopen(tempname, WRITE))) {
821: curout = f;
822: curfile = olist[f];
823: }
824: }
825:
826: doundiv(ap, c)
827: char **ap;
828: {
829: register FILE *fp;
830: register int i, ch;
831: int j;
832:
833: if (c == 0) {
834: for (i=1; i<10; i++) {
835: if (i==curout || olist[i]==NULL)
836: continue;
837: fclose(olist[i]);
838: tempname[7] = 'a'+i;
839: fp = fopen(tempname, READ);
840: if (curfile != NULL)
841: while ((ch = getc(fp)) > 0)
842: putc(ch, curfile);
843: fclose(fp);
844: unlink(tempname);
845: olist[i] = NULL;
846: }
847:
848: }
849: else {
850: for (j = 1; j <= c; j++) {
851: i = ctoi(*++ap);
852: if (i<1 || i>9 || i==curout || olist[i]==NULL)
853: continue;
854: fclose(olist[i]);
855: tempname[7] = 'a'+i;
856: fp = fopen(tempname, READ);
857: if (curfile != NULL)
858: while ((ch = getc(fp)) > 0)
859: putc(ch, curfile);
860: fclose(fp);
861: unlink(tempname);
862: olist[i] = NULL;
863: }
864: }
865: }
866:
867: dodivnum(ap, c)
868: char **ap;
869: {
870: putnum((long) curout);
871: }
872:
873: dodnl(ap, c)
874: char **ap;
875: {
876: register t;
877:
878: while ((t=getchr())!='\n' && t>=0)
879: ;
880: }
881:
882: long ctol(str)
883: register char *str;
884: {
885: register sign;
886: long num;
887:
888: while (*str==' ' || *str=='\t' || *str=='\n')
889: str++;
890: num = 0;
891: if (*str == '-') {
892: sign = -1;
893: str++;
894: }
895: else
896: sign = 1;
897: while (*str>='0' && *str<='9')
898: num = num*10 + *str++ - '0';
899: return(sign * num);
900: }
901:
902: ctoi(s)
903: char *s;
904: {
905: return(ctol(s));
906: }
907:
908: min(a, b)
909: {
910: if (a>b)
911: return(b);
912: return(a);
913: }
914:
915: max(a, b)
916: {
917: if (a>b)
918: return(a);
919: return(b);
920: }