# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/utilities/pmerge.c

##### Functions

    main              X
    onintr            X
    printout          X
    quit              X
    split             X

##### Variables

    beginnest         X
    copyright         X
    inbrac            X
    incom             X
    incur             X
    inprog            X
    instr             X
    labelopen         X
    names             X
    nest              X
    paren_level       X

##### Macros

    BODYFILE          X
    CONSTFILE         X
    FALSE             X
    LABELFILE         X
    MAXINCL           X
    MAXNAM            X
    NUMFILES          X
    PRGFILE           X
    RTNFILE           X
    TMPNAME           X
    TRUE              X
    TYPEFILE          X
    VARFILE           X

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

#### Defined functions

main defined in line 60; never used
onintr defined in line 47; used 3 times

- in line 80, 110, 418

printout defined in line 392; used 1 times

- in line 109

quit defined in line 413; used 12 times

- in line 92-95(2), 107, 132, 151-156(2), 162, 172, 257, 297, 351, 401

split defined in line 187; used 1 times

- in line 116

#### Defined variables

beginnest defined in line 183; used 7 times

- in line 253, 261, 267-268(2), 285-289(3)

copyright defined in line 8; never used
inbrac defined in line 180; used 3 times

- in line 221-227(3)

incom defined in line 178; used 11 times

- in line 200-205(2), 213-222(4), 228-241(5)

incur defined in line 179; used 3 times

- in line 206, 212-214(2)

inprog defined in line 182; used 4 times

- in line 254, 292-293(2), 353

instr defined in line 181; used 3 times

- in line 234-237(3)

labelopen defined in line 40; used 2 times

- in line 330-331(2)

names defined in line 37; used 11 times

- in line 53, 82-92(8), 399-401(2)

nest defined in line 184; used 15 times

- in line 253, 273, 286-294(3), 306, 312-316(2), 322, 328, 340-349(3), 359, 371

paren_level defined in line 185; used 6 times

- in line 208, 216, 305, 315, 321, 343

sccsid defined in line 14; never used

#### Defined macros

BODYFILE defined in line 27; used 3 times

- in line 88(2), 259

CONSTFILE defined in line 23; used 3 times

- in line 84(2), 279

FALSE defined in line 31; used 20 times

- in line 40(4), 178-182(5), 213-214(2), 227-228(2), 236-237(2), 274, 304, 329, 360, 372

LABELFILE defined in line 22; used 3 times

- in line 83(2), 334

MAXINCL defined in line 32; used 2 times

- in line 64, 148

MAXNAM defined in line 33; used 3 times

- in line 66, 77, 153

NUMFILES defined in line 28; used 5 times

- in line 36-37(2), 51, 90, 398

PRGFILE defined in line 21; used 3 times

- in line 82(2), 354

RTNFILE defined in line 26; used 4 times

- in line 87(2), 313, 341

TMPNAME defined in line 34; used 7 times

- in line 82-88(7)

TRUE defined in line 30; used 16 times

- in line 193, 205-206(2), 221-222(2), 233-234(2), 276-277(2), 331-332(2), 362-363(2), 374-375(2), 384

TYPEFILE defined in line 24; used 3 times

- in line 85(2), 365

VARFILE defined in line 25; used 3 times

- in line 86(2), 377

Last modified: 1985-06-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2514 |