home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1980 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- #ifndef lint
- char copyright[] =
- "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
- All rights reserved.\n";
- #endif /* not lint */
-
- #ifndef lint
- static char sccsid[] = "@(#)xstr.c 5.7 (Berkeley) 2/26/91";
- #endif /* not lint */
-
- #include <sys/types.h>
- #include <signal.h>
- #include <errno.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include "pathnames.h"
-
- /*
- * xstr - extract and hash strings in a C program
- *
- * Bill Joy UCB
- * November, 1978
- */
-
- #define ignore(a) ((void) a)
-
- off_t tellpt;
- off_t hashit();
- void onintr();
- char *savestr();
- off_t yankstr();
-
- off_t mesgpt;
- char *strings = "strings";
-
- int cflg;
- int vflg;
- int readstd;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- argc--, argv++;
- while (argc > 0 && argv[0][0] == '-') {
- register char *cp = &(*argv++)[1];
-
- argc--;
- if (*cp == 0) {
- readstd++;
- continue;
- }
- do switch (*cp++) {
-
- case 'c':
- cflg++;
- continue;
-
- case 'v':
- vflg++;
- continue;
-
- default:
- fprintf(stderr, "usage: xstr [ -v ] [ -c ] [ - ] [ name ... ]\n");
- } while (*cp);
- }
- if (signal(SIGINT, SIG_IGN) == SIG_DFL)
- signal(SIGINT, onintr);
- if (cflg || argc == 0 && !readstd)
- inithash();
- else
- strings = mktemp(strdup(_PATH_TMP));
- while (readstd || argc > 0) {
- if (freopen("x.c", "w", stdout) == NULL)
- perror("x.c"), exit(1);
- if (!readstd && freopen(argv[0], "r", stdin) == NULL)
- perror(argv[0]), exit(2);
- process("x.c");
- if (readstd == 0)
- argc--, argv++;
- else
- readstd = 0;
- };
- flushsh();
- if (cflg == 0)
- xsdotc();
- if (strings[0] == '/')
- ignore(unlink(strings));
- exit(0);
- }
-
- char linebuf[BUFSIZ];
-
- process(name)
- char *name;
- {
- char *cp;
- register int c;
- register int incomm = 0;
- int ret;
-
- printf("extern char\txstr[];\n");
- for (;;) {
- if (fgets(linebuf, sizeof linebuf, stdin) == NULL) {
- if (ferror(stdin)) {
- perror(name);
- exit(3);
- }
- break;
- }
- if (linebuf[0] == '#') {
- if (linebuf[1] == ' ' && isdigit(linebuf[2]))
- printf("#line%s", &linebuf[1]);
- else
- printf("%s", linebuf);
- continue;
- }
- for (cp = linebuf; c = *cp++;) switch (c) {
-
- case '"':
- if (incomm)
- goto def;
- if ((ret = (int) yankstr(&cp)) == -1)
- goto out;
- printf("(&xstr[%d])", ret);
- break;
-
- case '\'':
- if (incomm)
- goto def;
- putchar(c);
- if (*cp)
- putchar(*cp++);
- break;
-
- case '/':
- if (incomm || *cp != '*')
- goto def;
- incomm = 1;
- cp++;
- printf("/*");
- continue;
-
- case '*':
- if (incomm && *cp == '/') {
- incomm = 0;
- cp++;
- printf("*/");
- continue;
- }
- goto def;
-
- def:
- default:
- putchar(c);
- break;
- }
- }
- out:
- if (ferror(stdout))
- perror("x.c"), onintr();
- }
-
- off_t
- yankstr(cpp)
- register char **cpp;
- {
- register char *cp = *cpp;
- register int c, ch;
- char dbuf[BUFSIZ];
- register char *dp = dbuf;
- register char *tp;
-
- while (c = *cp++) {
- switch (c) {
-
- case '"':
- cp++;
- goto out;
-
- case '\\':
- c = *cp++;
- if (c == 0)
- break;
- if (c == '\n') {
- if (fgets(linebuf, sizeof linebuf, stdin)
- == NULL) {
- if (ferror(stdin)) {
- perror("x.c");
- exit(3);
- }
- return(-1);
- }
- cp = linebuf;
- continue;
- }
- for (tp = "b\bt\tr\rn\nf\f\\\\\"\""; ch = *tp++; tp++)
- if (c == ch) {
- c = *tp;
- goto gotc;
- }
- if (!octdigit(c)) {
- *dp++ = '\\';
- break;
- }
- c -= '0';
- if (!octdigit(*cp))
- break;
- c <<= 3, c += *cp++ - '0';
- if (!octdigit(*cp))
- break;
- c <<= 3, c += *cp++ - '0';
- break;
- }
- gotc:
- *dp++ = c;
- }
- out:
- *cpp = --cp;
- *dp = 0;
- return (hashit(dbuf, 1));
- }
-
- octdigit(c)
- char c;
- {
-
- return (isdigit(c) && c != '8' && c != '9');
- }
-
- inithash()
- {
- char buf[BUFSIZ];
- register FILE *mesgread = fopen(strings, "r");
-
- if (mesgread == NULL)
- return;
- for (;;) {
- mesgpt = tellpt;
- if (fgetNUL(buf, sizeof buf, mesgread) == NULL)
- break;
- ignore(hashit(buf, 0));
- }
- ignore(fclose(mesgread));
- }
-
- fgetNUL(obuf, rmdr, file)
- char *obuf;
- register int rmdr;
- FILE *file;
- {
- register c;
- register char *buf = obuf;
-
- while (--rmdr > 0 && (c = xgetc(file)) != 0 && c != EOF)
- *buf++ = c;
- *buf++ = 0;
- return ((feof(file) || ferror(file)) ? NULL : 1);
- }
-
- xgetc(file)
- FILE *file;
- {
-
- tellpt++;
- return (getc(file));
- }
-
- #define BUCKETS 128
-
- struct hash {
- off_t hpt;
- char *hstr;
- struct hash *hnext;
- short hnew;
- } bucket[BUCKETS];
-
- off_t
- hashit(str, new)
- char *str;
- int new;
- {
- int i;
- register struct hash *hp, *hp0;
-
- hp = hp0 = &bucket[lastchr(str) & 0177];
- while (hp->hnext) {
- hp = hp->hnext;
- i = istail(str, hp->hstr);
- if (i >= 0)
- return (hp->hpt + i);
- }
- if ((hp = (struct hash *) calloc(1, sizeof (*hp))) == NULL) {
- perror("xstr");
- exit(8);
- }
- hp->hpt = mesgpt;
- if (!(hp->hstr = strdup(str))) {
- (void)fprintf(stderr, "xstr: %s\n", strerror(errno));
- exit(1);
- }
- mesgpt += strlen(hp->hstr) + 1;
- hp->hnext = hp0->hnext;
- hp->hnew = new;
- hp0->hnext = hp;
- return (hp->hpt);
- }
-
- flushsh()
- {
- register int i;
- register struct hash *hp;
- register FILE *mesgwrit;
- register int old = 0, new = 0;
-
- for (i = 0; i < BUCKETS; i++)
- for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext)
- if (hp->hnew)
- new++;
- else
- old++;
- if (new == 0 && old != 0)
- return;
- mesgwrit = fopen(strings, old ? "r+" : "w");
- if (mesgwrit == NULL)
- perror(strings), exit(4);
- for (i = 0; i < BUCKETS; i++)
- for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) {
- found(hp->hnew, hp->hpt, hp->hstr);
- if (hp->hnew) {
- fseek(mesgwrit, hp->hpt, 0);
- ignore(fwrite(hp->hstr, strlen(hp->hstr) + 1, 1, mesgwrit));
- if (ferror(mesgwrit))
- perror(strings), exit(4);
- }
- }
- if (fclose(mesgwrit) == EOF)
- perror(strings), exit(4);
- }
-
- found(new, off, str)
- int new;
- off_t off;
- char *str;
- {
- if (vflg == 0)
- return;
- if (!new)
- fprintf(stderr, "found at %d:", (int) off);
- else
- fprintf(stderr, "new at %d:", (int) off);
- prstr(str);
- fprintf(stderr, "\n");
- }
-
- prstr(cp)
- register char *cp;
- {
- register int c;
-
- while (c = (*cp++ & 0377))
- if (c < ' ')
- fprintf(stderr, "^%c", c + '`');
- else if (c == 0177)
- fprintf(stderr, "^?");
- else if (c > 0200)
- fprintf(stderr, "\\%03o", c);
- else
- fprintf(stderr, "%c", c);
- }
-
- xsdotc()
- {
- register FILE *strf = fopen(strings, "r");
- register FILE *xdotcf;
-
- if (strf == NULL)
- perror(strings), exit(5);
- xdotcf = fopen("xs.c", "w");
- if (xdotcf == NULL)
- perror("xs.c"), exit(6);
- fprintf(xdotcf, "char\txstr[] = {\n");
- for (;;) {
- register int i, c;
-
- for (i = 0; i < 8; i++) {
- c = getc(strf);
- if (ferror(strf)) {
- perror(strings);
- onintr();
- }
- if (feof(strf)) {
- fprintf(xdotcf, "\n");
- goto out;
- }
- fprintf(xdotcf, "0x%02x,", c);
- }
- fprintf(xdotcf, "\n");
- }
- out:
- fprintf(xdotcf, "};\n");
- ignore(fclose(xdotcf));
- ignore(fclose(strf));
- }
-
- lastchr(cp)
- register char *cp;
- {
-
- while (cp[0] && cp[1])
- cp++;
- return (*cp);
- }
-
- istail(str, of)
- register char *str, *of;
- {
- register int d = strlen(of) - strlen(str);
-
- if (d < 0 || strcmp(&of[d], str) != 0)
- return (-1);
- return (d);
- }
-
- void
- onintr()
- {
-
- ignore(signal(SIGINT, SIG_IGN));
- if (strings[0] == '/')
- ignore(unlink(strings));
- ignore(unlink("x.c"));
- ignore(unlink("xs.c"));
- exit(7);
- }
-