1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * University Copyright- Copyright (c) 1982, 1986, 1988 28 * The Regents of the University of California 29 * All Rights Reserved 30 * 31 * University Acknowledgment- Portions of this document are derived from 32 * software developed by the University of California, Berkeley, and its 33 * contributors. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 #include <stdio.h> 38 39 #define ungetchar(c) ungetc(c, stdin) 40 41 long ftell(); 42 char *calloc(); 43 /* 44 * mkstr - create a string error message file by massaging C source 45 * 46 * Modified March 1978 to hash old messages to be able to recompile 47 * without adding messages to the message file (usually) 48 * 49 * Program to create a string error message file 50 * from a group of C programs. Arguments are the name 51 * of the file where the strings are to be placed, the 52 * prefix of the new files where the processed source text 53 * is to be placed, and the files to be processed. 54 * 55 * The program looks for 'error("' in the source stream. 56 * Whenever it finds this, the following characters from the '"' 57 * to a '"' are replaced by 'seekpt' where seekpt is a 58 * pointer into the error message file. 59 * If the '(' is not immediately followed by a '"' no change occurs. 60 * 61 * The optional '-' causes strings to be added at the end of the 62 * existing error message file for recompilation of single routines. 63 */ 64 65 66 FILE *mesgread, *mesgwrite; 67 char *progname; 68 char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n"; 69 char name[100], *np; 70 71 main(argc, argv) 72 int argc; 73 char *argv[]; 74 { 75 char addon = 0; 76 77 argc--, progname = *argv++; 78 if (argc > 1 && argv[0][0] == '-') 79 addon++, argc--, argv++; 80 if (argc < 3) 81 fprintf(stderr, usagestr, progname), exit(1); 82 mesgwrite = fopen(argv[0], addon ? "a" : "w"); 83 if (mesgwrite == NULL) 84 perror(argv[0]), exit(1); 85 mesgread = fopen(argv[0], "r"); 86 if (mesgread == NULL) 87 perror(argv[0]), exit(1); 88 inithash(); 89 argc--, argv++; 90 strcpy(name, argv[0]); 91 np = name + strlen(name); 92 argc--, argv++; 93 do { 94 strcpy(np, argv[0]); 95 if (freopen(name, "w", stdout) == NULL) 96 perror(name), exit(1); 97 if (freopen(argv[0], "r", stdin) == NULL) 98 perror(argv[0]), exit(1); 99 process(); 100 argc--, argv++; 101 } while (argc > 0); 102 exit(0); 103 } 104 105 process() 106 { 107 register c; 108 109 for (;;) { 110 c = getchar(); 111 if (c == EOF) 112 return; 113 if (c != 'e') { 114 putchar(c); 115 continue; 116 } 117 if (match("error(")) { 118 printf("error("); 119 c = getchar(); 120 if (c != '"') 121 putchar(c); 122 else 123 copystr(); 124 } 125 } 126 } 127 128 match(ocp) 129 char *ocp; 130 { 131 register char *cp; 132 register c; 133 134 for (cp = ocp + 1; *cp; cp++) { 135 c = getchar(); 136 if (c != *cp) { 137 while (ocp < cp) 138 putchar(*ocp++); 139 ungetchar(c); 140 return (0); 141 } 142 } 143 return (1); 144 } 145 146 copystr() 147 { 148 register c, ch; 149 char buf[512]; 150 register char *cp = buf; 151 152 for (;;) { 153 c = getchar(); 154 if (c == EOF) 155 break; 156 switch (c) { 157 158 case '"': 159 *cp++ = 0; 160 goto out; 161 case '\\': 162 c = getchar(); 163 switch (c) { 164 165 case 'b': 166 c = '\b'; 167 break; 168 case 't': 169 c = '\t'; 170 break; 171 case 'r': 172 c = '\r'; 173 break; 174 case 'n': 175 c = '\n'; 176 break; 177 case '\n': 178 continue; 179 case 'f': 180 c = '\f'; 181 break; 182 case '0': 183 c = 0; 184 break; 185 case '\\': 186 break; 187 default: 188 if (!octdigit(c)) 189 break; 190 c -= '0'; 191 ch = getchar(); 192 if (!octdigit(ch)) 193 break; 194 c <<= 7, c += ch - '0'; 195 ch = getchar(); 196 if (!octdigit(ch)) 197 break; 198 c <<= 3, c+= ch - '0', ch = -1; 199 break; 200 } 201 } 202 *cp++ = c; 203 } 204 out: 205 *cp = 0; 206 printf("%d", hashit(buf, 1, NULL)); 207 } 208 209 octdigit(c) 210 char c; 211 { 212 213 return (c >= '0' && c <= '7'); 214 } 215 216 inithash() 217 { 218 char buf[512]; 219 int mesgpt = 0; 220 221 rewind(mesgread); 222 while (fgetNUL(buf, sizeof buf, mesgread) != NULL) { 223 hashit(buf, 0, mesgpt); 224 mesgpt += strlen(buf) + 2; 225 } 226 } 227 228 #define NBUCKETS 511 229 230 struct hash { 231 long hval; 232 unsigned hpt; 233 struct hash *hnext; 234 } *bucket[NBUCKETS]; 235 236 hashit(str, really, fakept) 237 char *str; 238 char really; 239 unsigned fakept; 240 { 241 int i; 242 register struct hash *hp; 243 char buf[512]; 244 long hashval = 0; 245 register char *cp; 246 247 if (really) 248 fflush(mesgwrite); 249 for (cp = str; *cp;) 250 hashval = (hashval << 1) + *cp++; 251 i = hashval % NBUCKETS; 252 if (i < 0) 253 i += NBUCKETS; 254 if (really != 0) 255 for (hp = bucket[i]; hp != 0; hp = hp->hnext) 256 if (hp->hval == hashval) { 257 fseek(mesgread, (long) hp->hpt, 0); 258 fgetNUL(buf, sizeof buf, mesgread); 259 /* 260 fprintf(stderr, "Got (from %d) %s\n", hp->hpt, buf); 261 */ 262 if (strcmp(buf, str) == 0) 263 break; 264 } 265 if (!really || hp == 0) { 266 hp = (struct hash *) calloc(1, sizeof *hp); 267 hp->hnext = bucket[i]; 268 hp->hval = hashval; 269 hp->hpt = really ? ftell(mesgwrite) : fakept; 270 if (really) { 271 fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite); 272 fwrite("\n", sizeof (char), 1, mesgwrite); 273 } 274 bucket[i] = hp; 275 } 276 /* 277 fprintf(stderr, "%s hashed to %ld at %d\n", str, hp->hval, hp->hpt); 278 */ 279 return (hp->hpt); 280 } 281 282 #include <sys/types.h> 283 #include <sys/stat.h> 284 285 fgetNUL(obuf, rmdr, file) 286 char *obuf; 287 register int rmdr; 288 FILE *file; 289 { 290 register c; 291 register char *buf = obuf; 292 293 while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF) 294 *buf++ = c; 295 *buf++ = 0; 296 getc(file); 297 return ((feof(file) || ferror(file)) ? NULL : 1); 298 } 299