|
|
1.1 root 1: /*
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Ozan Yigit.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)eval.c 5.3 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * eval.c
29: * Facility: m4 macro processor
30: * by: oz
31: */
32:
33: #include "mdef.h"
34: #include "extr.h"
35:
36: extern ndptr lookup();
37: extern char *strsave();
38: extern char *mktemp();
39:
40: /*
41: * eval - evaluate built-in macros.
42: * argc - number of elements in argv.
43: * argv - element vector :
44: * argv[0] = definition of a user
45: * macro or nil if built-in.
46: * argv[1] = name of the macro or
47: * built-in.
48: * argv[2] = parameters to user-defined
49: * . macro or built-in.
50: * .
51: *
52: * Note that the minimum value for argc is 3. A call in the form
53: * of macro-or-builtin() will result in:
54: * argv[0] = nullstr
55: * argv[1] = macro-or-builtin
56: * argv[2] = nullstr
57: *
58: */
59:
60: eval (argv, argc, td)
61: register char *argv[];
62: register int argc;
63: register int td;
64: {
65: register int c, n;
66: static int sysval;
67:
68: #ifdef DEBUG
69: printf("argc = %d\n", argc);
70: for (n = 0; n < argc; n++)
71: printf("argv[%d] = %s\n", n, argv[n]);
72: #endif
73: /*
74: * if argc == 3 and argv[2] is null,
75: * then we have macro-or-builtin() type call.
76: * We adjust argc to avoid further checking..
77: *
78: */
79: if (argc == 3 && !*(argv[2]))
80: argc--;
81:
82: switch (td & ~STATIC) {
83:
84: case DEFITYPE:
85: if (argc > 2)
86: dodefine(argv[2], (argc > 3) ? argv[3] : null);
87: break;
88:
89: case PUSDTYPE:
90: if (argc > 2)
91: dopushdef(argv[2], (argc > 3) ? argv[3] : null);
92: break;
93:
94: case DUMPTYPE:
95: dodump(argv, argc);
96: break;
97:
98: case EXPRTYPE:
99: /*
100: * doexpr - evaluate arithmetic expression
101: *
102: */
103: if (argc > 2)
104: pbnum(expr(argv[2]));
105: break;
106:
107: case IFELTYPE:
108: if (argc > 4)
109: doifelse(argv, argc);
110: break;
111:
112: case IFDFTYPE:
113: /*
114: * doifdef - select one of two alternatives based
115: * on the existence of another definition
116: */
117: if (argc > 3) {
118: if (lookup(argv[2]) != nil)
119: pbstr(argv[3]);
120: else if (argc > 4)
121: pbstr(argv[4]);
122: }
123: break;
124:
125: case LENGTYPE:
126: /*
127: * dolen - find the length of the argument
128: *
129: */
130: if (argc > 2)
131: pbnum((argc > 2) ? strlen(argv[2]) : 0);
132: break;
133:
134: case INCRTYPE:
135: /*
136: * doincr - increment the value of the argument
137: *
138: */
139: if (argc > 2)
140: pbnum(atoi(argv[2]) + 1);
141: break;
142:
143: case DECRTYPE:
144: /*
145: * dodecr - decrement the value of the argument
146: *
147: */
148: if (argc > 2)
149: pbnum(atoi(argv[2]) - 1);
150: break;
151:
152: case SYSCTYPE:
153: /*
154: * dosys - execute system command
155: *
156: */
157: if (argc > 2)
158: sysval = system(argv[2]);
159: break;
160:
161: case SYSVTYPE:
162: /*
163: * dosysval - return value of the last system call.
164: *
165: */
166: pbnum(sysval);
167: break;
168:
169: case INCLTYPE:
170: if (argc > 2)
171: if (!doincl(argv[2])) {
172: fprintf(stderr,"m4: %s: ",argv[2]);
173: error("cannot open for read.");
174: }
175: break;
176:
177: case SINCTYPE:
178: if (argc > 2)
179: (void) doincl(argv[2]);
180: break;
181: #ifdef EXTENDED
182: case PASTTYPE:
183: if (argc > 2)
184: if (!dopaste(argv[2])) {
185: fprintf(stderr,"m4: %s: ",argv[2]);
186: error("cannot open for read.");
187: }
188: break;
189:
190: case SPASTYPE:
191: if (argc > 2)
192: (void) dopaste(argv[2]);
193: break;
194: #endif
195: case CHNQTYPE:
196: dochq(argv, argc);
197: break;
198:
199: case CHNCTYPE:
200: dochc(argv, argc);
201: break;
202:
203: case SUBSTYPE:
204: /*
205: * dosub - select substring
206: *
207: */
208: if (argc > 3)
209: dosub(argv,argc);
210: break;
211:
212: case SHIFTYPE:
213: /*
214: * doshift - push back all arguments except the
215: * first one (i.e. skip argv[2])
216: */
217: if (argc > 3) {
218: for (n = argc-1; n > 3; n--) {
219: putback(rquote);
220: pbstr(argv[n]);
221: putback(lquote);
222: putback(',');
223: }
224: putback(rquote);
225: pbstr(argv[3]);
226: putback(lquote);
227: }
228: break;
229:
230: case DIVRTYPE:
231: if (argc > 2 && (n = atoi(argv[2])) != 0)
232: dodiv(n);
233: else {
234: active = stdout;
235: oindex = 0;
236: }
237: break;
238:
239: case UNDVTYPE:
240: doundiv(argv, argc);
241: break;
242:
243: case DIVNTYPE:
244: /*
245: * dodivnum - return the number of current
246: * output diversion
247: *
248: */
249: pbnum(oindex);
250: break;
251:
252: case UNDFTYPE:
253: /*
254: * doundefine - undefine a previously defined
255: * macro(s) or m4 keyword(s).
256: */
257: if (argc > 2)
258: for (n = 2; n < argc; n++)
259: remhash(argv[n], ALL);
260: break;
261:
262: case POPDTYPE:
263: /*
264: * dopopdef - remove the topmost definitions of
265: * macro(s) or m4 keyword(s).
266: */
267: if (argc > 2)
268: for (n = 2; n < argc; n++)
269: remhash(argv[n], TOP);
270: break;
271:
272: case MKTMTYPE:
273: /*
274: * dotemp - create a temporary file
275: *
276: */
277: if (argc > 2)
278: pbstr(mktemp(argv[2]));
279: break;
280:
281: case TRNLTYPE:
282: /*
283: * dotranslit - replace all characters in the
284: * source string that appears in
285: * the "from" string with the corresponding
286: * characters in the "to" string.
287: *
288: */
289: if (argc > 3) {
290: char temp[MAXTOK];
291: if (argc > 4)
292: map(temp, argv[2], argv[3], argv[4]);
293: else
294: map(temp, argv[2], argv[3], null);
295: pbstr(temp);
296: }
297: else
298: if (argc > 2)
299: pbstr(argv[2]);
300: break;
301:
302: case INDXTYPE:
303: /*
304: * doindex - find the index of the second argument
305: * string in the first argument string.
306: * -1 if not present.
307: */
308: pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
309: break;
310:
311: case ERRPTYPE:
312: /*
313: * doerrp - print the arguments to stderr file
314: *
315: */
316: if (argc > 2) {
317: for (n = 2; n < argc; n++)
318: fprintf(stderr,"%s ", argv[n]);
319: fprintf(stderr, "\n");
320: }
321: break;
322:
323: case DNLNTYPE:
324: /*
325: * dodnl - eat-up-to and including newline
326: *
327: */
328: while ((c = gpbc()) != '\n' && c != EOF)
329: ;
330: break;
331:
332: case M4WRTYPE:
333: /*
334: * dom4wrap - set up for wrap-up/wind-down activity
335: *
336: */
337: m4wraps = (argc > 2) ? strsave(argv[2]) : null;
338: break;
339:
340: case EXITTYPE:
341: /*
342: * doexit - immediate exit from m4.
343: *
344: */
345: exit((argc > 2) ? atoi(argv[2]) : 0);
346: break;
347:
348: case DEFNTYPE:
349: if (argc > 2)
350: for (n = 2; n < argc; n++)
351: dodefn(argv[n]);
352: break;
353:
354: default:
355: error("m4: major botch in eval.");
356: break;
357: }
358: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.