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