|
|
1.1 root 1: #include "stdio.h"
2: #include "sys/types.h"
3: #include "sys/stat.h"
4: #include "m4.h"
5:
6: #define arg(n) (c<(n)? nullstr: ap[n])
7:
8: dochcom(ap,c)
9: char **ap;
10: {
11: register char *l = arg(1);
12: register char *r = arg(2);
13:
14: if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
15: error2("comment marker longer than %d chars",MAXSYM);
16: strcpy(lcom,l);
17: strcpy(rcom,*r?r:"\n");
18: }
19:
20: docq(ap,c)
21: register char **ap;
22: {
23: register char *l = arg(1);
24: register char *r = arg(2);
25:
26: if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
27: error2("quote marker longer than %d chars", MAXSYM);
28:
29: if (c<=1 && !*l) {
30: l = "`";
31: r = "'";
32: } else if (c==1) {
33: r = l;
34: }
35:
36: strcpy(lquote,l);
37: strcpy(rquote,r);
38: }
39:
40: dodecr(ap,c)
41: char **ap;
42: {
43: pbnum(ctol(arg(1))-1);
44: }
45:
46: dodef(ap,c)
47: char **ap;
48: {
49: def(ap,c,NOPUSH);
50: }
51:
52: def(ap,c,mode)
53: register char **ap;
54: {
55: register char *s;
56:
57: if (c<1)
58: return;
59:
60: s = ap[1];
61: if (isalpha(*s))
62: while (alphanum(*++s))
63: ;
64: if (*s || s==ap[1])
65: error("bad macro name");
66:
67: if (strcmp(ap[1],ap[2])==0)
68: error("macro defined as itself");
69: install(ap[1],arg(2),mode);
70: }
71:
72: dodefn(ap,c)
73: register char **ap;
74: register c;
75: {
76: register char *d;
77:
78: while (c > 0)
79: if ((d = lookup(ap[c--])->def) != NULL) {
80: putbak(*rquote);
81: while (*d)
82: putbak(*d++);
83: putbak(*lquote);
84: }
85: }
86:
87: dodiv(ap,c)
88: register char **ap;
89: {
90: register int f;
91:
92: f = atoi(arg(1));
93: if (f>=10 || f<0) {
94: cf = NULL;
95: ofx = f;
96: return;
97: }
98: tempname[7] = 'a'+f;
99: if (ofile[f] || (ofile[f]=xfopen(tempname,"w"))) {
100: ofx = f;
101: cf = ofile[f];
102: }
103: }
104:
105: dodivnum(ap,c)
106: {
107: pbnum((long) ofx);
108: }
109:
110: dodnl(ap,c)
111: char *ap;
112: {
113: register t;
114:
115: while ((t=getchr())!='\n' && t!=EOF)
116: ;
117: }
118:
119: dodump(ap,c)
120: char **ap;
121: {
122: register struct nlist *np;
123: register i;
124:
125: if (c > 0)
126: while (c--) {
127: if ((np = lookup(*++ap))->name != NULL)
128: dump(np->name,np->def);
129: }
130: else
131: for (i=0; i<hshsize; i++)
132: for (np=hshtab[i]; np!=NULL; np=np->next)
133: dump(np->name,np->def);
134: }
135:
136: dump(name,def)
137: register char *name,
138: *def;
139: {
140: register char *s = def;
141:
142: fprintf(stderr,"%s:\t",name);
143:
144: while (*s++)
145: ;
146: --s;
147:
148: while (s>def)
149: if (*--s&~LOW7)
150: fprintf(stderr,"<%s>",barray[*s&LOW7].bname);
151: else
152: fputc(*s,stderr);
153:
154: fputc('\n',stderr);
155: }
156:
157: doerrp(ap,c)
158: char **ap;
159: {
160: if (c > 0)
161: fprintf(stderr,"%s",ap[1]);
162: }
163:
164: long evalval; /* return value from yacc stuff */
165: char *pe; /* used by grammar */
166: doeval(ap,c)
167: char **ap;
168: {
169: register base = atoi(arg(2));
170: register pad = atoi(arg(3));
171:
172: evalval = 0;
173: if (c > 0) {
174: pe = ap[1];
175: if (yyparse()!=0)
176: error("invalid expression");
177: }
178: pbnbr(evalval, base>0?base:10, pad>0?pad:1);
179: }
180:
181: doexit(ap,c)
182: char **ap;
183: {
184: delexit(atoi(arg(1)));
185: }
186:
187: doif(ap,c)
188: register char **ap;
189: {
190: if (c < 3)
191: return;
192: while (c >= 3) {
193: if (strcmp(ap[1],ap[2])==0) {
194: pbstr(ap[3]);
195: return;
196: }
197: c -= 3;
198: ap += 3;
199: }
200: if (c > 0)
201: pbstr(ap[1]);
202: }
203:
204: doifdef(ap,c)
205: char **ap;
206: {
207: if (c < 2)
208: return;
209:
210: while (c >= 2) {
211: if (lookup(ap[1])->name != NULL) {
212: pbstr(ap[2]);
213: return;
214: }
215: c -= 2;
216: ap += 2;
217: }
218:
219: if (c > 0)
220: pbstr(ap[1]);
221: }
222:
223: doincl(ap,c)
224: char **ap;
225: {
226: incl(ap,c,1);
227: }
228:
229: incl(ap,c,noisy)
230: register char **ap;
231: {
232: if (c>0 && strlen(ap[1])>0) {
233: if (ifx >= 9)
234: error("input file nesting too deep (9)");
235: if ((ifile[++ifx]=fopen(ap[1],"r"))==NULL){
236: --ifx;
237: if (noisy)
238: error(badfile);
239: } else {
240: ipstk[ifx] = ipflr = ip;
241: setfname(ap[1]);
242: }
243: }
244: }
245:
246: doincr(ap,c)
247: char **ap;
248: {
249: pbnum(ctol(arg(1))+1);
250: }
251:
252: doindex(ap,c)
253: char **ap;
254: {
255: register char *subj = arg(1);
256: register char *obj = arg(2);
257: register i;
258:
259: for (i=0; *subj; ++i)
260: if (leftmatch(subj++,obj)) {
261: pbnum( (long) i );
262: return;
263: }
264:
265: pbnum( (long) -1 );
266: }
267:
268: leftmatch(str,substr)
269: register char *str;
270: register char *substr;
271: {
272: while (*substr)
273: if (*str++ != *substr++)
274: return (0);
275:
276: return (1);
277: }
278:
279: dolen(ap,c)
280: char **ap;
281: {
282: pbnum((long) strlen(arg(1)));
283: }
284:
285: domake(ap,c)
286: char **ap;
287: {
288: if (c > 0)
289: pbstr(mktemp(ap[1]));
290: }
291:
292: dopopdef(ap,c)
293: char **ap;
294: {
295: register i;
296:
297: for (i=1; i<=c; ++i)
298: undef(ap[i]);
299: }
300:
301: dopushdef(ap,c)
302: char **ap;
303: {
304: def(ap,c,PUSH);
305: }
306:
307: doshift(ap,c)
308: register char **ap;
309: register c;
310: {
311: if (c <= 1)
312: return;
313:
314: for (;;) {
315: pbstr(rquote);
316: pbstr(ap[c--]);
317: pbstr(lquote);
318:
319: if (c <= 1)
320: break;
321:
322: pbstr(",");
323: }
324: }
325:
326: dosincl(ap,c)
327: char **ap;
328: {
329: incl(ap,c,0);
330: }
331:
332: dosubstr(ap,c)
333: register char **ap;
334: {
335: char *str;
336: int inlen, outlen;
337: register offset, ix;
338:
339: inlen = strlen(str=arg(1));
340: offset = atoi(arg(2));
341:
342: if (offset<0 || offset>=inlen)
343: return;
344:
345: outlen = c>=3? atoi(ap[3]): inlen;
346: ix = min(offset+outlen,inlen);
347:
348: while (ix > offset)
349: putbak(str[--ix]);
350: }
351:
352: dosyscmd(ap,c)
353: char **ap;
354: {
355: sysrval = 0;
356: if (c > 0) {
357: fflush(stdout);
358: sysrval = system(ap[1]);
359: }
360: }
361:
362: dosysval(ap,c)
363: char **ap;
364: {
365: pbnum((long) (sysrval>>8));
366: }
367:
368: dotransl(ap,c)
369: char **ap;
370: {
371: char *sink, *fr, *sto;
372: register char *source, *to;
373:
374: if (c<1)
375: return;
376:
377: sink = ap[1];
378: fr = arg(2);
379: sto = arg(3);
380:
381: for (source = ap[1]; *source; source++) {
382: register char *i;
383: to = sto;
384: for (i = fr; *i; ++i) {
385: if (*source==*i)
386: break;
387: if (*to)
388: ++to;
389: }
390: if (*i) {
391: if (*to)
392: *sink++ = *to;
393: } else
394: *sink++ = *source;
395: }
396: *sink = EOS;
397: pbstr(ap[1]);
398: }
399:
400: dotroff(ap,c)
401: register char **ap;
402: {
403: register struct nlist *np;
404:
405: trace = 0;
406:
407: while (c > 0)
408: if ((np=lookup(ap[c--]))->name)
409: np->tflag = 0;
410: }
411:
412: dotron(ap,c)
413: register char **ap;
414: {
415: register struct nlist *np;
416:
417: trace = !*arg(1);
418:
419: while (c > 0)
420: if ((np=lookup(ap[c--]))->name)
421: np->tflag = 1;
422: }
423:
424: doundef(ap,c)
425: char **ap;
426: {
427: register i;
428:
429: for (i=1; i<=c; ++i)
430: while (undef(ap[i]))
431: ;
432: }
433:
434: undef(nam)
435: char *nam;
436: {
437: register struct nlist *np, *tnp;
438:
439: if ((np=lookup(nam))->name==NULL)
440: return 0;
441: tnp = hshtab[hshval]; /* lookup sets hshval */
442: if (tnp==np) /* it's in first place */
443: hshtab[hshval] = tnp->next;
444: else {
445: while (tnp->next != np)
446: tnp = tnp->next;
447:
448: tnp->next = np->next;
449: }
450: cfree(np->name);
451: cfree(np->def);
452: cfree(np);
453: return 1;
454: }
455:
456: doundiv(ap,c)
457: register char **ap;
458: {
459: register int i;
460:
461: if (c<=0)
462: for (i=1; i<10; i++)
463: undiv(i,OK);
464: else
465: while (--c >= 0)
466: undiv(atoi(*++ap),OK);
467: }
468:
469: dowrap(ap,c)
470: char **ap;
471: {
472: register char *a = arg(1);
473: extern char *xcalloc();
474:
475: if (Wrapstr)
476: cfree(Wrapstr);
477:
478: Wrapstr = xcalloc(strlen(a)+1,sizeof(char));
479: strcpy(Wrapstr,a);
480: }
481:
482: struct bs barray[] = {
483: dochcom, "changecom",
484: docq, "changequote",
485: dodecr, "decr",
486: dodef, "define",
487: dodefn, "defn",
488: dodiv, "divert",
489: dodivnum, "divnum",
490: dodnl, "dnl",
491: dodump, "dumpdef",
492: doerrp, "errprint",
493: doeval, "eval",
494: doexit, "m4exit",
495: doif, "ifelse",
496: doifdef, "ifdef",
497: doincl, "include",
498: doincr, "incr",
499: doindex, "index",
500: dolen, "len",
501: domake, "maketemp",
502: dopopdef, "popdef",
503: dopushdef, "pushdef",
504: doshift, "shift",
505: dosincl, "sinclude",
506: dosubstr, "substr",
507: dosyscmd, "syscmd",
508: dosysval, "sysval",
509: dotransl, "translit",
510: dotroff, "traceoff",
511: dotron, "traceon",
512: doundef, "undefine",
513: doundiv, "undivert",
514: dowrap, "m4wrap",
515: 0, 0
516: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.