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