Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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