17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 2178b6ed60Scraigm */ 2278b6ed60Scraigm 2378b6ed60Scraigm /* 24*f22acdffSgbrunett * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * mkstr - create a string error message file by massaging C source 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * Bill Joy UCB August 1977 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * Modified March 1978 to hash old messages to be able to recompile 367c478bd9Sstevel@tonic-gate * without addding messages to the message file (usually) 377c478bd9Sstevel@tonic-gate * 387c478bd9Sstevel@tonic-gate * Based on an earlier program conceived by Bill Joy and Chuck Haley 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * Program to create a string error message file 417c478bd9Sstevel@tonic-gate * from a group of C programs. Arguments are the name 427c478bd9Sstevel@tonic-gate * of the file where the strings are to be placed, the 437c478bd9Sstevel@tonic-gate * prefix of the new files where the processed source text 447c478bd9Sstevel@tonic-gate * is to be placed, and the files to be processed. 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * The program looks for 'error("' in the source stream. 477c478bd9Sstevel@tonic-gate * Whenever it finds this, the following characters from the '"' 487c478bd9Sstevel@tonic-gate * to a '"' are replaced by 'seekpt' where seekpt is a 497c478bd9Sstevel@tonic-gate * pointer into the error message file. 507c478bd9Sstevel@tonic-gate * If the '(' is not immediately followed by a '"' no change occurs. 517c478bd9Sstevel@tonic-gate * 527c478bd9Sstevel@tonic-gate * The optional '-' causes strings to be added at the end of the 537c478bd9Sstevel@tonic-gate * existing error message file for recompilation of single routines. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 5678b6ed60Scraigm #include <stdio.h> 57*f22acdffSgbrunett #include <stdlib.h> 58*f22acdffSgbrunett #include <string.h> 5978b6ed60Scraigm #include <locale.h> 60*f22acdffSgbrunett #include <sys/param.h> 6178b6ed60Scraigm 6278b6ed60Scraigm #define ungetchar(c) ungetc(c, stdin) 6378b6ed60Scraigm 64*f22acdffSgbrunett #define NBUCKETS 511 657c478bd9Sstevel@tonic-gate 66*f22acdffSgbrunett static char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n"; 677c478bd9Sstevel@tonic-gate 68*f22acdffSgbrunett static FILE *mesgread, *mesgwrite; 69*f22acdffSgbrunett 70*f22acdffSgbrunett static void process(void); 71*f22acdffSgbrunett static int match(char *ocp); 72*f22acdffSgbrunett static void copystr(void); 73*f22acdffSgbrunett static int octdigit(char c); 74*f22acdffSgbrunett static void inithash(void); 75*f22acdffSgbrunett static int hashit(char *str, char really, unsigned int fakept); 76*f22acdffSgbrunett static int fgetNUL(char *obuf, int rmdr, FILE *file); 7778b6ed60Scraigm 7878b6ed60Scraigm int 7978b6ed60Scraigm main(int argc, char *argv[]) 807c478bd9Sstevel@tonic-gate { 817c478bd9Sstevel@tonic-gate char addon = 0; 82*f22acdffSgbrunett char *progname, *np, name[MAXPATHLEN]; 83*f22acdffSgbrunett size_t size = 0; 84*f22acdffSgbrunett size_t len; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 897c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 907c478bd9Sstevel@tonic-gate #endif 917c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate argc--, progname = *argv++; 947c478bd9Sstevel@tonic-gate if (argc > 1 && argv[0][0] == '-') 957c478bd9Sstevel@tonic-gate addon++, argc--, argv++; 967c478bd9Sstevel@tonic-gate if (argc < 3) 97*f22acdffSgbrunett (void) fprintf(stderr, gettext(usagestr), progname), exit(1); 987c478bd9Sstevel@tonic-gate mesgwrite = fopen(argv[0], addon ? "a" : "w"); 997c478bd9Sstevel@tonic-gate if (mesgwrite == NULL) 1007c478bd9Sstevel@tonic-gate perror(argv[0]), exit(1); 1017c478bd9Sstevel@tonic-gate mesgread = fopen(argv[0], "r"); 1027c478bd9Sstevel@tonic-gate if (mesgread == NULL) 1037c478bd9Sstevel@tonic-gate perror(argv[0]), exit(1); 1047c478bd9Sstevel@tonic-gate inithash(); 1057c478bd9Sstevel@tonic-gate argc--, argv++; 106*f22acdffSgbrunett 107*f22acdffSgbrunett if (strlcpy(name, argv[0], sizeof (name)) >= sizeof (name)) { 108*f22acdffSgbrunett (void) fprintf(stderr, gettext("%s: %s: string too long"), 109*f22acdffSgbrunett progname, argv[0]); 110*f22acdffSgbrunett exit(1); 111*f22acdffSgbrunett } 112*f22acdffSgbrunett 1137c478bd9Sstevel@tonic-gate np = name + strlen(name); 114*f22acdffSgbrunett 115*f22acdffSgbrunett len = strlen(name); 116*f22acdffSgbrunett np = name + len; 117*f22acdffSgbrunett size = sizeof (name) - len; 1187c478bd9Sstevel@tonic-gate argc--, argv++; 1197c478bd9Sstevel@tonic-gate do { 120*f22acdffSgbrunett if (strlcpy(np, argv[0], size) >= size) { 121*f22acdffSgbrunett (void) fprintf(stderr, 122*f22acdffSgbrunett gettext("%s: %s: string too long"), 123*f22acdffSgbrunett progname, argv[0]); 124*f22acdffSgbrunett exit(1); 125*f22acdffSgbrunett } 1267c478bd9Sstevel@tonic-gate if (freopen(name, "w", stdout) == NULL) 1277c478bd9Sstevel@tonic-gate perror(name), exit(1); 1287c478bd9Sstevel@tonic-gate if (freopen(argv[0], "r", stdin) == NULL) 1297c478bd9Sstevel@tonic-gate perror(argv[0]), exit(1); 1307c478bd9Sstevel@tonic-gate process(); 1317c478bd9Sstevel@tonic-gate argc--, argv++; 1327c478bd9Sstevel@tonic-gate } while (argc > 0); 133*f22acdffSgbrunett 13478b6ed60Scraigm return (0); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 137*f22acdffSgbrunett static void 13878b6ed60Scraigm process(void) 1397c478bd9Sstevel@tonic-gate { 14078b6ed60Scraigm int c; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate for (;;) { 1437c478bd9Sstevel@tonic-gate c = getchar(); 1447c478bd9Sstevel@tonic-gate if (c == EOF) 1457c478bd9Sstevel@tonic-gate return; 1467c478bd9Sstevel@tonic-gate if (c != 'e') { 147*f22acdffSgbrunett (void) putchar(c); 1487c478bd9Sstevel@tonic-gate continue; 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate if (match("error(")) { 151*f22acdffSgbrunett (void) printf(gettext("error(")); 1527c478bd9Sstevel@tonic-gate c = getchar(); 1537c478bd9Sstevel@tonic-gate if (c != '"') 154*f22acdffSgbrunett (void) putchar(c); 1557c478bd9Sstevel@tonic-gate else 1567c478bd9Sstevel@tonic-gate copystr(); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 161*f22acdffSgbrunett static int 16278b6ed60Scraigm match(char *ocp) 1637c478bd9Sstevel@tonic-gate { 16478b6ed60Scraigm char *cp; 16578b6ed60Scraigm int c; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate for (cp = ocp + 1; *cp; cp++) { 1687c478bd9Sstevel@tonic-gate c = getchar(); 1697c478bd9Sstevel@tonic-gate if (c != *cp) { 1707c478bd9Sstevel@tonic-gate while (ocp < cp) 171*f22acdffSgbrunett (void) putchar(*ocp++); 172*f22acdffSgbrunett (void) ungetchar(c); 1737c478bd9Sstevel@tonic-gate return (0); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate return (1); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 179*f22acdffSgbrunett static void 18078b6ed60Scraigm copystr(void) 1817c478bd9Sstevel@tonic-gate { 18278b6ed60Scraigm int c, ch; 1837c478bd9Sstevel@tonic-gate char buf[512]; 18478b6ed60Scraigm char *cp = buf; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate for (;;) { 1877c478bd9Sstevel@tonic-gate c = getchar(); 1887c478bd9Sstevel@tonic-gate if (c == EOF) 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate switch (c) { 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate case '"': 1937c478bd9Sstevel@tonic-gate *cp++ = 0; 1947c478bd9Sstevel@tonic-gate goto out; 1957c478bd9Sstevel@tonic-gate case '\\': 1967c478bd9Sstevel@tonic-gate c = getchar(); 1977c478bd9Sstevel@tonic-gate switch (c) { 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate case 'b': 2007c478bd9Sstevel@tonic-gate c = '\b'; 2017c478bd9Sstevel@tonic-gate break; 2027c478bd9Sstevel@tonic-gate case 't': 2037c478bd9Sstevel@tonic-gate c = '\t'; 2047c478bd9Sstevel@tonic-gate break; 2057c478bd9Sstevel@tonic-gate case 'r': 2067c478bd9Sstevel@tonic-gate c = '\r'; 2077c478bd9Sstevel@tonic-gate break; 2087c478bd9Sstevel@tonic-gate case 'n': 2097c478bd9Sstevel@tonic-gate c = '\n'; 2107c478bd9Sstevel@tonic-gate break; 2117c478bd9Sstevel@tonic-gate case '\n': 2127c478bd9Sstevel@tonic-gate continue; 2137c478bd9Sstevel@tonic-gate case 'f': 2147c478bd9Sstevel@tonic-gate c = '\f'; 2157c478bd9Sstevel@tonic-gate break; 2167c478bd9Sstevel@tonic-gate case '0': 2177c478bd9Sstevel@tonic-gate c = 0; 2187c478bd9Sstevel@tonic-gate break; 2197c478bd9Sstevel@tonic-gate case '\\': 2207c478bd9Sstevel@tonic-gate break; 2217c478bd9Sstevel@tonic-gate default: 2227c478bd9Sstevel@tonic-gate if (!octdigit(c)) 2237c478bd9Sstevel@tonic-gate break; 2247c478bd9Sstevel@tonic-gate c -= '0'; 2257c478bd9Sstevel@tonic-gate ch = getchar(); 2267c478bd9Sstevel@tonic-gate if (!octdigit(ch)) 2277c478bd9Sstevel@tonic-gate break; 2287c478bd9Sstevel@tonic-gate c <<= 7, c += ch - '0'; 2297c478bd9Sstevel@tonic-gate ch = getchar(); 2307c478bd9Sstevel@tonic-gate if (!octdigit(ch)) 2317c478bd9Sstevel@tonic-gate break; 2327c478bd9Sstevel@tonic-gate c <<= 3, c += ch - '0', ch = -1; 2337c478bd9Sstevel@tonic-gate break; 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate *cp++ = c; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate out: 2397c478bd9Sstevel@tonic-gate *cp = 0; 240*f22acdffSgbrunett (void) printf("%d", hashit(buf, 1, NULL)); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 243*f22acdffSgbrunett static int 24478b6ed60Scraigm octdigit(char c) 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate return (c >= '0' && c <= '7'); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 250*f22acdffSgbrunett static void 25178b6ed60Scraigm inithash(void) 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate char buf[512]; 2547c478bd9Sstevel@tonic-gate int mesgpt = 0; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate rewind(mesgread); 257*f22acdffSgbrunett while (fgetNUL(buf, sizeof (buf), mesgread) != NULL) { 258*f22acdffSgbrunett (void) hashit(buf, 0, mesgpt); 2597c478bd9Sstevel@tonic-gate mesgpt += strlen(buf) + 2; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate 263*f22acdffSgbrunett static struct hash { 2647c478bd9Sstevel@tonic-gate long hval; 26578b6ed60Scraigm unsigned int hpt; 2667c478bd9Sstevel@tonic-gate struct hash *hnext; 2677c478bd9Sstevel@tonic-gate } *bucket[NBUCKETS]; 2687c478bd9Sstevel@tonic-gate 269*f22acdffSgbrunett static int 27078b6ed60Scraigm hashit(char *str, char really, unsigned int fakept) 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate int i; 27378b6ed60Scraigm struct hash *hp; 2747c478bd9Sstevel@tonic-gate char buf[512]; 2757c478bd9Sstevel@tonic-gate long hashval = 0; 27678b6ed60Scraigm char *cp; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate if (really) 279*f22acdffSgbrunett (void) fflush(mesgwrite); 2807c478bd9Sstevel@tonic-gate for (cp = str; *cp; ) 2817c478bd9Sstevel@tonic-gate hashval = (hashval << 1) + *cp++; 2827c478bd9Sstevel@tonic-gate i = hashval % NBUCKETS; 2837c478bd9Sstevel@tonic-gate if (i < 0) 2847c478bd9Sstevel@tonic-gate i += NBUCKETS; 2857c478bd9Sstevel@tonic-gate if (really != 0) 2867c478bd9Sstevel@tonic-gate for (hp = bucket[i]; hp != 0; hp = hp->hnext) 2877c478bd9Sstevel@tonic-gate if (hp->hval == hashval) { 288*f22acdffSgbrunett (void) fseek(mesgread, (long)hp->hpt, 0); 289*f22acdffSgbrunett (void) fgetNUL(buf, sizeof (buf), mesgread); 2907c478bd9Sstevel@tonic-gate if (strcmp(buf, str) == 0) 2917c478bd9Sstevel@tonic-gate break; 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate if (!really || hp == 0) { 294*f22acdffSgbrunett hp = (struct hash *)calloc(1, sizeof (*hp)); 2957c478bd9Sstevel@tonic-gate hp->hnext = bucket[i]; 2967c478bd9Sstevel@tonic-gate hp->hval = hashval; 2977c478bd9Sstevel@tonic-gate hp->hpt = really ? ftell(mesgwrite) : fakept; 2987c478bd9Sstevel@tonic-gate if (really) { 299*f22acdffSgbrunett (void) fwrite(str, sizeof (char), strlen(str) + 1, 300*f22acdffSgbrunett mesgwrite); 301*f22acdffSgbrunett (void) fwrite("\n", sizeof (char), 1, mesgwrite); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate bucket[i] = hp; 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate return (hp->hpt); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 308*f22acdffSgbrunett static int 30978b6ed60Scraigm fgetNUL(char *obuf, int rmdr, FILE *file) 3107c478bd9Sstevel@tonic-gate { 31178b6ed60Scraigm int c; 31278b6ed60Scraigm char *buf = obuf; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF) 3157c478bd9Sstevel@tonic-gate *buf++ = c; 3167c478bd9Sstevel@tonic-gate *buf++ = 0; 317*f22acdffSgbrunett (void) getc(file); 3187c478bd9Sstevel@tonic-gate return ((feof(file) || ferror(file)) ? NULL : 1); 3197c478bd9Sstevel@tonic-gate } 320