mkstr.c

来自「早期freebsd实现」· C语言 代码 · 共 311 行

C
311
字号
/* * Copyright (c) 1980, 1993 *	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 lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)mkstr.c	8.1 (Berkeley) 6/6/93";#endif /* not lint */#include <stdio.h>#define	ungetchar(c)	ungetc(c, stdin)long	ftell();char	*calloc();/* * mkstr - create a string error message file by massaging C source * * Bill Joy UCB August 1977 * * Modified March 1978 to hash old messages to be able to recompile * without addding messages to the message file (usually) * * Based on an earlier program conceived by Bill Joy and Chuck Haley * * Program to create a string error message file * from a group of C programs.  Arguments are the name * of the file where the strings are to be placed, the * prefix of the new files where the processed source text * is to be placed, and the files to be processed. * * The program looks for 'error("' in the source stream. * Whenever it finds this, the following characters from the '"' * to a '"' are replaced by 'seekpt' where seekpt is a * pointer into the error message file. * If the '(' is not immediately followed by a '"' no change occurs. * * The optional '-' causes strings to be added at the end of the * existing error message file for recompilation of single routines. */FILE	*mesgread, *mesgwrite;char	*progname;char	usagestr[] =	"usage: %s [ - ] mesgfile prefix file ...\n";char	name[100], *np;main(argc, argv)	int argc;	char *argv[];{	char addon = 0;	argc--, progname = *argv++;	if (argc > 1 && argv[0][0] == '-')		addon++, argc--, argv++;	if (argc < 3)		fprintf(stderr, usagestr, progname), exit(1);	mesgwrite = fopen(argv[0], addon ? "a" : "w");	if (mesgwrite == NULL)		perror(argv[0]), exit(1);	mesgread = fopen(argv[0], "r");	if (mesgread == NULL)		perror(argv[0]), exit(1);	inithash();	argc--, argv++;	strcpy(name, argv[0]);	np = name + strlen(name);	argc--, argv++;	do {		strcpy(np, argv[0]);		if (freopen(name, "w", stdout) == NULL)			perror(name), exit(1);		if (freopen(argv[0], "r", stdin) == NULL)			perror(argv[0]), exit(1);		process();		argc--, argv++;	} while (argc > 0);	exit(0);}process(){	register char *cp;	register c;	for (;;) {		c = getchar();		if (c == EOF)			return;		if (c != 'e') {			putchar(c);			continue;		}		if (match("error(")) {			printf("error(");			c = getchar();			if (c != '"')				putchar(c);			else				copystr();		}	}}match(ocp)	char *ocp;{	register char *cp;	register c;	for (cp = ocp + 1; *cp; cp++) {		c = getchar();		if (c != *cp) {			while (ocp < cp)				putchar(*ocp++);			ungetchar(c);			return (0);		}	}	return (1);}copystr(){	register c, ch;	char buf[512];	register char *cp = buf;	for (;;) {		c = getchar();		if (c == EOF)			break;		switch (c) {		case '"':			*cp++ = 0;			goto out;		case '\\':			c = getchar();			switch (c) {			case 'b':				c = '\b';				break;			case 't':				c = '\t';				break;			case 'r':				c = '\r';				break;			case 'n':				c = '\n';				break;			case '\n':				continue;			case 'f':				c = '\f';				break;			case '0':				c = 0;				break;			case '\\':				break;			default:				if (!octdigit(c))					break;				c -= '0';				ch = getchar();				if (!octdigit(ch))					break;				c <<= 7, c += ch - '0';				ch = getchar();				if (!octdigit(ch))					break;				c <<= 3, c+= ch - '0', ch = -1;				break;			}		}		*cp++ = c;	}out:	*cp = 0;	printf("%d", hashit(buf, 1, NULL));}octdigit(c)	char c;{	return (c >= '0' && c <= '7');}inithash(){	char buf[512];	int mesgpt = 0;	rewind(mesgread);	while (fgetNUL(buf, sizeof buf, mesgread) != NULL) {		hashit(buf, 0, mesgpt);		mesgpt += strlen(buf) + 2;	}}#define	NBUCKETS	511struct	hash {	long	hval;	unsigned hpt;	struct	hash *hnext;} *bucket[NBUCKETS];hashit(str, really, fakept)	char *str;	char really;	unsigned fakept;{	int i;	register struct hash *hp;	char buf[512];	long hashval = 0;	register char *cp;	if (really)		fflush(mesgwrite);	for (cp = str; *cp;)		hashval = (hashval << 1) + *cp++;	i = hashval % NBUCKETS;	if (i < 0)		i += NBUCKETS;	if (really != 0)		for (hp = bucket[i]; hp != 0; hp = hp->hnext)		if (hp->hval == hashval) {			fseek(mesgread, (long) hp->hpt, 0);			fgetNUL(buf, sizeof buf, mesgread);/*			fprintf(stderr, "Got (from %d) %s\n", hp->hpt, buf);*/			if (strcmp(buf, str) == 0)				break;		}	if (!really || hp == 0) {		hp = (struct hash *) calloc(1, sizeof *hp);		hp->hnext = bucket[i];		hp->hval = hashval;		hp->hpt = really ? ftell(mesgwrite) : fakept;		if (really) {			fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite);			fwrite("\n", sizeof (char), 1, mesgwrite);		}		bucket[i] = hp;	}/*	fprintf(stderr, "%s hashed to %ld at %d\n", str, hp->hval, hp->hpt);*/	return (hp->hpt);}#include <sys/types.h>#include <sys/stat.h>fgetNUL(obuf, rmdr, file)	char *obuf;	register int rmdr;	FILE *file;{	register c;	register char *buf = obuf;	while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)		*buf++ = c;	*buf++ = 0;	getc(file);	return ((feof(file) || ferror(file)) ? NULL : 1);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?