xref: /illumos-gate/usr/src/cmd/xstr/xstr.c (revision a6959a06)
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	*/
7*a6959a06SToomas Soome /*	  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 
157c478bd9Sstevel@tonic-gate #include <stdio.h>
167c478bd9Sstevel@tonic-gate #include <ctype.h>
177c478bd9Sstevel@tonic-gate #include <sys/types.h>
187c478bd9Sstevel@tonic-gate #include <signal.h>
197c478bd9Sstevel@tonic-gate #include <stdlib.h>
208d489c7aSmuffin #include <string.h>
218d489c7aSmuffin #include <unistd.h>
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate /*
247c478bd9Sstevel@tonic-gate  * xstr - extract and hash strings in a C program
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * Bill Joy UCB
277c478bd9Sstevel@tonic-gate  * November, 1978
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate off_t	tellpt;
318d489c7aSmuffin off_t	hashit(char *, int);
328d489c7aSmuffin void	onintr(void);
338d489c7aSmuffin char	*savestr(char *);
348d489c7aSmuffin off_t	yankstr(char **);
358d489c7aSmuffin void	cleanup(void);
368d489c7aSmuffin void	process(char *);
378d489c7aSmuffin int	octdigit(char);
388d489c7aSmuffin void	inithash(void);
398d489c7aSmuffin void	flushsh(void);
408d489c7aSmuffin void	found(int, off_t, char *);
418d489c7aSmuffin void	prstr(char *);
428d489c7aSmuffin void	xsdotc(void);
438d489c7aSmuffin int	fgetNUL(char *, int, FILE *);
448d489c7aSmuffin int	xgetc(FILE *);
458d489c7aSmuffin int	lastchr(char *);
468d489c7aSmuffin int	istail(char *, char *);
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate off_t	mesgpt;
497c478bd9Sstevel@tonic-gate char	*strings =	"strings";
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate int	cflg;
527c478bd9Sstevel@tonic-gate int	vflg;
537c478bd9Sstevel@tonic-gate char	*xname = "xstr";
547c478bd9Sstevel@tonic-gate int	readstd;
557c478bd9Sstevel@tonic-gate int	tmpfd;
567c478bd9Sstevel@tonic-gate 
578d489c7aSmuffin int
main(int argc,char ** argv)588d489c7aSmuffin main(int argc, char **argv)
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 	argc--, argv++;
617c478bd9Sstevel@tonic-gate 	while (argc > 0 && argv[0][0] == '-') {
628d489c7aSmuffin 		char *cp = &(*argv++)[1];
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 		argc--;
657c478bd9Sstevel@tonic-gate 		if (*cp == 0) {
667c478bd9Sstevel@tonic-gate 			readstd++;
677c478bd9Sstevel@tonic-gate 			continue;
687c478bd9Sstevel@tonic-gate 		}
697c478bd9Sstevel@tonic-gate 		do switch (*cp++) {
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 		case 'c':
727c478bd9Sstevel@tonic-gate 			cflg++;
737c478bd9Sstevel@tonic-gate 			continue;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 		case 'l':
767c478bd9Sstevel@tonic-gate 			xname = *argv++;
777c478bd9Sstevel@tonic-gate 			argc--;
787c478bd9Sstevel@tonic-gate 			continue;
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 		case 'v':
817c478bd9Sstevel@tonic-gate 			vflg++;
827c478bd9Sstevel@tonic-gate 			continue;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 		default:
858d489c7aSmuffin 			(void) fprintf(stderr,
867c478bd9Sstevel@tonic-gate 		"usage: xstr [ -v ] [ -c ] [ -l label ] [ - ] [ name ... ]\n");
877c478bd9Sstevel@tonic-gate 		} while (*cp);
887c478bd9Sstevel@tonic-gate 	}
897c478bd9Sstevel@tonic-gate 	if (signal(SIGINT, SIG_IGN) == SIG_DFL)
908d489c7aSmuffin 		(void) signal(SIGINT, (void (*)(int))onintr);
917c478bd9Sstevel@tonic-gate 	if (cflg || argc == 0 && !readstd)
927c478bd9Sstevel@tonic-gate 		inithash();
937c478bd9Sstevel@tonic-gate 	else {
947c478bd9Sstevel@tonic-gate 		strings = savestr("/tmp/xstrXXXXXX");
957c478bd9Sstevel@tonic-gate 		tmpfd = mkstemp(strings);
967c478bd9Sstevel@tonic-gate 		if (tmpfd == -1) {
977c478bd9Sstevel@tonic-gate 			perror(strings);
987c478bd9Sstevel@tonic-gate 			(void) free(strings);
997c478bd9Sstevel@tonic-gate 			exit(9);
1007c478bd9Sstevel@tonic-gate 		}
1017c478bd9Sstevel@tonic-gate 		(void) close(tmpfd);
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 	while (readstd || argc > 0) {
1047c478bd9Sstevel@tonic-gate 		if (freopen("x.c", "w", stdout) == NULL)
1057c478bd9Sstevel@tonic-gate 			perror("x.c"), (void) cleanup(), exit(1);
1067c478bd9Sstevel@tonic-gate 		if (!readstd && freopen(argv[0], "r", stdin) == NULL)
1077c478bd9Sstevel@tonic-gate 			perror(argv[0]), (void) cleanup(), exit(2);
1087c478bd9Sstevel@tonic-gate 		process("x.c");
1097c478bd9Sstevel@tonic-gate 		if (readstd == 0)
1107c478bd9Sstevel@tonic-gate 			argc--, argv++;
1117c478bd9Sstevel@tonic-gate 		else
1127c478bd9Sstevel@tonic-gate 			readstd = 0;
1138d489c7aSmuffin 	}
1147c478bd9Sstevel@tonic-gate 	flushsh();
1157c478bd9Sstevel@tonic-gate 	if (cflg == 0)
1167c478bd9Sstevel@tonic-gate 		xsdotc();
1177c478bd9Sstevel@tonic-gate 	(void) cleanup();
1188d489c7aSmuffin 	return (0);
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate char linebuf[BUFSIZ];
1227c478bd9Sstevel@tonic-gate 
1238d489c7aSmuffin void
process(char * name)1248d489c7aSmuffin process(char *name)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	char *cp;
1278d489c7aSmuffin 	int c;
1288d489c7aSmuffin 	int incomm = 0;
1297c478bd9Sstevel@tonic-gate 	int ret;
1307c478bd9Sstevel@tonic-gate 
1318d489c7aSmuffin 	(void) printf("extern char\t%s[];\n", xname);
1327c478bd9Sstevel@tonic-gate 	for (;;) {
1337c478bd9Sstevel@tonic-gate 		if (fgets(linebuf, sizeof (linebuf), stdin) == NULL) {
1347c478bd9Sstevel@tonic-gate 			if (ferror(stdin)) {
1357c478bd9Sstevel@tonic-gate 				perror(name);
1367c478bd9Sstevel@tonic-gate 				(void) cleanup();
1377c478bd9Sstevel@tonic-gate 				exit(3);
1387c478bd9Sstevel@tonic-gate 			}
1397c478bd9Sstevel@tonic-gate 			break;
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 		if (linebuf[0] == '#') {
1427c478bd9Sstevel@tonic-gate 			if (linebuf[1] == ' ' && isdigit(linebuf[2]))
1438d489c7aSmuffin 				(void) printf("#line%s", &linebuf[1]);
1447c478bd9Sstevel@tonic-gate 			else
1458d489c7aSmuffin 				(void) printf("%s", linebuf);
1467c478bd9Sstevel@tonic-gate 			continue;
1477c478bd9Sstevel@tonic-gate 		}
1488d489c7aSmuffin 		for (cp = linebuf; (c = *cp++) != 0; ) {
1497c478bd9Sstevel@tonic-gate 			switch (c) {
1507c478bd9Sstevel@tonic-gate 				case '"':
1517c478bd9Sstevel@tonic-gate 					if (incomm)
1527c478bd9Sstevel@tonic-gate 						goto def;
1538d489c7aSmuffin 					if ((ret = (int)yankstr(&cp)) == -1)
1547c478bd9Sstevel@tonic-gate 						goto out;
1558d489c7aSmuffin 					(void) printf("(&%s[%d])", xname, ret);
1567c478bd9Sstevel@tonic-gate 					break;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 				case '\'':
1597c478bd9Sstevel@tonic-gate 					if (incomm)
1607c478bd9Sstevel@tonic-gate 						goto def;
1618d489c7aSmuffin 					(void) putchar(c);
1627c478bd9Sstevel@tonic-gate 					if (*cp)
1638d489c7aSmuffin 						(void) putchar(*cp++);
1647c478bd9Sstevel@tonic-gate 					break;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 				case '/':
1677c478bd9Sstevel@tonic-gate 					if (incomm || *cp != '*')
1687c478bd9Sstevel@tonic-gate 						goto def;
1697c478bd9Sstevel@tonic-gate 					incomm = 1;
1707c478bd9Sstevel@tonic-gate 					cp++;
1718d489c7aSmuffin 					(void) printf("/*");
1727c478bd9Sstevel@tonic-gate 					continue;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 				case '*':
1757c478bd9Sstevel@tonic-gate 					if (incomm && *cp == '/') {
1767c478bd9Sstevel@tonic-gate 						incomm = 0;
1777c478bd9Sstevel@tonic-gate 						cp++;
1788d489c7aSmuffin 						(void) printf("*/");
1797c478bd9Sstevel@tonic-gate 						continue;
1807c478bd9Sstevel@tonic-gate 					}
1817c478bd9Sstevel@tonic-gate 					goto def;
1827c478bd9Sstevel@tonic-gate def:
1837c478bd9Sstevel@tonic-gate 				default:
1848d489c7aSmuffin 					(void) putchar(c);
1857c478bd9Sstevel@tonic-gate 					break;
1867c478bd9Sstevel@tonic-gate 			}
1877c478bd9Sstevel@tonic-gate 		}
1887c478bd9Sstevel@tonic-gate 	}
1897c478bd9Sstevel@tonic-gate out:
1907c478bd9Sstevel@tonic-gate 	if (ferror(stdout))
1917c478bd9Sstevel@tonic-gate 		perror("x.c"), onintr();
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate off_t
yankstr(char ** cpp)1958d489c7aSmuffin yankstr(char **cpp)
1967c478bd9Sstevel@tonic-gate {
1978d489c7aSmuffin 	char *cp = *cpp;
1988d489c7aSmuffin 	int c, ch;
1997c478bd9Sstevel@tonic-gate 	char dbuf[BUFSIZ];
2008d489c7aSmuffin 	char *dp = dbuf;
2018d489c7aSmuffin 	char *tp;
2027c478bd9Sstevel@tonic-gate 
2038d489c7aSmuffin 	while ((c = *cp++) != 0) {
2047c478bd9Sstevel@tonic-gate 		switch (c) {
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 		case '"':
2077c478bd9Sstevel@tonic-gate 			cp++;
2087c478bd9Sstevel@tonic-gate 			goto out;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 		case '\\':
2117c478bd9Sstevel@tonic-gate 			c = *cp++;
2127c478bd9Sstevel@tonic-gate 			if (c == 0)
2137c478bd9Sstevel@tonic-gate 				break;
2147c478bd9Sstevel@tonic-gate 			if (c == '\n') {
2157c478bd9Sstevel@tonic-gate 				if (fgets(linebuf, sizeof (linebuf), stdin)
2167c478bd9Sstevel@tonic-gate 				    == NULL) {
2177c478bd9Sstevel@tonic-gate 					if (ferror(stdin)) {
2187c478bd9Sstevel@tonic-gate 						perror("x.c");
2197c478bd9Sstevel@tonic-gate 						(void) cleanup();
2207c478bd9Sstevel@tonic-gate 						exit(3);
2217c478bd9Sstevel@tonic-gate 					}
2227c478bd9Sstevel@tonic-gate 					return (-1);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 				}
2257c478bd9Sstevel@tonic-gate 				cp = linebuf;
2267c478bd9Sstevel@tonic-gate 				continue;
2277c478bd9Sstevel@tonic-gate 			}
2288d489c7aSmuffin 			for (tp = "b\bt\tr\rn\nf\f\\\\\"\""; (ch = *tp++) != 0;
2298d489c7aSmuffin 			    tp++)
2307c478bd9Sstevel@tonic-gate 				if (c == ch) {
2317c478bd9Sstevel@tonic-gate 					c = *tp;
2327c478bd9Sstevel@tonic-gate 					goto gotc;
2337c478bd9Sstevel@tonic-gate 				}
2347c478bd9Sstevel@tonic-gate 			if (!octdigit(c)) {
2357c478bd9Sstevel@tonic-gate 				*dp++ = '\\';
2367c478bd9Sstevel@tonic-gate 				break;
2377c478bd9Sstevel@tonic-gate 			}
2387c478bd9Sstevel@tonic-gate 			c -= '0';
2397c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
2407c478bd9Sstevel@tonic-gate 				break;
2417c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
2427c478bd9Sstevel@tonic-gate 			if (!octdigit(*cp))
2437c478bd9Sstevel@tonic-gate 				break;
2447c478bd9Sstevel@tonic-gate 			c <<= 3, c += *cp++ - '0';
2457c478bd9Sstevel@tonic-gate 			break;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate gotc:
2487c478bd9Sstevel@tonic-gate 		*dp++ = c;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate out:
2517c478bd9Sstevel@tonic-gate 	*cpp = --cp;
2527c478bd9Sstevel@tonic-gate 	*dp = 0;
2537c478bd9Sstevel@tonic-gate 	return (hashit(dbuf, 1));
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate 
2568d489c7aSmuffin int
octdigit(char c)2578d489c7aSmuffin octdigit(char c)
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	return (isdigit(c) && c != '8' && c != '9');
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate 
2638d489c7aSmuffin void
inithash(void)2648d489c7aSmuffin inithash(void)
2657c478bd9Sstevel@tonic-gate {
2667c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
2678d489c7aSmuffin 	FILE *mesgread = fopen(strings, "r");
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	if (mesgread == NULL)
2707c478bd9Sstevel@tonic-gate 		return;
2717c478bd9Sstevel@tonic-gate 	for (;;) {
2727c478bd9Sstevel@tonic-gate 		mesgpt = tellpt;
273*a6959a06SToomas Soome 		if (fgetNUL(buf, sizeof (buf), mesgread) == 0)
2747c478bd9Sstevel@tonic-gate 			break;
2758d489c7aSmuffin 		(void) hashit(buf, 0);
2767c478bd9Sstevel@tonic-gate 	}
2778d489c7aSmuffin 	(void) fclose(mesgread);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate 
2808d489c7aSmuffin int
fgetNUL(char * obuf,int rmdr,FILE * file)2818d489c7aSmuffin fgetNUL(char *obuf, int rmdr, FILE *file)
2827c478bd9Sstevel@tonic-gate {
2838d489c7aSmuffin 	int c;
2848d489c7aSmuffin 	char *buf = obuf;
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	while (--rmdr > 0 && (c = xgetc(file)) != 0 && c != EOF)
2877c478bd9Sstevel@tonic-gate 		*buf++ = c;
2887c478bd9Sstevel@tonic-gate 	*buf++ = 0;
289*a6959a06SToomas Soome 	return ((feof(file) || ferror(file)) ? 0 : 1);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate 
2928d489c7aSmuffin int
xgetc(FILE * file)2938d489c7aSmuffin xgetc(FILE *file)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	tellpt++;
2977c478bd9Sstevel@tonic-gate 	return (getc(file));
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate #define	BUCKETS	128
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate struct	hash {
3037c478bd9Sstevel@tonic-gate 	off_t	hpt;
3047c478bd9Sstevel@tonic-gate 	char	*hstr;
3057c478bd9Sstevel@tonic-gate 	struct	hash *hnext;
3067c478bd9Sstevel@tonic-gate 	short	hnew;
3077c478bd9Sstevel@tonic-gate } bucket[BUCKETS];
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate off_t
hashit(char * str,int new)3108d489c7aSmuffin hashit(char *str, int new)
3117c478bd9Sstevel@tonic-gate {
3127c478bd9Sstevel@tonic-gate 	int i;
3138d489c7aSmuffin 	struct hash *hp, *hp0;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	hp = hp0 = &bucket[lastchr(str) & 0177];
3167c478bd9Sstevel@tonic-gate 	while (hp->hnext) {
3177c478bd9Sstevel@tonic-gate 		hp = hp->hnext;
3187c478bd9Sstevel@tonic-gate 		i = istail(str, hp->hstr);
3197c478bd9Sstevel@tonic-gate 		if (i >= 0)
3207c478bd9Sstevel@tonic-gate 			return (hp->hpt + i);
3217c478bd9Sstevel@tonic-gate 	}
3228d489c7aSmuffin 	if ((hp = calloc(1, sizeof (*hp))) == NULL) {
3237c478bd9Sstevel@tonic-gate 		perror("xstr");
3247c478bd9Sstevel@tonic-gate 		(void) cleanup();
3257c478bd9Sstevel@tonic-gate 		exit(8);
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 	hp->hpt = mesgpt;
3287c478bd9Sstevel@tonic-gate 	hp->hstr = savestr(str);
3297c478bd9Sstevel@tonic-gate 	mesgpt += strlen(hp->hstr) + 1;
3307c478bd9Sstevel@tonic-gate 	hp->hnext = hp0->hnext;
3317c478bd9Sstevel@tonic-gate 	hp->hnew = new;
3327c478bd9Sstevel@tonic-gate 	hp0->hnext = hp;
3337c478bd9Sstevel@tonic-gate 	return (hp->hpt);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate 
3368d489c7aSmuffin void
flushsh(void)3378d489c7aSmuffin flushsh(void)
3387c478bd9Sstevel@tonic-gate {
3398d489c7aSmuffin 	int i;
3408d489c7aSmuffin 	struct hash *hp;
3418d489c7aSmuffin 	FILE *mesgwrit;
3428d489c7aSmuffin 	int old = 0, new = 0;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
3457c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext)
3467c478bd9Sstevel@tonic-gate 			if (hp->hnew)
3477c478bd9Sstevel@tonic-gate 				new++;
3487c478bd9Sstevel@tonic-gate 			else
3497c478bd9Sstevel@tonic-gate 				old++;
3507c478bd9Sstevel@tonic-gate 	if (new == 0 && old != 0)
3517c478bd9Sstevel@tonic-gate 		return;
3527c478bd9Sstevel@tonic-gate 	mesgwrit = fopen(strings, old ? "r+" : "w");
3537c478bd9Sstevel@tonic-gate 	if (mesgwrit == NULL)
3547c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
3557c478bd9Sstevel@tonic-gate 	for (i = 0; i < BUCKETS; i++)
3567c478bd9Sstevel@tonic-gate 		for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) {
3577c478bd9Sstevel@tonic-gate 			found(hp->hnew, hp->hpt, hp->hstr);
3587c478bd9Sstevel@tonic-gate 			if (hp->hnew) {
3598d489c7aSmuffin 				(void) fseek(mesgwrit, hp->hpt, 0);
3608d489c7aSmuffin 				(void) fwrite(hp->hstr,
3618d489c7aSmuffin 				    strlen(hp->hstr) + 1, 1, mesgwrit);
3627c478bd9Sstevel@tonic-gate 				if (ferror(mesgwrit)) {
3637c478bd9Sstevel@tonic-gate 					perror(strings);
3647c478bd9Sstevel@tonic-gate 					(void) cleanup();
3657c478bd9Sstevel@tonic-gate 					exit(4);
3667c478bd9Sstevel@tonic-gate 				}
3677c478bd9Sstevel@tonic-gate 			}
3687c478bd9Sstevel@tonic-gate 		}
3697c478bd9Sstevel@tonic-gate 	if (fclose(mesgwrit) == EOF)
3707c478bd9Sstevel@tonic-gate 		perror(strings), (void) cleanup(), exit(4);
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3738d489c7aSmuffin void
found(int new,off_t off,char * str)3748d489c7aSmuffin found(int new, off_t off, char *str)
3757c478bd9Sstevel@tonic-gate {
3767c478bd9Sstevel@tonic-gate 	if (vflg == 0)
3777c478bd9Sstevel@tonic-gate 		return;
3787c478bd9Sstevel@tonic-gate 	if (!new)
3798d489c7aSmuffin 		(void) fprintf(stderr, "found at %d:", (int)off);
3807c478bd9Sstevel@tonic-gate 	else
3818d489c7aSmuffin 		(void) fprintf(stderr, "new at %d:", (int)off);
3827c478bd9Sstevel@tonic-gate 	prstr(str);
3838d489c7aSmuffin 	(void) fprintf(stderr, "\n");
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate 
3868d489c7aSmuffin void
prstr(char * cp)3878d489c7aSmuffin prstr(char *cp)
3887c478bd9Sstevel@tonic-gate {
3898d489c7aSmuffin 	int c;
3907c478bd9Sstevel@tonic-gate 
3918d489c7aSmuffin 	while ((c = (*cp++ & 0377)) != 0)
3927c478bd9Sstevel@tonic-gate 		if (c < ' ')
3938d489c7aSmuffin 			(void) fprintf(stderr, "^%c", c + '`');
3947c478bd9Sstevel@tonic-gate 		else if (c == 0177)
3958d489c7aSmuffin 			(void) fprintf(stderr, "^?");
3967c478bd9Sstevel@tonic-gate 		else if (c > 0200)
3978d489c7aSmuffin 			(void) fprintf(stderr, "\\%03o", c);
3987c478bd9Sstevel@tonic-gate 		else
3998d489c7aSmuffin 			(void) fprintf(stderr, "%c", c);
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate 
4028d489c7aSmuffin void
xsdotc(void)4038d489c7aSmuffin xsdotc(void)
4047c478bd9Sstevel@tonic-gate {
4058d489c7aSmuffin 	FILE *strf = fopen(strings, "r");
4068d489c7aSmuffin 	FILE *xdotcf;
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	if (strf == NULL)
4097c478bd9Sstevel@tonic-gate 		perror(strings), exit(5);
4107c478bd9Sstevel@tonic-gate 	xdotcf = fopen("xs.c", "w");
4117c478bd9Sstevel@tonic-gate 	if (xdotcf == NULL)
4127c478bd9Sstevel@tonic-gate 		perror("xs.c"), exit(6);
4138d489c7aSmuffin 	(void) fprintf(xdotcf, "char\t%s[] = {\n", xname);
4147c478bd9Sstevel@tonic-gate 	for (;;) {
4158d489c7aSmuffin 		int i, c;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 		for (i = 0; i < 8; i++) {
4187c478bd9Sstevel@tonic-gate 			c = getc(strf);
4197c478bd9Sstevel@tonic-gate 			if (ferror(strf)) {
4207c478bd9Sstevel@tonic-gate 				perror(strings);
4217c478bd9Sstevel@tonic-gate 				onintr();
4227c478bd9Sstevel@tonic-gate 			}
4237c478bd9Sstevel@tonic-gate 			if (feof(strf)) {
4248d489c7aSmuffin 				(void) fprintf(xdotcf, "\n");
4257c478bd9Sstevel@tonic-gate 				goto out;
4267c478bd9Sstevel@tonic-gate 			}
4278d489c7aSmuffin 			(void) fprintf(xdotcf, "0x%02x,", c);
4287c478bd9Sstevel@tonic-gate 		}
4298d489c7aSmuffin 		(void) fprintf(xdotcf, "\n");
4307c478bd9Sstevel@tonic-gate 	}
4317c478bd9Sstevel@tonic-gate out:
4328d489c7aSmuffin 	(void) fprintf(xdotcf, "};\n");
4338d489c7aSmuffin 	(void) fclose(xdotcf);
4348d489c7aSmuffin 	(void) fclose(strf);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate char *
savestr(char * cp)4388d489c7aSmuffin savestr(char *cp)
4397c478bd9Sstevel@tonic-gate {
4408d489c7aSmuffin 	char *dp;
4417c478bd9Sstevel@tonic-gate 
4428d489c7aSmuffin 	if ((dp = calloc(1, strlen(cp) + 1)) == NULL) {
4437c478bd9Sstevel@tonic-gate 		perror("xstr");
4447c478bd9Sstevel@tonic-gate 		exit(8);
4457c478bd9Sstevel@tonic-gate 	}
4467c478bd9Sstevel@tonic-gate 	return (strcpy(dp, cp));
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate 
4498d489c7aSmuffin int
lastchr(char * cp)4508d489c7aSmuffin lastchr(char *cp)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	while (cp[0] && cp[1])
4547c478bd9Sstevel@tonic-gate 		cp++;
4558d489c7aSmuffin 	return ((int)*cp);
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate 
4588d489c7aSmuffin int
istail(char * str,char * of)4598d489c7aSmuffin istail(char *str, char *of)
4607c478bd9Sstevel@tonic-gate {
4618d489c7aSmuffin 	int d = strlen(of) - strlen(str);
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	if (d < 0 || strcmp(&of[d], str) != 0)
4647c478bd9Sstevel@tonic-gate 		return (-1);
4657c478bd9Sstevel@tonic-gate 	return (d);
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate void
onintr(void)4698d489c7aSmuffin onintr(void)
4707c478bd9Sstevel@tonic-gate {
4717c478bd9Sstevel@tonic-gate 
4728d489c7aSmuffin 	(void) signal(SIGINT, SIG_IGN);
4737c478bd9Sstevel@tonic-gate 	(void) cleanup();
4748d489c7aSmuffin 	(void) unlink("x.c");
4758d489c7aSmuffin 	(void) unlink("xs.c");
4767c478bd9Sstevel@tonic-gate 	exit(7);
4777c478bd9Sstevel@tonic-gate }
4788d489c7aSmuffin 
4797c478bd9Sstevel@tonic-gate void
cleanup(void)4807c478bd9Sstevel@tonic-gate cleanup(void)
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate 	if (strings[0] == '/') {
4838d489c7aSmuffin 		(void) unlink(strings);
4847c478bd9Sstevel@tonic-gate 	}
4857c478bd9Sstevel@tonic-gate }
486