# 2.11BSD#431 - /usr/src/old/shortc/shortc.c

##### Functions

    doarg             X
    dump              X
    lookup            X
    main              X
    myalloc           X
    newname           X
    nextname          X
    process           X
    token             X
    truncname         X

##### Variables

    curarg            X
    parsepp           X
    read_file         X
    sedout            X
    symlen            X
    symtab            X

##### Macros

    HASHSIZ           X
    MAXLEN            X
    NOTSEEN           X
    SEEN              X
    SYMLEN            X
    TRUNC             X
    prefix            X
    trunc             X

##### struct's

    Symbol            X

##### typedef's

    symbol            X

       1: /*
       2:  * Produce a set of preprocessor defines which guarantee that all identifiers
       3:  * in the files are unique in the first symlen (default 7) characters.
       4:  * Include the output into each file (or into a common header file).  Since
       5:  * the symbols being redefined are ambiguous within symlen chars (that was the
       6:  * problem in the first place), the files must be compiled using a flexnames
       7:  * version of cpp.
       8:  *
       9:  * Lacking that, turn the output into a sed script and massage the source
      10:  * files.  In this case, you may need to specify -p to parse preprocessor
      11:  * lines, but watch for things like include-file names.  If using cpp,
      12:  * preprocessor symbols should be weeded out by hand; otherwise they will
      13:  * cause (innocuous) redefinition messages.
      14:  *
      15:  * Hacked by m.d. marquez to allow pipe into stdin and add -s (sed) option.
      16:  */
      17:
      18: #if !defined(lint) && !defined(pdp11)
      19: static char rcsid[] =
      20:     "$Header: shortc.c,v 1.2 88/09/06 01:30:58 bin Exp Locker: bin $";
      21: #endif
      22:
      23: #include <stdio.h>
      24: #include <ctype.h>
      25: #include <strings.h>
      26:
      27: #define SYMLEN  7           /* symbols must be unique within ... chars */
      28: #define MAXLEN  128         /* need a limit for tokenizing */
      29: #define HASHSIZ 512        /* power of 2; not an upper limit */
      30:
      31: typedef struct Symbol symbol;
      32: struct Symbol {
      33:     symbol  *link;          /* hash chain */
      34:     union {
      35:         char   *xprefix;   /* prefix for mapped name if flag > SEEN */
      36:         symbol *xtrunc;    /* symbol which truncates to this one
      37: 				  if flag == TRUNC */
      38:     } x;
      39:     char    flag;
      40:     char    inname[1];
      41: };
      42: #define prefix  x.xprefix
      43: #define trunc   x.xtrunc
      44: #define NOTSEEN 0           /* symbol never seen */
      45: #define TRUNC   1           /* trunc points to symbol which truncates to
      46: 			       this one */
      47: #define SEEN    2           /* there is no conflict with this symbol */
      48: /*              > SEEN */   /* prefix must be added to resolve conflict */
      49:
      50: symbol  *symtab[HASHSIZ];
      51:
      52: int     symlen  = SYMLEN;
      53: char    parsepp;            /* if set, parse preprocessor lines */
      54: int sedout = 0;     /* want sed output */
      55: int read_file = 0;      /* flag if read file arguments */
      56:
      57: symbol  *lookup();
      58: char    *token(), *truncname(), *curarg = "stdin";
      59: char    *myalloc();
      60:
      61: extern  char *malloc();
      62: extern  int  errno;
      63:
      64: /*
      65:  * entry point
      66:  */
      67: main(argc, argv)
      68: register argc;
      69: register char **argv;
      70: {
      71:     char    obuf[BUFSIZ];
      72:
      73:     setbuf(stdout, obuf);
      74:
      75:     while (--argc > 0)
      76:         doarg(*++argv);
      77:
      78:     if (!read_file)
      79:         process();
      80:
      81:     dump();
      82:     exit(0);
      83: }
      84:
      85: /*
      86:  * process one file or flag arg
      87:  */
      88: doarg(arg)
      89: char *arg;
      90: {
      91:     char    ibuf[BUFSIZ];
      92:
      93:     if (*arg == '-') {
      94:         arg++;
      95:         if (isdigit(*arg))
      96:         symlen = atoi(arg);
      97:         else if (*arg == 'p')
      98:         parsepp = 1;
      99:         else if (*arg == 's')
     100:         sedout = 1;
     101:         else {
     102:         fputs("usage: shortc [-symlen] [-s] [-p] file ...\n", stderr);
     103:         exit(1);
     104:         }
     105:         return;
     106:     }
     107:
     108:     if (freopen(arg, "r", stdin) == NULL) {
     109:         fprintf(stderr, "freopen(%s) err: %d\n", errno);
     110:         return;
     111:     }
     112:     setbuf(stdin, ibuf);
     113:
     114:     curarg = arg;
     115:     process();
     116:
     117:     read_file++;
     118: }
     119:
     120: process()
     121: {
     122:     register char *s;
     123:     register symbol *y;
     124:
     125:     while (s = token())
     126:         if ((y = lookup(s))->flag < SEEN)
     127:         newname(y);
     128: }
     129:
     130: /*
     131:  * pick a new non-colliding name
     132:  */
     133: newname(y)
     134: register symbol *y;
     135: {
     136:     register symbol *a;
     137:
     138:     /* repeat until no collision */
     139:     for (;;) {
     140:         /* pick another name */
     141:         nextname(y);
     142:         /* check its truncation for conflicts */
     143:         a = lookup(truncname(y));
     144:         if (a->flag == NOTSEEN)
     145:         break;
     146:         /*
     147: 	     * if this is an original symbol and it collides with another
     148: 	     * (maybe modified) symbol, fix the other one instead of this one
     149: 	     */
     150:         if (a->flag == TRUNC && y->flag == SEEN) {
     151:         newname(a->trunc);
     152:         break;
     153:         }
     154:         /* if already a short name, ok */
     155:         if (a == y)
     156:         return;
     157:     }
     158:     /* flag what this truncates to */
     159:     a->trunc = y;
     160:     a->flag = TRUNC;
     161: }
     162:
     163: /*
     164:  * find next possible name for this symbol
     165:  */
     166: nextname(y)
     167: register symbol *y;
     168: {
     169:     register char *s, *p;
     170:     register n;
     171:
     172:     switch (y->flag) {
     173:         case TRUNC:
     174:         /* if another symbol truncates to this one, fix it not to */
     175:         newname(y->trunc);
     176:         case NOTSEEN:
     177:         /* this symbol's name is available, so use it */
     178:         y->flag = SEEN;
     179:         return;
     180:     }
     181:     /* prefix++ in base 26 */
     182:     for (n = y->flag-SEEN, p = y->prefix, s = p+n; s > p; *s = 'A')
     183:         if (++*--s <= 'Z')     /* love that syntax */
     184:         return;
     185:
     186:     /* overflow; need new digit */
     187:     y->prefix = s = myalloc(n+2);
     188:     *s++ = 'A';
     189:     if (y->flag++ == SEEN)
     190:         *s = '\0';
     191:     else {
     192:         strcpy(s, p);
     193:         free(p);
     194:     }
     195: }
     196:
     197: /*
     198:  * return symbol name truncated to symlen chars
     199:  */
     200: char *
     201: truncname(y)
     202: register symbol *y;
     203: {
     204:     static char buf[MAXLEN+10];
     205:     register n = y->flag-SEEN;
     206:
     207:     /*
     208: 	 * sprintf(buf, "%.*s%.*s", n, y->prefix, symlen-n, y->inname);
     209: 	 */
     210:
     211:     strncpy(buf, y->prefix, n);
     212:     buf[n] = '\0';
     213:     strncat(buf, y->inname, symlen - n);
     214:
     215:     return buf;
     216: }
     217:
     218: /*
     219:  * find name in symbol table
     220:  */
     221: symbol *
     222: lookup(s)
     223: char *s;
     224: {
     225:     register h;
     226:
     227:     {
     228:         register char *p;
     229:         register c;
     230:
     231:         for (h = 0, p = s; (c = *p++);)
     232:         h += h + c;
     233:     }
     234:     {
     235:         register symbol *y, **yy;
     236:
     237:         for (y = *(yy = &symtab[h & HASHSIZ-1]);; y = y->link) {
     238:         if (!y) {
     239:             y = (symbol *)myalloc(sizeof *y + strlen(s));
     240:             strcpy(y->inname, s);
     241:             y->flag = NOTSEEN;
     242:             y->link = *yy;
     243:             *yy = y;
     244:             break;
     245:         }
     246:
     247:         if (strcmp(y->inname, s) == 0)
     248:             break;
     249:         }
     250:         return y;
     251:     }
     252: }
     253:
     254: /*
     255:  * output all mappings
     256:  */
     257: dump()
     258: {
     259:     register symbol *y;
     260:     register n;
     261:
     262:     for (n = HASHSIZ; --n >= 0;)
     263:         for (y = symtab[n]; y; y = y->link)
     264:         if (y->flag > SEEN) {
     265:             if (sedout)
     266:                 printf("/%s/s//%s%s/g\n", y->inname,
     267:                         y->prefix, y->inname);
     268:            else
     269:                 printf("#define %s %s%s\n", y->inname,
     270:                         y->prefix, y->inname);
     271:         }
     272: }
     273:
     274: /*
     275:  * return next interesting identifier
     276:  */
     277: char *
     278: token()
     279: {
     280:     register c, state = 0;
     281:     register char *p;
     282:     static char buf[MAXLEN+1];
     283:
     284:     for (p = buf; (c = getchar()) != EOF;) {
     285:         if (state)
     286:         switch (state) {
     287:         case '/':
     288:             if (c != '*') {
     289:             state = 0;
     290:             break;
     291:             }
     292:             state = c;
     293:             continue;
     294:
     295:         case 'S':
     296:             if (c == '/')
     297:             state = 0;
     298:             else
     299:             state = '*';
     300:         case '*':
     301:             if (c == state)
     302:             state = 'S';
     303:             continue;
     304:
     305:         default:
     306:             if (c == '\\')
     307:             (void) getchar();
     308:             else if (c == state)
     309:             state = 0;
     310:             continue;
     311:         }
     312:         if (isalnum(c) || c == '_') {
     313:         if (p < &buf[sizeof buf - 1])
     314:             *p++ = c;
     315:         continue;
     316:         }
     317:         if (p > buf) {
     318:         if (p-buf >= symlen && !isdigit(*buf)) {
     319:             *p = '\0';
     320:             ungetc(c, stdin);
     321:             return buf;
     322:         }
     323:         p = buf;
     324:         }
     325:         if (c == '"' || c == '\'' || c == '/')
     326:         state = c;
     327:         else if (c == '#' && !parsepp)
     328:         state = '\n';
     329:     }
     330:     return NULL;
     331: }
     332:
     333: /*
     334:  * malloc with error detection
     335:  */
     336: char *
     337: myalloc(n)
     338: {
     339:     register char *p;
     340:
     341:     if (!(p = malloc((unsigned)n))) {
     342:         fprintf(stderr, "Out of space in %s\n", curarg);
     343:         exit(1);
     344:     }
     345:     return p;
     346: }

