xref: /titanic_51/usr/src/cmd/xstr/xstr.c (revision 8d489c7a815fcac696803219572e95aa01532b0f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
15*8d489c7aSmuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include <stdio.h>
187c478bd9Sstevel@tonic-gate #include <ctype.h>
197c478bd9Sstevel@tonic-gate #include <sys/types.h>
207c478bd9Sstevel@tonic-gate #include <signal.h>
217c478bd9Sstevel@tonic-gate #include <stdlib.h>
22*8d489c7aSmuffin #include <string.h>
23*8d489c7aSmuffin #include <unistd.h>
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * xstr - extract and hash strings in a C program
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  * Bill Joy UCB
297c478bd9Sstevel@tonic-gate  * November, 1978
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate off_t	tellpt;
33*8d489c7aSmuffin off_t	hashit(char *, int);
34*8d489c7aSmuffin void	onintr(void);
35*8d489c7aSmuffin char	*savestr(char *);
36*8d489c7aSmuffin off_t	yankstr(char **);
37*8d489c7aSmuffin void	cleanup(void);
38*8d489c7aSmuffin void	process(char *);
39*8d489c7aSmuffin int	octdigit(char);
40*8d489c7aSmuffin void	inithash(void);
41*8d489c7aSmuffin void	flushsh(void);
42*8d489c7aSmuffin void	found(int, off_t, char *);
43*8d489c7aSmuffin void	prstr(char *);
44*8d489c7aSmuffin void	xsdotc(void);
45*8d489c7aSmuffin int	fgetNUL(char *, int, FILE *);
46*8d489c7aSmuffin int	xgetc(FILE *);
47*8d489c7aSmuffin int	lastchr(char *);
48*8d489c7aSmuffin int	istail(char *, char *);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate off_t	mesgpt;
517c478bd9Sstevel@tonic-gate char	*strings =	"strings";
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate int	cflg;
547c478bd9Sstevel@tonic-gate int	vflg;
557c478bd9Sstevel@tonic-gate char	*xname = "xstr";
567c478bd9Sstevel@tonic-gate int	readstd;
577c478bd9Sstevel@tonic-gate int	tmpfd;
587c478bd9Sstevel@tonic-gate 
59*8d489c7aSmuffin int
60*8d489c7aSmuffin main(int argc, char **argv)
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate 	argc--, argv++;
637c478bd9Sstevel@tonic-gate 	while (argc > 0 && argv[0][0] == '-') {
64*8d489c7aSmuffin 		char *cp = &(*argv++)[1];
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 		argc--;
677c478bd9Sstevel@tonic-gate 		if (*cp == 0) {
687c478bd9Sstevel@tonic-gate 			readstd++;
697c478bd9Sstevel@tonic-gate 			continue;
707c478bd9Sstevel@tonic-gate 		}
717c478bd9Sstevel@tonic-gate 		do switch (*cp++) {
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 		case 'c':
747c478bd9Sstevel@tonic-gate 			cflg++;
757c478bd9Sstevel@tonic-gate 			continue;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 		case 'l':
787c478bd9Sstevel@tonic-gate 			xname = *argv++;
797c478bd9Sstevel@tonic-gate 			argc--;
807c478bd9Sstevel@tonic-gate 			continue;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 		case 'v':
837c478bd9Sstevel@tonic-gate 			vflg++;
847c478bd9Sstevel@tonic-gate 			continue;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 		default:
87*8d489c7aSmuffin 			(void) fprintf(stderr,
887c478bd9Sstevel@tonic-gate 		"usage: xstr [ -v ] [ -c ] [ -l label ] [ - ] [ name ... ]\n");
897c478bd9Sstevel@tonic-gate 		} while (*cp);
907c478bd9Sstevel@tonic-gate 	}
917c478bd9Sstevel@tonic-gate 	if (signal(SIGINT, SIG_IGN) == SIG_DFL)
92*8d489c7aSmuffin 		(void) signal(SIGINT, (void (*)(int))onintr);
937c478bd9Sstevel@tonic-gate 	if (cflg || argc == 0 && !readstd)
947c478bd9Sstevel@tonic-gate 		inithash();
957c478bd9Sstevel@tonic-gate 	else {
967c478bd9Sstevel@tonic-gate 		strings = savestr("/tmp/xstrXXXXXX");
977c478bd9Sstevel@tonic-gate 		tmpfd = mkstemp(strings);
987c478bd9Sstevel@tonic-gate 		if (tmpfd == -1) {
997c478bd9Sstevel@tonic-gate 			perror(strings);
1007c478bd9Sstevel@tonic-gate 			(void) free(strings);
1017c478bd9Sstevel@tonic-gate 			exit(9);
1027c478bd9Sstevel@tonic-gate 		}
1037c478bd9Sstevel@tonic-gate 		(void) close(tmpfd);
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 	while (readstd || argc > 0) {
1067c478bd9Sstevel@tonic-gate 		if (freopen("x.c", "w", stdout) == NULL)
1077c478bd9Sstevel@tonic-gate 			perror("x.c"), (void) cleanup(), exit(1);
1087c478bd9Sstevel@tonic-gate 		if (!readstd && freopen(argv[0], "r", stdin) == NULL)
1097c478bd9Sstevel@tonic-gate 			perror(argv[0]), (void) cleanup(), exit(2);
1107c478bd9Sstevel@tonic-gate 		process("x.c");
1117c478bd9Sstevel@tonic-gate 		if (readstd == 0)
1127c478bd9Sstevel@tonic-gate 			argc--, argv++;
1137c478bd9Sstevel@tonic-gate 		else
1147c478bd9Sstevel@tonic-gate 			readstd = 0;
115*8d489c7aSmuffin 	}
1167c478bd9Sstevel@tonic-gate 	flushsh();
1177c478bd9Sstevel@tonic-gate 	if (cflg == 0)
1187c478bd9Sstevel@tonic-gate 		xsdotc();
1197c478bd9Sstevel@tonic-gate 	(void) cleanup();
120*8d489c7aSmuffin 	return (0);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate char linebuf[BUFSIZ];
1247c478bd9Sstevel@tonic-gate 
125*8d489c7aSmuffin void
126*8d489c7aSmuffin process(char *name)
1277c478bd9Sstevel@tonic-gate {
1287c478bd9Sstevel@tonic-gate 	char *cp;
129*8d489c7aSmuffin 	int c;
130*8d489c7aSmuffin 	int incomm = 0;
1317c478bd9Sstevel@tonic-gate 	int ret;
1327c478bd9Sstevel@tonic-gate 
133*8d489c7aSmuffin 	(void) printf("extern char\t%s[];\n", xname);
1347c478bd9Sstevel@tonic-gate 	for (;;) {
1357c478bd9Sstevel@tonic-gate 		if (fgets(linebuf, sizeof (linebuf), stdin) == NULL) {
1367c478bd9Sstevel@tonic-gate 			if (ferror(stdin)) {
1377c478bd9Sstevel@tonic-gate 				perror(name);
1387c478bd9Sstevel@tonic-gate 				(void) cleanup();
1397c478bd9Sstevel@tonic-gate 				exit(3);
1407c478bd9Sstevel@tonic-gate 			}
1417c478bd9Sstevel@tonic-gate 			break;
1427c478bd9Sstevel@tonic-gate 		}
1437c478bd9Sstevel@tonic-gate 		if (linebuf[0] == '#') {
1447c478bd9Sstevel@tonic-gate 			if (linebuf[1] == ' ' && isdigit(linebuf[2]))
145*8d489c7aSmuffin 				(void) printf("#line%s", &linebuf[1]);
1467c478bd9Sstevel@tonic-gate 			else
147*8d489c7aSmuffin 				(void) printf("%s", linebuf);
1487c478bd9Sstevel@tonic-gate 			continue;
1497c478bd9Sstevel@tonic-gate 		}
150*8d489c7aSmuffin 		for (cp = linebuf; (c = *cp++) != 0; ) {
1517c478bd9Sstevel@tonic-gate 			switch (c) {
1527c478bd9Sstevel@tonic-gate 				case '"':
1537c478bd9Sstevel@tonic-gate 					if (incomm)
1547c478bd9Sstevel@tonic-gate 						goto def;
1557c478bd9Sstevel@tonic-gate 					if ((ret = (int)yankstr(&cp)) == -1)
1567c478bd9Sstevel@tonic-gate 						goto out;
157*8d489c7aSmuffin 					(void) printf("(&%s[%d])", xname, ret);
1587c478bd9Sstevel@tonic-gate 					break;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 				case '\'':
1617c478bd9Sstevel@tonic-gate 					if (incomm)
1627c478bd9Sstevel@tonic-gate 						goto def;
163*8d489c7aSmuffin 					(void) putchar(c);
1647c478bd9Sstevel@tonic-gate 					if (*cp)
165*8d489c7aSmuffin 						(void) putchar(*cp++);
1667c478bd9Sstevel@tonic-gate 					break;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 				case '/':
1697c478bd9Sstevel@tonic-gate 					if (incomm || *cp != '*')
1707c478bd9Sstevel@tonic-gate 						goto def;
1717c478bd9Sstevel@tonic-gate 					incomm = 1;
1727c478bd9Sstevel@tonic-gate 					cp++;
173*8d489c7aSmuffin 					(void) printf("/*");
1747c478bd9Sstevel@tonic-gate 					continue;
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 				case '*':
1777c478bd9Sstevel@tonic-gate 					if (incomm && *cp == '/') {
1787c478bd9Sstevel@tonic-gate 						incomm = 0;
1797c478bd9Sstevel@tonic-gate 						cp++;
180*8d489c7aSmuffin 						(void) printf("*/");
1817c478bd9Sstevel@tonic-gate 						continue;
1827c478bd9Sstevel@tonic-gate 					}
1837c478bd9Sstevel@tonic-gate 					goto def;
1847c478bd9Sstevel@tonic-gate def:
1857c478bd9Sstevel@tonic-gate 				default:
186*8d489c7aSmuffin 					(void) putchar(c);
1877c478bd9Sstevel@tonic-gate 					break;
1887c478bd9Sstevel@tonic-gate 			}
1897c478bd9Sstevel@tonic-gate 		}
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate out:
1927c478bd9Sstevel@tonic-gate 	if (ferror(stdout))
1937c478bd9Sstevel@tonic-gate 		perror("x.c"), onintr();
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate off_t
197*8d489c7aSmuffin yankstr(char **cpp)
1987c478bd9Sstevel@tonic-gate {
199*8d489c7aSmuffin 	char *cp = *cpp;
200*8d489c7aSmuffin 	int c, ch;
2017c478bd9Sstevel@tonic-gate 	char dbuf[BUFSIZ];
202*8d489c7aSmuffin 	char *dp = dbuf;
203*8d489c7aSmuffin 	char *tp;
2047c478bd9Sstevel@tonic-gate 
205*8d489c7aSmuffin 	while ((c = *cp++) != 0) {
2067c478bd9Sstevel@tonic-gate 		switch (c) {
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 		case '"':
2097c478bd9Sstevel@tonic-gate 			cp++;
2107c478bd9Sstevel@tonic-gate 			goto out;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		case '\\':
2137c478bd9Sstevel@tonic-gate 			c = *cp++;
2147c478bd9Sstevel@tonic-gate 			if (c == 0)
2157c478bd9Sstevel@tonic-gate 				break;
2167c478bd9Sstevel@tonic-gate 			if (c == '\n') {
2177c478bd9Sstevel@tonic-gate 				if (fgets(linebuf, sizeof (linebuf), stdin)
2187c478bd9Sstevel@tonic-gate 				    == NULL) {
2197c478bd9Sstevel@tonic-gate 					if (ferror(stdin)) {
2207c478bd9Sstevel@tonic-gate 						perror("x.c");
2217c478bd9Sstevel@tonic-gate 						(void) cleanup();
2227c478bd9Sstevel@tonic-gate 						exit(3);
2237c478bd9Sstevel@tonic-gate 					}
2247c478bd9Sstevel@tonic-gate 					return (-1);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 				}
2277c478bd9Sstevel@tonic-gate 				cp = linebuf;
2287c478bd9Sstevel@tonic-gate 				continue;
2297c478bd9Sstevel@tonic-gate 			}
230*8d489c7aSmuffin 			for (tp = "b\bt\tr\rn\nf\f\\\\\"\""; (ch = *tp++) != 0;
231*8d489c7aSmuffin 			    tp++)
2327c478bd9Sstevel@tonic-gate 				if (c == ch) {
2337c478bd9Sstevel@tonic-gate 					c = *tp;
2347c478bd9Sstevel@tonic-gate 					goto gotc;
2357c478bd9Sstevel@tonic-gate 				}
2367c478bd9Sstevel@tonic-gate 			if (!octdigit(c)) {
2377c478bd9Sstevel@tonic-gate 				*dp++ = '\\';
2387c478bd9Sstevel@tonic-gate 				break;
2397c478bd9Sstevel@tonic-gate 			}
2407c478bd9Sstevel@tonic-gate 			c -= '0';
2417c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
2427c478bd9Sstevel@tonic-gate 				break;
2437c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
2447c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
2457c478bd9Sstevel@tonic-gate 				break;
2467c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
2477c478bd9Sstevel@tonic-gate 			break;
2487c478bd9Sstevel@tonic-gate 		}
2497c478bd9Sstevel@tonic-gate gotc:
2507c478bd9Sstevel@tonic-gate 		*dp++ = c;
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate out:
2537c478bd9Sstevel@tonic-gate 	*cpp = --cp;
2547c478bd9Sstevel@tonic-gate 	*dp = 0;
2557c478bd9Sstevel@tonic-gate 	return (hashit(dbuf, 1));
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate 
258*8d489c7aSmuffin int
259*8d489c7aSmuffin octdigit(char c)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	return (isdigit(c) && c != '8' && c != '9');
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate 
265*8d489c7aSmuffin void
266*8d489c7aSmuffin inithash(void)
2677c478bd9Sstevel@tonic-gate {
2687c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
269*8d489c7aSmuffin 	FILE *mesgread = fopen(strings, "r");
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	if (mesgread == NULL)
2727c478bd9Sstevel@tonic-gate 		return;
2737c478bd9Sstevel@tonic-gate 	for (;;) {
2747c478bd9Sstevel@tonic-gate 		mesgpt = tellpt;
2757c478bd9Sstevel@tonic-gate 		if (fgetNUL(buf, sizeof (buf), mesgread) == NULL)
2767c478bd9Sstevel@tonic-gate 			break;
277*8d489c7aSmuffin 		(void) hashit(buf, 0);
2787c478bd9Sstevel@tonic-gate 	}
279*8d489c7aSmuffin 	(void) fclose(mesgread);
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
282*8d489c7aSmuffin int
283*8d489c7aSmuffin fgetNUL(char *obuf, int rmdr, FILE *file)
2847c478bd9Sstevel@tonic-gate {
285*8d489c7aSmuffin 	int c;
286*8d489c7aSmuffin 	char *buf = obuf;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	while (--rmdr > 0 && (c = xgetc(file)) != 0 && c != EOF)
2897c478bd9Sstevel@tonic-gate 		*buf++ = c;
2907c478bd9Sstevel@tonic-gate 	*buf++ = 0;
2917c478bd9Sstevel@tonic-gate 	return ((feof(file) || ferror(file)) ? NULL : 1);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
294*8d489c7aSmuffin int
295*8d489c7aSmuffin xgetc(FILE *file)
2967c478bd9Sstevel@tonic-gate {
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	tellpt++;
2997c478bd9Sstevel@tonic-gate 	return (getc(file));
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate #define	BUCKETS	128
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate struct	hash {
3057c478bd9Sstevel@tonic-gate 	off_t	hpt;
3067c478bd9Sstevel@tonic-gate 	char	*hstr;
3077c478bd9Sstevel@tonic-gate 	struct	hash *hnext;
3087c478bd9Sstevel@tonic-gate 	short	hnew;
3097c478bd9Sstevel@tonic-gate } bucket[BUCKETS];
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate off_t
312*8d489c7aSmuffin hashit(char *str, int new)
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate 	int i;
315*8d489c7aSmuffin 	struct hash *hp, *hp0;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	hp = hp0 = &bucket[lastchr(str) & 0177];
3187c478bd9Sstevel@tonic-gate 	while (hp->hnext) {
3197c478bd9Sstevel@tonic-gate 		hp = hp->hnext;
3207c478bd9Sstevel@tonic-gate 		i = istail(str, hp->hstr);
3217c478bd9Sstevel@tonic-gate 		if (i >= 0)
3227c478bd9Sstevel@tonic-gate 			return (hp->hpt + i);
3237c478bd9Sstevel@tonic-gate 	}
324*8d489c7aSmuffin 	if ((hp = calloc(1, sizeof (*hp))) == NULL) {
3257c478bd9Sstevel@tonic-gate 		perror("xstr");
3267c478bd9Sstevel@tonic-gate 		(void) cleanup();
3277c478bd9Sstevel@tonic-gate 		exit(8);
3287c478bd9Sstevel@tonic-gate 	}
3297c478bd9Sstevel@tonic-gate 	hp->hpt = mesgpt;
3307c478bd9Sstevel@tonic-gate 	hp->hstr = savestr(str);
3317c478bd9Sstevel@tonic-gate 	mesgpt += strlen(hp->hstr) + 1;
3327c478bd9Sstevel@tonic-gate 	hp->hnext = hp0->hnext;
3337c478bd9Sstevel@tonic-gate 	hp->hnew = new;
3347c478bd9Sstevel@tonic-gate 	hp0->hnext = hp;
3357c478bd9Sstevel@tonic-gate 	return (hp->hpt);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate 
338*8d489c7aSmuffin void
339*8d489c7aSmuffin flushsh(void)
3407c478bd9Sstevel@tonic-gate {
341*8d489c7aSmuffin 	int i;
342*8d489c7aSmuffin 	struct hash *hp;
343*8d489c7aSmuffin 	FILE *mesgwrit;
344*8d489c7aSmuffin 	int old = 0, new = 0;
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
3477c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext)
3487c478bd9Sstevel@tonic-gate 			if (hp->hnew)
3497c478bd9Sstevel@tonic-gate 				new++;
3507c478bd9Sstevel@tonic-gate 			else
3517c478bd9Sstevel@tonic-gate 				old++;
3527c478bd9Sstevel@tonic-gate 	if (new == 0 && old != 0)
3537c478bd9Sstevel@tonic-gate 		return;
3547c478bd9Sstevel@tonic-gate 	mesgwrit = fopen(strings, old ? "r+" : "w");
3557c478bd9Sstevel@tonic-gate 	if (mesgwrit == NULL)
3567c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
3577c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
3587c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) {
3597c478bd9Sstevel@tonic-gate 			found(hp->hnew, hp->hpt, hp->hstr);
3607c478bd9Sstevel@tonic-gate 			if (hp->hnew) {
361*8d489c7aSmuffin 				(void) fseek(mesgwrit, hp->hpt, 0);
362*8d489c7aSmuffin 				(void) fwrite(hp->hstr,
363*8d489c7aSmuffin 				    strlen(hp->hstr) + 1, 1, mesgwrit);
3647c478bd9Sstevel@tonic-gate 				if (ferror(mesgwrit)) {
3657c478bd9Sstevel@tonic-gate 					perror(strings);
3667c478bd9Sstevel@tonic-gate 					(void) cleanup();
3677c478bd9Sstevel@tonic-gate 					exit(4);
3687c478bd9Sstevel@tonic-gate 				}
3697c478bd9Sstevel@tonic-gate 			}
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 	if (fclose(mesgwrit) == EOF)
3727c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate 
375*8d489c7aSmuffin void
376*8d489c7aSmuffin found(int new, off_t off, char *str)
3777c478bd9Sstevel@tonic-gate {
3787c478bd9Sstevel@tonic-gate 	if (vflg == 0)
3797c478bd9Sstevel@tonic-gate 		return;
3807c478bd9Sstevel@tonic-gate 	if (!new)
381*8d489c7aSmuffin 		(void) fprintf(stderr, "found at %d:", (int)off);
3827c478bd9Sstevel@tonic-gate 	else
383*8d489c7aSmuffin 		(void) fprintf(stderr, "new at %d:", (int)off);
3847c478bd9Sstevel@tonic-gate 	prstr(str);
385*8d489c7aSmuffin 	(void) fprintf(stderr, "\n");
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate 
388*8d489c7aSmuffin void
389*8d489c7aSmuffin prstr(char *cp)
3907c478bd9Sstevel@tonic-gate {
391*8d489c7aSmuffin 	int c;
3927c478bd9Sstevel@tonic-gate 
393*8d489c7aSmuffin 	while ((c = (*cp++ & 0377)) != 0)
3947c478bd9Sstevel@tonic-gate 		if (c < ' ')
395*8d489c7aSmuffin 			(void) fprintf(stderr, "^%c", c + '`');
3967c478bd9Sstevel@tonic-gate 		else if (c == 0177)
397*8d489c7aSmuffin 			(void) fprintf(stderr, "^?");
3987c478bd9Sstevel@tonic-gate 		else if (c > 0200)
399*8d489c7aSmuffin 			(void) fprintf(stderr, "\\%03o", c);
4007c478bd9Sstevel@tonic-gate 		else
401*8d489c7aSmuffin 			(void) fprintf(stderr, "%c", c);
4027c478bd9Sstevel@tonic-gate }
4037c478bd9Sstevel@tonic-gate 
404*8d489c7aSmuffin void
405*8d489c7aSmuffin xsdotc(void)
4067c478bd9Sstevel@tonic-gate {
407*8d489c7aSmuffin 	FILE *strf = fopen(strings, "r");
408*8d489c7aSmuffin 	FILE *xdotcf;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	if (strf == NULL)
4117c478bd9Sstevel@tonic-gate 		perror(strings), exit(5);
4127c478bd9Sstevel@tonic-gate 	xdotcf = fopen("xs.c", "w");
4137c478bd9Sstevel@tonic-gate 	if (xdotcf == NULL)
4147c478bd9Sstevel@tonic-gate 		perror("xs.c"), exit(6);
415*8d489c7aSmuffin 	(void) fprintf(xdotcf, "char\t%s[] = {\n", xname);
4167c478bd9Sstevel@tonic-gate 	for (;;) {
417*8d489c7aSmuffin 		int i, c;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
4207c478bd9Sstevel@tonic-gate 			c = getc(strf);
4217c478bd9Sstevel@tonic-gate 			if (ferror(strf)) {
4227c478bd9Sstevel@tonic-gate 				perror(strings);
4237c478bd9Sstevel@tonic-gate 				onintr();
4247c478bd9Sstevel@tonic-gate 			}
4257c478bd9Sstevel@tonic-gate 			if (feof(strf)) {
426*8d489c7aSmuffin 				(void) fprintf(xdotcf, "\n");
4277c478bd9Sstevel@tonic-gate 				goto out;
4287c478bd9Sstevel@tonic-gate 			}
429*8d489c7aSmuffin 			(void) fprintf(xdotcf, "0x%02x,", c);
4307c478bd9Sstevel@tonic-gate 		}
431*8d489c7aSmuffin 		(void) fprintf(xdotcf, "\n");
4327c478bd9Sstevel@tonic-gate 	}
4337c478bd9Sstevel@tonic-gate out:
434*8d489c7aSmuffin 	(void) fprintf(xdotcf, "};\n");
435*8d489c7aSmuffin 	(void) fclose(xdotcf);
436*8d489c7aSmuffin 	(void) fclose(strf);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate char *
440*8d489c7aSmuffin savestr(char *cp)
4417c478bd9Sstevel@tonic-gate {
442*8d489c7aSmuffin 	char *dp;
4437c478bd9Sstevel@tonic-gate 
444*8d489c7aSmuffin 	if ((dp = calloc(1, strlen(cp) + 1)) == NULL) {
4457c478bd9Sstevel@tonic-gate 		perror("xstr");
4467c478bd9Sstevel@tonic-gate 		exit(8);
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 	return (strcpy(dp, cp));
4497c478bd9Sstevel@tonic-gate }
4507c478bd9Sstevel@tonic-gate 
451*8d489c7aSmuffin int
452*8d489c7aSmuffin lastchr(char *cp)
4537c478bd9Sstevel@tonic-gate {
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	while (cp[0] && cp[1])
4567c478bd9Sstevel@tonic-gate 		cp++;
457*8d489c7aSmuffin 	return ((int)*cp);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate 
460*8d489c7aSmuffin int
461*8d489c7aSmuffin istail(char *str, char *of)
4627c478bd9Sstevel@tonic-gate {
463*8d489c7aSmuffin 	int d = strlen(of) - strlen(str);
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	if (d < 0 || strcmp(&of[d], str) != 0)
4667c478bd9Sstevel@tonic-gate 		return (-1);
4677c478bd9Sstevel@tonic-gate 	return (d);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate void
471*8d489c7aSmuffin onintr(void)
4727c478bd9Sstevel@tonic-gate {
4737c478bd9Sstevel@tonic-gate 
474*8d489c7aSmuffin 	(void) signal(SIGINT, SIG_IGN);
4757c478bd9Sstevel@tonic-gate 	(void) cleanup();
476*8d489c7aSmuffin 	(void) unlink("x.c");
477*8d489c7aSmuffin 	(void) unlink("xs.c");
4787c478bd9Sstevel@tonic-gate 	exit(7);
4797c478bd9Sstevel@tonic-gate }
480*8d489c7aSmuffin 
4817c478bd9Sstevel@tonic-gate void
4827c478bd9Sstevel@tonic-gate cleanup(void)
4837c478bd9Sstevel@tonic-gate {
4847c478bd9Sstevel@tonic-gate 	if (strings[0] == '/') {
485*8d489c7aSmuffin 		(void) unlink(strings);
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate }
488