Annotation of 42BSD/ucb/pascal/utilities/pmerge.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.