|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)pmerge.c 1.3 12/7/82";
4:
5: #include <ctype.h>
6: #include <stdio.h>
7: #include <signal.h>
8:
9: #define PRGFILE 0
10: #define LABELFILE 1
11: #define CONSTFILE 2
12: #define TYPEFILE 3
13: #define VARFILE 4
14: #define RTNFILE 5
15: #define BODYFILE 6
16: #define NUMFILES 7
17:
18: #define TRUE 1
19: #define FALSE 0
20: #define MAXINCL 9
21: #define MAXNAM 75
22: #define TMPNAME "/usr/tmp/MGXXXXXX"
23:
24: FILE *files[NUMFILES];
25: char *names[NUMFILES];
26: FILE *curfile; /* current output file */
27: FILE *fopen();
28: char labelopen = FALSE, constopen = FALSE, typeopen = FALSE, varopen = FALSE;
29: char *mktemp();
30: char *malloc();
31:
32: /*
33: * Remove temporary files if interrupted
34: */
35: onintr()
36: {
37: int i;
38:
39: for (i = 0; i < NUMFILES; i++)
40: if (files[i] != NULL)
41: unlink(names[i]);
42: }
43:
44: /*
45: * Program to merge separately compiled pascal modules into a
46: * single standard Pascal program.
47: */
48: main(argc, argv)
49: long argc;
50: char **argv;
51: {
52: FILE *incl[MAXINCL]; /* include stack */
53: long inclcnt = 0; /* incl index */
54: char *name[MAXNAM]; /* include names seen so far */
55: long namcnt = 0; /* next name ptr slot available */
56: char *nambuf; /* string table for names */
57: char line[BUFSIZ]; /* input line buffer */
58: char *next; /* next name space available */
59: FILE *input = stdin; /* current input file */
60: long ac = 0; /* argv index */
61: char **cpp, *cp, *fp;/* char ptrs */
62: char quote; /* include quote character */
63: int i; /* index var */
64:
65: for (i = 0; i < MAXNAM ; i++)
66: name[i] = 0;
67:
68: signal(SIGINT, onintr);
69:
70: curfile = files[PRGFILE] = fopen(names[PRGFILE] = mktemp(TMPNAME), "w");
71: files[LABELFILE] = fopen(names[LABELFILE] = mktemp(TMPNAME), "w");
72: files[CONSTFILE] = fopen(names[CONSTFILE] = mktemp(TMPNAME), "w");
73: files[TYPEFILE] = fopen(names[TYPEFILE] = mktemp(TMPNAME), "w");
74: files[VARFILE] = fopen(names[VARFILE] = mktemp(TMPNAME), "w");
75: files[RTNFILE] = fopen(names[RTNFILE] = mktemp(TMPNAME), "w");
76: files[BODYFILE] = fopen(names[BODYFILE] = mktemp(TMPNAME), "w");
77:
78: for (i = 0; i < NUMFILES; i++)
79: if (files[i] == NULL)
80: quit(names[i]);
81: if ((nambuf = malloc(BUFSIZ)) == NULL) {
82: fputs("no space for string table\n", stderr);
83: quit(NULL);
84: }
85: next = nambuf;
86: name[namcnt] = next;
87: for(;;) {
88: if (inclcnt > 0) {
89: inclcnt--;
90: fclose(input);
91: input = incl[inclcnt];
92: } else if (++ac < argc) {
93: input = freopen(argv[ac], "r", input);
94: if (input == NULL)
95: quit(argv[ac]);
96: } else {
97: printout();
98: onintr();
99: exit(0);
100: }
101: fgets(line, BUFSIZ, input);
102: while (!feof(input)) {
103: if (line[0] != '#') {
104: split(line);
105: fgets(line, BUFSIZ, input);
106: continue;
107: }
108: for (cp = &line[1]; isspace(*cp); cp++)
109: /* void */;
110: if (strcmpn("include", cp, 7))
111: goto bad;
112: for (cp += 7; isspace(*cp); cp++)
113: /* void */;
114: if (*cp != '\'' && *cp != '"')
115: goto bad;
116: if (&nambuf[BUFSIZ] < next + strlen(cp)) {
117: if ((nambuf = malloc(BUFSIZ)) == NULL) {
118: fputs("no space for string table\n",
119: stderr);
120: quit(NULL);
121: }
122: next = nambuf;
123: name[namcnt] = next;
124: }
125: for (fp = next, quote = *cp++;
126: *cp != '\0' && *cp != quote; )
127: *fp++ = *cp++;
128: if (*cp != quote &&
129: (fp[-1] != 'i' || fp[-1] != 'h') &&
130: (fp[-2] != '.'))
131: goto bad;
132: *fp++ = '\0';
133: for (cpp = name; *cpp < next && strcmp(*cpp, next); )
134: cpp++;
135: if (*cpp == next) {
136: if (inclcnt == MAXINCL) {
137: fputs("include table overflow\n",
138: stderr);
139: quit(NULL);
140: }
141: if (++namcnt == MAXNAM) {
142: fputs("include name table overflow\n",
143: stderr);
144: quit(NULL);
145: }
146: incl[inclcnt] = input;
147: inclcnt++;
148: input = fopen(next, "r");
149: if (input == NULL)
150: quit(next);
151: next = fp;
152: name[namcnt] = next;
153: }
154: fgets(line, BUFSIZ, input);
155: }
156: }
157: bad:
158: fputs("bad include format:", stderr);
159: fputs(line, stderr);
160: quit(NULL);
161: }
162:
163: /*
164: * Split up output into the approprite files
165: */
166: char incom = FALSE; /* TRUE => in comment */
167: char incur = FALSE; /* TRUE => in (* *) style comment */
168: char inbrac = FALSE; /* TRUE => in { } style comment */
169: char instr = FALSE; /* TRUE => in quoted string */
170: char inprog = FALSE; /* TRUE => program statement has been found */
171: int beginnest = 0; /* routine nesting level */
172: int nest = 0; /* begin block nesting level */
173: int paren_level = 0; /* nesting level of parentheses */
174:
175: split(line)
176: char *line;
177: {
178: char ch1, *cp; /* input window */
179: char *word; /* ptr to current word */
180: int len; /* length of current word */
181: char prt = TRUE; /* TRUE => print current word */
182:
183: ch1 = ' ';
184: cp = line;
185: while (*cp) {
186: switch(*cp) {
187: case '(':
188: if (incom)
189: break;
190: if (*(cp+1) == '*') {
191: fputc(*cp, curfile);
192: cp++;
193: incom = TRUE;
194: incur = TRUE;
195: } else {
196: paren_level++;
197: }
198: break;
199: case ')':
200: if (incur && ch1 == '*') {
201: incom = FALSE;
202: incur = FALSE;
203: } else if (!incom) {
204: paren_level--;
205: }
206: break;
207: case '{':
208: if (!incom) {
209: inbrac = TRUE;
210: incom = TRUE;
211: }
212: break;
213: case '}':
214: if (inbrac) {
215: inbrac = FALSE;
216: incom = FALSE;
217: }
218: break;
219: case '\'':
220: if (!incom) {
221: incom = TRUE;
222: instr = TRUE;
223: } else if (instr) {
224: incom = FALSE;
225: instr = FALSE;
226: }
227: break;
228: }
229: if (incom || !isalpha(*cp)) {
230: fputc(*cp, curfile);
231: ch1 = *cp++;
232: continue;
233: }
234: word = cp;
235: while (isalnum(*cp))
236: cp++;
237: len = cp - word;
238: switch (*word) {
239: case 'b':
240: if (len == 5 && !strcmpn(word, "begin", 5)) {
241: if (nest == 0 && beginnest == 0) {
242: if (inprog != 1) {
243: fprintf(stderr,
244: "improper program body");
245: quit(NULL);
246: }
247: curfile = files[BODYFILE];
248: } else {
249: beginnest++;
250: }
251: }
252: break;
253: case 'c':
254: if (len == 4 && !strcmpn(word, "case", 4)) {
255: if (beginnest > 0) {
256: beginnest++;
257: }
258: break;
259: }
260: if (len == 5 && !strcmpn(word, "const", 5)) {
261: if (nest == 0) {
262: prt = FALSE;
263: if (!constopen) {
264: constopen = TRUE;
265: prt = TRUE;
266: }
267: curfile = files[CONSTFILE];
268: }
269: }
270: break;
271: case 'e':
272: if (len == 3 && !strcmpn(word, "end", 3)) {
273: if (beginnest == 1) {
274: nest--;
275: }
276: if (beginnest > 0) {
277: beginnest--;
278: }
279: if (nest < 0) {
280: if (inprog == 1) {
281: inprog = 0;
282: nest = 0;
283: } else {
284: fprintf(stderr, "too many end statements");
285: quit(NULL);
286: }
287: }
288: break;
289: }
290: if (len == 8 && !strcmpn(word, "external", 8)) {
291: fputs("forward", curfile);
292: prt = FALSE;
293: if (paren_level == 0) {
294: nest--;
295: }
296: }
297: break;
298: case 'f':
299: if (len == 8 && !strcmpn(word, "function", 8)) {
300: if (nest == 0) {
301: curfile = files[RTNFILE];
302: }
303: if (paren_level == 0) {
304: nest++;
305: }
306: break;
307: }
308: if (len == 7 && !strcmpn(word, "forward", 7)) {
309: if (paren_level == 0) {
310: nest--;
311: }
312: }
313: break;
314: case 'l':
315: if (len == 5 && !strcmpn(word, "label", 5)) {
316: if (nest == 0) {
317: prt = FALSE;
318: if (!labelopen) {
319: labelopen = TRUE;
320: prt = TRUE;
321: }
322: curfile = files[LABELFILE];
323: }
324: }
325: break;
326: case 'p':
327: if (len == 9 && !strcmpn(word, "procedure", 9)) {
328: if (nest == 0) {
329: curfile = files[RTNFILE];
330: }
331: if (paren_level == 0) {
332: nest++;
333: }
334: break;
335: }
336: if (len == 7 && !strcmpn(word, "program", 7)) {
337: if (nest != 0) {
338: fprintf(stderr, "improper program nesting");
339: quit(NULL);
340: }
341: inprog = 1;
342: curfile = files[PRGFILE];
343: }
344: break;
345: case 't':
346: if (len == 4 && !strcmpn(word, "type", 4)) {
347: if (nest == 0) {
348: prt = FALSE;
349: if (!typeopen) {
350: typeopen = TRUE;
351: prt = TRUE;
352: }
353: curfile = files[TYPEFILE];
354: }
355: }
356: break;
357: case 'v':
358: if (len == 3 && !strcmpn(word, "var", 3)) {
359: if (nest == 0) {
360: prt = FALSE;
361: if (!varopen) {
362: varopen = TRUE;
363: prt = TRUE;
364: }
365: curfile = files[VARFILE];
366: }
367: }
368: break;
369: }
370: if (prt)
371: fprintf(curfile, "%.*s", len, word);
372: prt = TRUE;
373: ch1 = ' ';
374: }
375: }
376:
377: /*
378: * Print out the merged result
379: */
380: printout()
381: {
382: FILE *fp;
383: int i;
384: char ch;
385:
386: for(i = 0; i < NUMFILES; i++) {
387: fp = freopen(names[i], "r", files[i]);
388: if (fp == NULL)
389: quit(names[i]);
390: ch = getc(fp);
391: while (!feof(fp)) {
392: putc(ch,stdout);
393: ch = getc(fp);
394: }
395: }
396: }
397:
398: /*
399: * Die gracefully
400: */
401: quit(fp)
402: char *fp;
403: {
404: if (fp != NULL)
405: perror(fp);
406: onintr();
407: exit(1);
408: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.