Annotation of 42BSD/ucb/pascal/utilities/pmerge.c, revision 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.