|
|
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.