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
printout defined in line 392; used 1 times
quit defined in line 413; used 12 times
split defined in line 187; used 1 times

Defined variables

beginnest defined in line 183; used 7 times
copyright defined in line 8; never used
inbrac defined in line 180; used 3 times
incom defined in line 178; used 11 times
incur defined in line 179; used 3 times
inprog defined in line 182; used 4 times
instr defined in line 181; used 3 times
labelopen defined in line 40; used 2 times
names defined in line 37; used 11 times
nest defined in line 184; used 15 times
paren_level defined in line 185; used 6 times
sccsid defined in line 14; never used

Defined macros

BODYFILE defined in line 27; used 3 times
CONSTFILE defined in line 23; used 3 times
FALSE defined in line 31; used 20 times
LABELFILE defined in line 22; used 3 times
MAXINCL defined in line 32; used 2 times
MAXNAM defined in line 33; used 3 times
NUMFILES defined in line 28; used 5 times
PRGFILE defined in line 21; used 3 times
RTNFILE defined in line 26; used 4 times
TMPNAME defined in line 34; used 7 times
TRUE defined in line 30; used 16 times
TYPEFILE defined in line 24; used 3 times
VARFILE defined in line 25; used 3 times
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2154
Valid CSS Valid XHTML 1.0 Strict