xref: /titanic_54/usr/src/cmd/xstr/xstr.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
8*7c478bd9Sstevel@tonic-gate 
9*7c478bd9Sstevel@tonic-gate /*
10*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
11*7c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
12*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
13*7c478bd9Sstevel@tonic-gate  */
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include <stdio.h>
18*7c478bd9Sstevel@tonic-gate #include <ctype.h>
19*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
20*7c478bd9Sstevel@tonic-gate #include <signal.h>
21*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate /*
24*7c478bd9Sstevel@tonic-gate  * xstr - extract and hash strings in a C program
25*7c478bd9Sstevel@tonic-gate  *
26*7c478bd9Sstevel@tonic-gate  * Bill Joy UCB
27*7c478bd9Sstevel@tonic-gate  * November, 1978
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #define	ignore(a)	((void) a)
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate off_t	tellpt;
33*7c478bd9Sstevel@tonic-gate off_t	hashit();
34*7c478bd9Sstevel@tonic-gate void	onintr();
35*7c478bd9Sstevel@tonic-gate char	*savestr();
36*7c478bd9Sstevel@tonic-gate char	*strcat();
37*7c478bd9Sstevel@tonic-gate char	*strcpy();
38*7c478bd9Sstevel@tonic-gate off_t	yankstr();
39*7c478bd9Sstevel@tonic-gate void	cleanup();
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate off_t	mesgpt;
42*7c478bd9Sstevel@tonic-gate char	*strings =	"strings";
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate int	cflg;
45*7c478bd9Sstevel@tonic-gate int	vflg;
46*7c478bd9Sstevel@tonic-gate char	*xname = "xstr";
47*7c478bd9Sstevel@tonic-gate int	readstd;
48*7c478bd9Sstevel@tonic-gate int	tmpfd;
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate main(argc, argv)
51*7c478bd9Sstevel@tonic-gate 	int argc;
52*7c478bd9Sstevel@tonic-gate 	char *argv[];
53*7c478bd9Sstevel@tonic-gate {
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 	argc--, argv++;
57*7c478bd9Sstevel@tonic-gate 	while (argc > 0 && argv[0][0] == '-') {
58*7c478bd9Sstevel@tonic-gate 		register char *cp = &(*argv++)[1];
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate 		argc--;
61*7c478bd9Sstevel@tonic-gate 		if (*cp == 0) {
62*7c478bd9Sstevel@tonic-gate 			readstd++;
63*7c478bd9Sstevel@tonic-gate 			continue;
64*7c478bd9Sstevel@tonic-gate 		}
65*7c478bd9Sstevel@tonic-gate 		do switch (*cp++) {
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate 		case 'c':
68*7c478bd9Sstevel@tonic-gate 			cflg++;
69*7c478bd9Sstevel@tonic-gate 			continue;
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 		case 'l':
72*7c478bd9Sstevel@tonic-gate 			xname = *argv++;
73*7c478bd9Sstevel@tonic-gate 			argc--;
74*7c478bd9Sstevel@tonic-gate 			continue;
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate 		case 'v':
77*7c478bd9Sstevel@tonic-gate 			vflg++;
78*7c478bd9Sstevel@tonic-gate 			continue;
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate 		default:
81*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
82*7c478bd9Sstevel@tonic-gate 		"usage: xstr [ -v ] [ -c ] [ -l label ] [ - ] [ name ... ]\n");
83*7c478bd9Sstevel@tonic-gate 		} while (*cp);
84*7c478bd9Sstevel@tonic-gate 	}
85*7c478bd9Sstevel@tonic-gate 	if (signal(SIGINT, SIG_IGN) == SIG_DFL)
86*7c478bd9Sstevel@tonic-gate 		signal(SIGINT, onintr);
87*7c478bd9Sstevel@tonic-gate 	if (cflg || argc == 0 && !readstd)
88*7c478bd9Sstevel@tonic-gate 		inithash();
89*7c478bd9Sstevel@tonic-gate 	else {
90*7c478bd9Sstevel@tonic-gate 		strings = savestr("/tmp/xstrXXXXXX");
91*7c478bd9Sstevel@tonic-gate 		tmpfd = mkstemp(strings);
92*7c478bd9Sstevel@tonic-gate 		if (tmpfd == -1) {
93*7c478bd9Sstevel@tonic-gate 			perror(strings);
94*7c478bd9Sstevel@tonic-gate 			(void) free(strings);
95*7c478bd9Sstevel@tonic-gate 			exit(9);
96*7c478bd9Sstevel@tonic-gate 		}
97*7c478bd9Sstevel@tonic-gate 		(void) close(tmpfd);
98*7c478bd9Sstevel@tonic-gate 	}
99*7c478bd9Sstevel@tonic-gate 	while (readstd || argc > 0) {
100*7c478bd9Sstevel@tonic-gate 		if (freopen("x.c", "w", stdout) == NULL)
101*7c478bd9Sstevel@tonic-gate 			perror("x.c"), (void) cleanup(), exit(1);
102*7c478bd9Sstevel@tonic-gate 		if (!readstd && freopen(argv[0], "r", stdin) == NULL)
103*7c478bd9Sstevel@tonic-gate 			perror(argv[0]), (void) cleanup(), exit(2);
104*7c478bd9Sstevel@tonic-gate 		process("x.c");
105*7c478bd9Sstevel@tonic-gate 		if (readstd == 0)
106*7c478bd9Sstevel@tonic-gate 			argc--, argv++;
107*7c478bd9Sstevel@tonic-gate 		else
108*7c478bd9Sstevel@tonic-gate 			readstd = 0;
109*7c478bd9Sstevel@tonic-gate 	};
110*7c478bd9Sstevel@tonic-gate 	flushsh();
111*7c478bd9Sstevel@tonic-gate 	if (cflg == 0)
112*7c478bd9Sstevel@tonic-gate 		xsdotc();
113*7c478bd9Sstevel@tonic-gate 	(void) cleanup();
114*7c478bd9Sstevel@tonic-gate 	exit(0);
115*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
116*7c478bd9Sstevel@tonic-gate }
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate char linebuf[BUFSIZ];
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate process(name)
121*7c478bd9Sstevel@tonic-gate 	char *name;
122*7c478bd9Sstevel@tonic-gate {
123*7c478bd9Sstevel@tonic-gate 	char *cp;
124*7c478bd9Sstevel@tonic-gate 	register int c;
125*7c478bd9Sstevel@tonic-gate 	register int incomm = 0;
126*7c478bd9Sstevel@tonic-gate 	int ret;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	printf("extern char\t%s[];\n", xname);
129*7c478bd9Sstevel@tonic-gate 	for (;;) {
130*7c478bd9Sstevel@tonic-gate 		if (fgets(linebuf, sizeof (linebuf), stdin) == NULL) {
131*7c478bd9Sstevel@tonic-gate 			if (ferror(stdin)) {
132*7c478bd9Sstevel@tonic-gate 				perror(name);
133*7c478bd9Sstevel@tonic-gate 				(void) cleanup();
134*7c478bd9Sstevel@tonic-gate 				exit(3);
135*7c478bd9Sstevel@tonic-gate 			}
136*7c478bd9Sstevel@tonic-gate 			break;
137*7c478bd9Sstevel@tonic-gate 		}
138*7c478bd9Sstevel@tonic-gate 		if (linebuf[0] == '#') {
139*7c478bd9Sstevel@tonic-gate 			if (linebuf[1] == ' ' && isdigit(linebuf[2]))
140*7c478bd9Sstevel@tonic-gate 				printf("#line%s", &linebuf[1]);
141*7c478bd9Sstevel@tonic-gate 			else
142*7c478bd9Sstevel@tonic-gate 				printf("%s", linebuf);
143*7c478bd9Sstevel@tonic-gate 			continue;
144*7c478bd9Sstevel@tonic-gate 		}
145*7c478bd9Sstevel@tonic-gate 		for (cp = linebuf; c = *cp++; ) {
146*7c478bd9Sstevel@tonic-gate 			switch (c) {
147*7c478bd9Sstevel@tonic-gate 				case '"':
148*7c478bd9Sstevel@tonic-gate 					if (incomm)
149*7c478bd9Sstevel@tonic-gate 						goto def;
150*7c478bd9Sstevel@tonic-gate 					if ((ret = (int) yankstr(&cp)) == -1)
151*7c478bd9Sstevel@tonic-gate 						goto out;
152*7c478bd9Sstevel@tonic-gate 					printf("(&%s[%d])", xname, ret);
153*7c478bd9Sstevel@tonic-gate 					break;
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 				case '\'':
156*7c478bd9Sstevel@tonic-gate 					if (incomm)
157*7c478bd9Sstevel@tonic-gate 						goto def;
158*7c478bd9Sstevel@tonic-gate 					putchar(c);
159*7c478bd9Sstevel@tonic-gate 					if (*cp)
160*7c478bd9Sstevel@tonic-gate 						putchar(*cp++);
161*7c478bd9Sstevel@tonic-gate 					break;
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 				case '/':
164*7c478bd9Sstevel@tonic-gate 					if (incomm || *cp != '*')
165*7c478bd9Sstevel@tonic-gate 						goto def;
166*7c478bd9Sstevel@tonic-gate 					incomm = 1;
167*7c478bd9Sstevel@tonic-gate 					cp++;
168*7c478bd9Sstevel@tonic-gate 					printf("/*");
169*7c478bd9Sstevel@tonic-gate 					continue;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 				case '*':
172*7c478bd9Sstevel@tonic-gate 					if (incomm && *cp == '/') {
173*7c478bd9Sstevel@tonic-gate 						incomm = 0;
174*7c478bd9Sstevel@tonic-gate 						cp++;
175*7c478bd9Sstevel@tonic-gate 						printf("*/");
176*7c478bd9Sstevel@tonic-gate 						continue;
177*7c478bd9Sstevel@tonic-gate 					}
178*7c478bd9Sstevel@tonic-gate 					goto def;
179*7c478bd9Sstevel@tonic-gate def:
180*7c478bd9Sstevel@tonic-gate 				default:
181*7c478bd9Sstevel@tonic-gate 					putchar(c);
182*7c478bd9Sstevel@tonic-gate 					break;
183*7c478bd9Sstevel@tonic-gate 			}
184*7c478bd9Sstevel@tonic-gate 		}
185*7c478bd9Sstevel@tonic-gate 	}
186*7c478bd9Sstevel@tonic-gate out:
187*7c478bd9Sstevel@tonic-gate 	if (ferror(stdout))
188*7c478bd9Sstevel@tonic-gate 		perror("x.c"), onintr();
189*7c478bd9Sstevel@tonic-gate }
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate off_t
192*7c478bd9Sstevel@tonic-gate yankstr(cpp)
193*7c478bd9Sstevel@tonic-gate 	register char **cpp;
194*7c478bd9Sstevel@tonic-gate {
195*7c478bd9Sstevel@tonic-gate 	register char *cp = *cpp;
196*7c478bd9Sstevel@tonic-gate 	register int c, ch;
197*7c478bd9Sstevel@tonic-gate 	char dbuf[BUFSIZ];
198*7c478bd9Sstevel@tonic-gate 	register char *dp = dbuf;
199*7c478bd9Sstevel@tonic-gate 	register char *tp;
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	while (c = *cp++) {
202*7c478bd9Sstevel@tonic-gate 		switch (c) {
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		case '"':
205*7c478bd9Sstevel@tonic-gate 			cp++;
206*7c478bd9Sstevel@tonic-gate 			goto out;
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 		case '\\':
209*7c478bd9Sstevel@tonic-gate 			c = *cp++;
210*7c478bd9Sstevel@tonic-gate 			if (c == 0)
211*7c478bd9Sstevel@tonic-gate 				break;
212*7c478bd9Sstevel@tonic-gate 			if (c == '\n') {
213*7c478bd9Sstevel@tonic-gate 				if (fgets(linebuf, sizeof (linebuf), stdin)
214*7c478bd9Sstevel@tonic-gate 				    == NULL) {
215*7c478bd9Sstevel@tonic-gate 					if (ferror(stdin)) {
216*7c478bd9Sstevel@tonic-gate 						perror("x.c");
217*7c478bd9Sstevel@tonic-gate 						(void) cleanup();
218*7c478bd9Sstevel@tonic-gate 						exit(3);
219*7c478bd9Sstevel@tonic-gate 					}
220*7c478bd9Sstevel@tonic-gate 					return (-1);
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 				}
223*7c478bd9Sstevel@tonic-gate 				cp = linebuf;
224*7c478bd9Sstevel@tonic-gate 				continue;
225*7c478bd9Sstevel@tonic-gate 			}
226*7c478bd9Sstevel@tonic-gate 			for (tp = "b\bt\tr\rn\nf\f\\\\\"\""; ch = *tp++; tp++)
227*7c478bd9Sstevel@tonic-gate 				if (c == ch) {
228*7c478bd9Sstevel@tonic-gate 					c = *tp;
229*7c478bd9Sstevel@tonic-gate 					goto gotc;
230*7c478bd9Sstevel@tonic-gate 				}
231*7c478bd9Sstevel@tonic-gate 			if (!octdigit(c)) {
232*7c478bd9Sstevel@tonic-gate 				*dp++ = '\\';
233*7c478bd9Sstevel@tonic-gate 				break;
234*7c478bd9Sstevel@tonic-gate 			}
235*7c478bd9Sstevel@tonic-gate 			c -= '0';
236*7c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
237*7c478bd9Sstevel@tonic-gate 				break;
238*7c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
239*7c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
240*7c478bd9Sstevel@tonic-gate 				break;
241*7c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
242*7c478bd9Sstevel@tonic-gate 			break;
243*7c478bd9Sstevel@tonic-gate 		}
244*7c478bd9Sstevel@tonic-gate gotc:
245*7c478bd9Sstevel@tonic-gate 		*dp++ = c;
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate out:
248*7c478bd9Sstevel@tonic-gate 	*cpp = --cp;
249*7c478bd9Sstevel@tonic-gate 	*dp = 0;
250*7c478bd9Sstevel@tonic-gate 	return (hashit(dbuf, 1));
251*7c478bd9Sstevel@tonic-gate }
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate octdigit(c)
254*7c478bd9Sstevel@tonic-gate 	char c;
255*7c478bd9Sstevel@tonic-gate {
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	return (isdigit(c) && c != '8' && c != '9');
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate inithash()
261*7c478bd9Sstevel@tonic-gate {
262*7c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
263*7c478bd9Sstevel@tonic-gate 	register FILE *mesgread = fopen(strings, "r");
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 	if (mesgread == NULL)
266*7c478bd9Sstevel@tonic-gate 		return;
267*7c478bd9Sstevel@tonic-gate 	for (;;) {
268*7c478bd9Sstevel@tonic-gate 		mesgpt = tellpt;
269*7c478bd9Sstevel@tonic-gate 		if (fgetNUL(buf, sizeof (buf), mesgread) == NULL)
270*7c478bd9Sstevel@tonic-gate 			break;
271*7c478bd9Sstevel@tonic-gate 		ignore(hashit(buf, 0));
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 	ignore(fclose(mesgread));
274*7c478bd9Sstevel@tonic-gate }
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate fgetNUL(obuf, rmdr, file)
277*7c478bd9Sstevel@tonic-gate 	char *obuf;
278*7c478bd9Sstevel@tonic-gate 	register int rmdr;
279*7c478bd9Sstevel@tonic-gate 	FILE *file;
280*7c478bd9Sstevel@tonic-gate {
281*7c478bd9Sstevel@tonic-gate 	register c;
282*7c478bd9Sstevel@tonic-gate 	register char *buf = obuf;
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate 	while (--rmdr > 0 && (c = xgetc(file)) != 0 && c != EOF)
285*7c478bd9Sstevel@tonic-gate 		*buf++ = c;
286*7c478bd9Sstevel@tonic-gate 	*buf++ = 0;
287*7c478bd9Sstevel@tonic-gate 	return ((feof(file) || ferror(file)) ? NULL : 1);
288*7c478bd9Sstevel@tonic-gate }
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate xgetc(file)
291*7c478bd9Sstevel@tonic-gate 	FILE *file;
292*7c478bd9Sstevel@tonic-gate {
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate 	tellpt++;
295*7c478bd9Sstevel@tonic-gate 	return (getc(file));
296*7c478bd9Sstevel@tonic-gate }
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate #define	BUCKETS	128
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate struct	hash {
301*7c478bd9Sstevel@tonic-gate 	off_t	hpt;
302*7c478bd9Sstevel@tonic-gate 	char	*hstr;
303*7c478bd9Sstevel@tonic-gate 	struct	hash *hnext;
304*7c478bd9Sstevel@tonic-gate 	short	hnew;
305*7c478bd9Sstevel@tonic-gate } bucket[BUCKETS];
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate off_t
308*7c478bd9Sstevel@tonic-gate hashit(str, new)
309*7c478bd9Sstevel@tonic-gate 	char *str;
310*7c478bd9Sstevel@tonic-gate 	int new;
311*7c478bd9Sstevel@tonic-gate {
312*7c478bd9Sstevel@tonic-gate 	int i;
313*7c478bd9Sstevel@tonic-gate 	register struct hash *hp, *hp0;
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 	hp = hp0 = &bucket[lastchr(str) & 0177];
316*7c478bd9Sstevel@tonic-gate 	while (hp->hnext) {
317*7c478bd9Sstevel@tonic-gate 		hp = hp->hnext;
318*7c478bd9Sstevel@tonic-gate 		i = istail(str, hp->hstr);
319*7c478bd9Sstevel@tonic-gate 		if (i >= 0)
320*7c478bd9Sstevel@tonic-gate 			return (hp->hpt + i);
321*7c478bd9Sstevel@tonic-gate 	}
322*7c478bd9Sstevel@tonic-gate 	if ((hp = (struct hash *) calloc(1, sizeof (*hp))) == NULL) {
323*7c478bd9Sstevel@tonic-gate 		perror("xstr");
324*7c478bd9Sstevel@tonic-gate 		(void) cleanup();
325*7c478bd9Sstevel@tonic-gate 		exit(8);
326*7c478bd9Sstevel@tonic-gate 	}
327*7c478bd9Sstevel@tonic-gate 	hp->hpt = mesgpt;
328*7c478bd9Sstevel@tonic-gate 	hp->hstr = savestr(str);
329*7c478bd9Sstevel@tonic-gate 	mesgpt += strlen(hp->hstr) + 1;
330*7c478bd9Sstevel@tonic-gate 	hp->hnext = hp0->hnext;
331*7c478bd9Sstevel@tonic-gate 	hp->hnew = new;
332*7c478bd9Sstevel@tonic-gate 	hp0->hnext = hp;
333*7c478bd9Sstevel@tonic-gate 	return (hp->hpt);
334*7c478bd9Sstevel@tonic-gate }
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate flushsh()
337*7c478bd9Sstevel@tonic-gate {
338*7c478bd9Sstevel@tonic-gate 	register int i;
339*7c478bd9Sstevel@tonic-gate 	register struct hash *hp;
340*7c478bd9Sstevel@tonic-gate 	register FILE *mesgwrit;
341*7c478bd9Sstevel@tonic-gate 	register int old = 0, new = 0;
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
344*7c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext)
345*7c478bd9Sstevel@tonic-gate 			if (hp->hnew)
346*7c478bd9Sstevel@tonic-gate 				new++;
347*7c478bd9Sstevel@tonic-gate 			else
348*7c478bd9Sstevel@tonic-gate 				old++;
349*7c478bd9Sstevel@tonic-gate 	if (new == 0 && old != 0)
350*7c478bd9Sstevel@tonic-gate 		return;
351*7c478bd9Sstevel@tonic-gate 	mesgwrit = fopen(strings, old ? "r+" : "w");
352*7c478bd9Sstevel@tonic-gate 	if (mesgwrit == NULL)
353*7c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
354*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
355*7c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) {
356*7c478bd9Sstevel@tonic-gate 			found(hp->hnew, hp->hpt, hp->hstr);
357*7c478bd9Sstevel@tonic-gate 			if (hp->hnew) {
358*7c478bd9Sstevel@tonic-gate 				fseek(mesgwrit, hp->hpt, 0);
359*7c478bd9Sstevel@tonic-gate 				ignore(fwrite(hp->hstr,
360*7c478bd9Sstevel@tonic-gate 				    strlen(hp->hstr) + 1, 1, mesgwrit));
361*7c478bd9Sstevel@tonic-gate 				if (ferror(mesgwrit)) {
362*7c478bd9Sstevel@tonic-gate 					perror(strings);
363*7c478bd9Sstevel@tonic-gate 					(void) cleanup();
364*7c478bd9Sstevel@tonic-gate 					exit(4);
365*7c478bd9Sstevel@tonic-gate 				}
366*7c478bd9Sstevel@tonic-gate 			}
367*7c478bd9Sstevel@tonic-gate 		}
368*7c478bd9Sstevel@tonic-gate 	if (fclose(mesgwrit) == EOF)
369*7c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
370*7c478bd9Sstevel@tonic-gate }
371*7c478bd9Sstevel@tonic-gate 
372*7c478bd9Sstevel@tonic-gate found(new, off, str)
373*7c478bd9Sstevel@tonic-gate 	int new;
374*7c478bd9Sstevel@tonic-gate 	off_t off;
375*7c478bd9Sstevel@tonic-gate 	char *str;
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate 	if (vflg == 0)
378*7c478bd9Sstevel@tonic-gate 		return;
379*7c478bd9Sstevel@tonic-gate 	if (!new)
380*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "found at %d:", (int) off);
381*7c478bd9Sstevel@tonic-gate 	else
382*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "new at %d:", (int) off);
383*7c478bd9Sstevel@tonic-gate 	prstr(str);
384*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\n");
385*7c478bd9Sstevel@tonic-gate }
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate prstr(cp)
388*7c478bd9Sstevel@tonic-gate 	register char *cp;
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	register int c;
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate 	while (c = (*cp++ & 0377))
393*7c478bd9Sstevel@tonic-gate 		if (c < ' ')
394*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "^%c", c + '`');
395*7c478bd9Sstevel@tonic-gate 		else if (c == 0177)
396*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "^?");
397*7c478bd9Sstevel@tonic-gate 		else if (c > 0200)
398*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "\\%03o", c);
399*7c478bd9Sstevel@tonic-gate 		else
400*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%c", c);
401*7c478bd9Sstevel@tonic-gate }
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate xsdotc()
404*7c478bd9Sstevel@tonic-gate {
405*7c478bd9Sstevel@tonic-gate 	register FILE *strf = fopen(strings, "r");
406*7c478bd9Sstevel@tonic-gate 	register FILE *xdotcf;
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate 	if (strf == NULL)
409*7c478bd9Sstevel@tonic-gate 		perror(strings), exit(5);
410*7c478bd9Sstevel@tonic-gate 	xdotcf = fopen("xs.c", "w");
411*7c478bd9Sstevel@tonic-gate 	if (xdotcf == NULL)
412*7c478bd9Sstevel@tonic-gate 		perror("xs.c"), exit(6);
413*7c478bd9Sstevel@tonic-gate 	fprintf(xdotcf, "char\t%s[] = {\n", xname);
414*7c478bd9Sstevel@tonic-gate 	for (;;) {
415*7c478bd9Sstevel@tonic-gate 		register int i, c;
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
418*7c478bd9Sstevel@tonic-gate 			c = getc(strf);
419*7c478bd9Sstevel@tonic-gate 			if (ferror(strf)) {
420*7c478bd9Sstevel@tonic-gate 				perror(strings);
421*7c478bd9Sstevel@tonic-gate 				onintr();
422*7c478bd9Sstevel@tonic-gate 			}
423*7c478bd9Sstevel@tonic-gate 			if (feof(strf)) {
424*7c478bd9Sstevel@tonic-gate 				fprintf(xdotcf, "\n");
425*7c478bd9Sstevel@tonic-gate 				goto out;
426*7c478bd9Sstevel@tonic-gate 			}
427*7c478bd9Sstevel@tonic-gate 			fprintf(xdotcf, "0x%02x,", c);
428*7c478bd9Sstevel@tonic-gate 		}
429*7c478bd9Sstevel@tonic-gate 		fprintf(xdotcf, "\n");
430*7c478bd9Sstevel@tonic-gate 	}
431*7c478bd9Sstevel@tonic-gate out:
432*7c478bd9Sstevel@tonic-gate 	fprintf(xdotcf, "};\n");
433*7c478bd9Sstevel@tonic-gate 	ignore(fclose(xdotcf));
434*7c478bd9Sstevel@tonic-gate 	ignore(fclose(strf));
435*7c478bd9Sstevel@tonic-gate }
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate char *
438*7c478bd9Sstevel@tonic-gate savestr(cp)
439*7c478bd9Sstevel@tonic-gate 	register char *cp;
440*7c478bd9Sstevel@tonic-gate {
441*7c478bd9Sstevel@tonic-gate 	register char *dp;
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate 	if ((dp = (char *) calloc(1, strlen(cp) + 1)) == NULL) {
444*7c478bd9Sstevel@tonic-gate 		perror("xstr");
445*7c478bd9Sstevel@tonic-gate 		exit(8);
446*7c478bd9Sstevel@tonic-gate 	}
447*7c478bd9Sstevel@tonic-gate 	return (strcpy(dp, cp));
448*7c478bd9Sstevel@tonic-gate }
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate lastchr(cp)
451*7c478bd9Sstevel@tonic-gate 	register char *cp;
452*7c478bd9Sstevel@tonic-gate {
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate 	while (cp[0] && cp[1])
455*7c478bd9Sstevel@tonic-gate 		cp++;
456*7c478bd9Sstevel@tonic-gate 	return (*cp);
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate istail(str, of)
460*7c478bd9Sstevel@tonic-gate 	register char *str, *of;
461*7c478bd9Sstevel@tonic-gate {
462*7c478bd9Sstevel@tonic-gate 	register int d = strlen(of) - strlen(str);
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 	if (d < 0 || strcmp(&of[d], str) != 0)
465*7c478bd9Sstevel@tonic-gate 		return (-1);
466*7c478bd9Sstevel@tonic-gate 	return (d);
467*7c478bd9Sstevel@tonic-gate }
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate void
470*7c478bd9Sstevel@tonic-gate onintr()
471*7c478bd9Sstevel@tonic-gate {
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate 	ignore(signal(SIGINT, SIG_IGN));
474*7c478bd9Sstevel@tonic-gate 	(void) cleanup();
475*7c478bd9Sstevel@tonic-gate 	ignore(unlink("x.c"));
476*7c478bd9Sstevel@tonic-gate 	ignore(unlink("xs.c"));
477*7c478bd9Sstevel@tonic-gate 	exit(7);
478*7c478bd9Sstevel@tonic-gate }
479*7c478bd9Sstevel@tonic-gate void
480*7c478bd9Sstevel@tonic-gate cleanup(void)
481*7c478bd9Sstevel@tonic-gate {
482*7c478bd9Sstevel@tonic-gate 	if (strings[0] == '/') {
483*7c478bd9Sstevel@tonic-gate 		ignore(unlink(strings));
484*7c478bd9Sstevel@tonic-gate 	}
485*7c478bd9Sstevel@tonic-gate }
486