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
main(int argc,char ** argv)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
process(char * name)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
yankstr(char ** cpp)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
octdigit(char c)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
inithash(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
fgetNUL(char * obuf,int rmdr,FILE * file)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
xgetc(FILE * file)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
hashit(char * str,int new)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
flushsh(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
found(int new,off_t off,char * str)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
prstr(char * cp)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
xsdotc(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 *
savestr(char * cp)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
lastchr(char * cp)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
istail(char * str,char * of)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
onintr(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
cleanup(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