#### Defined functions

doarg defined in line 88; used 1 times

- in line 76

dump defined in line 257; used 1 times

- in line 81

lookup defined in line 221; used 3 times

- in line 57, 126, 143

main defined in line 67; never used
myalloc defined in line 336; used 3 times

- in line 59, 187, 239

newname defined in line 133; used 3 times

- in line 127, 151, 175

nextname defined in line 166; used 1 times

- in line 141

process defined in line 120; used 2 times

- in line 79, 115

token defined in line 277; used 2 times

- in line 58, 125

truncname defined in line 200; used 2 times

- in line 58, 143

#### Defined variables

curarg defined in line 58; used 2 times

- in line 114, 342

parsepp defined in line 53; used 2 times

- in line 98, 327

rcsid defined in line 19; never used
read_file defined in line 55; used 2 times

- in line 78, 117

sedout defined in line 54; used 2 times

- in line 100, 265

symlen defined in line 52; used 3 times

- in line 96, 213, 318

symtab defined in line 50; used 2 times

- in line 237, 263

#### Defined struct's

Symbol defined in line 32; used 1 times

- in line 31

#### Defined typedef's

symbol defined in line 31; used 13 times

- in line 50, 57, 134, 167, 202, 221-36(3), 123, 136, 235-239(2), 259

#### Defined macros

HASHSIZ defined in line 29; used 3 times

- in line 50, 237, 262

MAXLEN defined in line 28; used 2 times

- in line 204, 282

NOTSEEN defined in line 44; used 2 times

- in line 144, 241

SEEN defined in line 47; used 7 times

- in line 126, 150, 178-182(2), 189, 205, 264

SYMLEN defined in line 27; used 1 times

- in line 52

TRUNC defined in line 45; used 2 times

- in line 150, 160

prefix defined in line 42; used 5 times

- in line 182-187(2), 211, 267-270(2)

trunc defined in line 43; used 3 times

- in line 151, 159, 175

Last modified: 1992-04-19 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1577 |