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

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

unix.superglobalmegacorp.com

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