1: #ifndef lint
   2: static char *sccsid = "@(#)mkstr.c	4.1 (Berkeley) 10/1/80";
   3: #endif
   4: #include <sys/types.h>
   5: #include <stdio.h>
   6: #include <sys/stat.h>
   7: 
   8: #define ungetchar(c)    ungetc(c, stdin)
   9: 
  10: long    ftell();
  11: char    *calloc();
  12: /*
  13:  * mkstr - create a string error message file by massaging C source
  14:  *
  15:  * Bill Joy UCB August 1977
  16:  *
  17:  * Modified March 1978 to hash old messages to be able to recompile
  18:  * without addding messages to the message file (usually)
  19:  *
  20:  * Based on an earlier program conceived by Bill Joy and Chuck Haley
  21:  *
  22:  * Program to create a string error message file
  23:  * from a group of C programs.  Arguments are the name
  24:  * of the file where the strings are to be placed, the
  25:  * prefix of the new files where the processed source text
  26:  * is to be placed, and the files to be processed.
  27:  *
  28:  * The program looks for 'error("' in the source stream.
  29:  * Whenever it finds this, the following characters from the '"'
  30:  * to a '"' are replaced by 'seekpt' where seekpt is a
  31:  * pointer into the error message file.
  32:  * If the '(' is not immediately followed by a '"' no change occurs.
  33:  *
  34:  * The optional '-' causes strings to be added at the end of the
  35:  * existing error message file for recompilation of single routines.
  36:  */
  37: 
  38: 
  39: FILE    *mesgread, *mesgwrite;
  40: char    *progname;
  41: char    usagestr[] =    "usage: %s [ - ] mesgfile prefix file ...\n";
  42: char    name[100], *np;
  43: 
  44: main(argc, argv)
  45:     int argc;
  46:     char *argv[];
  47: {
  48:     char addon = 0;
  49: 
  50:     argc--, progname = *argv++;
  51:     if (argc > 1 && argv[0][0] == '-')
  52:         addon++, argc--, argv++;
  53:     if (argc < 3)
  54:         fprintf(stderr, usagestr, progname), exit(1);
  55:     mesgwrite = fopen(argv[0], addon ? "a" : "w");
  56:     if (mesgwrite == NULL)
  57:         perror(argv[0]), exit(1);
  58:     mesgread = fopen(argv[0], "r");
  59:     if (mesgread == NULL)
  60:         perror(argv[0]), exit(1);
  61:     inithash();
  62:     argc--, argv++;
  63:     strcpy(name, argv[0]);
  64:     np = name + strlen(name);
  65:     argc--, argv++;
  66:     do {
  67:         strcpy(np, argv[0]);
  68:         if (freopen(name, "w", stdout) == NULL)
  69:             perror(name), exit(1);
  70:         if (freopen(argv[0], "r", stdin) == NULL)
  71:             perror(argv[0]), exit(1);
  72:         process();
  73:         argc--, argv++;
  74:     } while (argc > 0);
  75:     exit(0);
  76: }
  77: 
  78: process()
  79: {
  80:     register c;
  81: 
  82:     for (;;) {
  83:         c = getchar();
  84:         if (c == EOF)
  85:             return;
  86:         if (c != 'e') {
  87:             putchar(c);
  88:             continue;
  89:         }
  90:         if (match("error(")) {
  91:             printf("error(");
  92:             c = getchar();
  93:             if (c != '"')
  94:                 putchar(c);
  95:             else
  96:                 copystr();
  97:         }
  98:     }
  99: }
 100: 
 101: match(ocp)
 102:     char *ocp;
 103: {
 104:     register char *cp;
 105:     register c;
 106: 
 107:     for (cp = ocp + 1; *cp; cp++) {
 108:         c = getchar();
 109:         if (c != *cp) {
 110:             while (ocp < cp)
 111:                 putchar(*ocp++);
 112:             ungetchar(c);
 113:             return (0);
 114:         }
 115:     }
 116:     return (1);
 117: }
 118: 
 119: copystr()
 120: {
 121:     register c, ch;
 122:     char buf[512];
 123:     register char *cp = buf;
 124: 
 125:     for (;;) {
 126:         c = getchar();
 127:         if (c == EOF)
 128:             break;
 129:         switch (c) {
 130: 
 131:         case '"':
 132:             *cp++ = 0;
 133:             goto out;
 134:         case '\\':
 135:             c = getchar();
 136:             switch (c) {
 137: 
 138:             case 'b':
 139:                 c = '\b';
 140:                 break;
 141:             case 't':
 142:                 c = '\t';
 143:                 break;
 144:             case 'r':
 145:                 c = '\r';
 146:                 break;
 147:             case 'n':
 148:                 c = '\n';
 149:                 break;
 150:             case '\n':
 151:                 continue;
 152:             case 'f':
 153:                 c = '\f';
 154:                 break;
 155:             case '0':
 156:                 c = 0;
 157:                 break;
 158:             case '\\':
 159:                 break;
 160:             default:
 161:                 if (!octdigit(c))
 162:                     break;
 163:                 c -= '0';
 164:                 ch = getchar();
 165:                 if (!octdigit(ch))
 166:                     break;
 167:                 c <<= 7, c += ch - '0';
 168:                 ch = getchar();
 169:                 if (!octdigit(ch))
 170:                     break;
 171:                 c <<= 3, c+= ch - '0', ch = -1;
 172:                 break;
 173:             }
 174:         }
 175:         *cp++ = c;
 176:     }
 177: out:
 178:     *cp = 0;
 179:     printf("%d", hashit(buf, 1, NULL));
 180: }
 181: 
 182: octdigit(c)
 183:     char c;
 184: {
 185: 
 186:     return (c >= '0' && c <= '7');
 187: }
 188: 
 189: inithash()
 190: {
 191:     char buf[512];
 192:     int mesgpt = 0;
 193: 
 194:     rewind(mesgread);
 195:     while (fgetNUL(buf, sizeof buf, mesgread) != NULL) {
 196:         (void) hashit(buf, 0, (unsigned) mesgpt);
 197:         mesgpt += strlen(buf) + 2;
 198:     }
 199: }
 200: 
 201: #define NBUCKETS    511
 202: 
 203: struct  hash {
 204:     long    hval;
 205:     unsigned hpt;
 206:     struct  hash *hnext;
 207: } *bucket[NBUCKETS];
 208: 
 209: hashit(str, really, fakept)
 210:     char *str;
 211:     char really;
 212:     unsigned fakept;
 213: {
 214:     int i;
 215:     register struct hash *hp;
 216:     char buf[512];
 217:     long hashval = 0;
 218:     register char *cp;
 219: 
 220:     if (really)
 221:         fflush(mesgwrite);
 222:     for (cp = str; *cp;)
 223:         hashval = (hashval << 1) + *cp++;
 224:     i = /*NOSTRICT*/ hashval % NBUCKETS;
 225:     if (i < 0)
 226:         i += NBUCKETS;
 227:     if (really != 0)
 228:         for (hp = bucket[i]; hp != 0; hp = hp->hnext)
 229:         if (hp->hval == hashval) {
 230:             fseek(mesgread, (long) hp->hpt, 0);
 231:             (void) fgetNUL(buf, sizeof buf, mesgread);
 232: /*
 233: 			fprintf(stderr, "Got (from %d) %s\n", hp->hpt, buf);
 234: */
 235:             if (strcmp(buf, str) == 0)
 236:                 break;
 237:         }
 238:     if (!really || hp == 0) {
 239:         hp = (struct hash *) calloc(1, sizeof *hp);
 240:         hp->hnext = bucket[i];
 241:         hp->hval = hashval;
 242:         hp->hpt = (unsigned) (really ? ftell(mesgwrite) : fakept);
 243:         if (really) {
 244:             fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite);
 245:             fwrite("\n", sizeof (char), 1, mesgwrite);
 246:         }
 247:         bucket[i] = hp;
 248:     }
 249: /*
 250: 	fprintf(stderr, "%s hashed to %ld at %d\n", str, hp->hval, hp->hpt);
 251: */
 252:     return (hp->hpt);
 253: }
 254: 
 255: fgetNUL(obuf, rmdr, file)
 256:     char *obuf;
 257:     register int rmdr;
 258:     FILE *file;
 259: {
 260:     register c;
 261:     register char *buf = obuf;
 262: 
 263:     while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)
 264:         *buf++ = c;
 265:     *buf++ = 0;
 266:     getc(file);
 267:     return ((feof(file) || ferror(file)) ? NULL : 1);
 268: }

Defined functions

copystr defined in line 119; used 1 times
  • in line 96
fgetNUL defined in line 255; used 2 times
hashit defined in line 209; used 2 times
inithash defined in line 189; used 1 times
  • in line 61
main defined in line 44; never used
match defined in line 101; used 1 times
  • in line 90
octdigit defined in line 182; used 3 times
process defined in line 78; used 1 times
  • in line 72

Defined variables

bucket defined in line 207; used 3 times
name defined in line 42; used 5 times
np defined in line 42; used 2 times
progname defined in line 40; used 2 times
sccsid defined in line 2; never used
usagestr defined in line 41; used 1 times
  • in line 54

Defined struct's

hash defined in line 203; used 6 times

Defined macros

NBUCKETS defined in line 201; used 3 times
ungetchar defined in line 8; used 1 times
Last modified: 1982-09-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1038
Valid CSS Valid XHTML 1.0 Strict