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
main defined in line 67; never used
myalloc defined in line 336; used 3 times
newname defined in line 133; used 3 times
nextname defined in line 166; used 1 times
process defined in line 120; used 2 times
token defined in line 277; used 2 times
truncname defined in line 200; used 2 times

Defined variables

curarg defined in line 58; used 2 times
parsepp defined in line 53; used 2 times
rcsid defined in line 19; never used
read_file defined in line 55; used 2 times
sedout defined in line 54; used 2 times
symlen defined in line 52; used 3 times
symtab defined in line 50; used 2 times

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

Defined macros

HASHSIZ defined in line 29; used 3 times
MAXLEN defined in line 28; used 2 times
NOTSEEN defined in line 44; used 2 times
SEEN defined in line 47; used 7 times
SYMLEN defined in line 27; used 1 times
  • in line 52
TRUNC defined in line 45; used 2 times
prefix defined in line 42; used 5 times
trunc defined in line 43; used 3 times
Last modified: 1992-04-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3437
Valid CSS Valid XHTML 1.0 Strict