Importing usr.bin/mkstr
No Minix-specific changes needed. Change-Id: I58a8e61dc300d9f54588526613dbc7aa54bf627b
This commit is contained in:
		
							parent
							
								
									3179b9b918
								
							
						
					
					
						commit
						69ccf97d12
					
				@ -407,6 +407,7 @@
 | 
			
		||||
./usr/bin/mkdir				minix-sys
 | 
			
		||||
./usr/bin/mkfifo			minix-sys
 | 
			
		||||
./usr/bin/mkproto			minix-sys	obsolete
 | 
			
		||||
./usr/bin/mkstr				minix-sys
 | 
			
		||||
./usr/bin/mktemp			minix-sys
 | 
			
		||||
./usr/bin/more				minix-sys
 | 
			
		||||
./usr/bin/mt				minix-sys
 | 
			
		||||
@ -1992,6 +1993,7 @@
 | 
			
		||||
./usr/man/man1/mkfs.1			minix-sys	obsolete
 | 
			
		||||
./usr/man/man1/mkfs.mfs.1		minix-sys
 | 
			
		||||
./usr/man/man1/mkproto.1		minix-sys
 | 
			
		||||
./usr/man/man1/mkstr.1			minix-sys
 | 
			
		||||
./usr/man/man1/mktemp.1			minix-sys
 | 
			
		||||
./usr/man/man1/more.1			minix-sys
 | 
			
		||||
./usr/man/man1/mount.1			minix-sys
 | 
			
		||||
 | 
			
		||||
@ -188,6 +188,7 @@
 | 
			
		||||
2010/07/07 21:24:34,usr.bin/man
 | 
			
		||||
2013/10/25 12:00:00,usr.bin/mesg
 | 
			
		||||
2010/10/15 05:46:48,usr.bin/mkdep
 | 
			
		||||
2012/10/17 12:00:00,usr.bin/mkstr
 | 
			
		||||
2009/08/15 20:44:56,usr.bin/mktemp
 | 
			
		||||
2012/10/17 12:00:00,usr.bin/nbperf
 | 
			
		||||
2013/10/10 12:00:00,usr.bin/nice
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ SUBDIR= asa \
 | 
			
		||||
	ldd leave \
 | 
			
		||||
	lock login logname lorder m4 \
 | 
			
		||||
	machine make man mesg \
 | 
			
		||||
	mkdep mktemp \
 | 
			
		||||
	mkdep mkstr mktemp \
 | 
			
		||||
	\
 | 
			
		||||
	nbperf newgrp nice nl nohup nvi \
 | 
			
		||||
	passwd paste pathchk pr \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								usr.bin/mkstr/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								usr.bin/mkstr/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
#	$NetBSD: Makefile,v 1.3 1995/09/28 06:22:18 tls Exp $
 | 
			
		||||
#	@(#)Makefile	8.1 (Berkeley) 6/6/93
 | 
			
		||||
 | 
			
		||||
PROG=	mkstr
 | 
			
		||||
 | 
			
		||||
.include <bsd.prog.mk>
 | 
			
		||||
							
								
								
									
										131
									
								
								usr.bin/mkstr/mkstr.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								usr.bin/mkstr/mkstr.1
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,131 @@
 | 
			
		||||
.\"	$NetBSD: mkstr.1,v 1.12 2012/05/12 14:52:57 reed Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.\" Copyright (c) 1980, 1990, 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. 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.
 | 
			
		||||
.\"
 | 
			
		||||
.\"     @(#)mkstr.1	8.1 (Berkeley) 6/6/93
 | 
			
		||||
.\"
 | 
			
		||||
.Dd June 6, 1993
 | 
			
		||||
.Dt MKSTR 1
 | 
			
		||||
.Os
 | 
			
		||||
.Sh NAME
 | 
			
		||||
.Nm mkstr
 | 
			
		||||
.Nd create an error message file by massaging C source
 | 
			
		||||
.Sh SYNOPSIS
 | 
			
		||||
.Nm
 | 
			
		||||
.Op Fl
 | 
			
		||||
.Ar messagefile
 | 
			
		||||
.Ar prefix file ...
 | 
			
		||||
.Sh DESCRIPTION
 | 
			
		||||
.Nm
 | 
			
		||||
creates files containing error messages extracted from C source,
 | 
			
		||||
and restructures the same C source, to use the created error message
 | 
			
		||||
file.
 | 
			
		||||
The intent of
 | 
			
		||||
.Nm
 | 
			
		||||
was to reduce the size of large programs and
 | 
			
		||||
reduce swapping (see
 | 
			
		||||
.Sx BUGS
 | 
			
		||||
section below).
 | 
			
		||||
.Pp
 | 
			
		||||
.Nm
 | 
			
		||||
processes each of the specified
 | 
			
		||||
.Ar files ,
 | 
			
		||||
placing a restructured version of the input in a file whose name
 | 
			
		||||
consists of the specified
 | 
			
		||||
.Ar prefix
 | 
			
		||||
and the original name.
 | 
			
		||||
A typical usage of
 | 
			
		||||
.Nm
 | 
			
		||||
is
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
mkstr pistrings xx *.c
 | 
			
		||||
.Ed
 | 
			
		||||
.Pp
 | 
			
		||||
This command causes all the error messages from the C source
 | 
			
		||||
files in the current directory to be placed in the file
 | 
			
		||||
.Ar pistrings
 | 
			
		||||
and restructured copies of the sources to be placed in
 | 
			
		||||
files whose names are prefixed with
 | 
			
		||||
.Ar \&xx .
 | 
			
		||||
.Pp
 | 
			
		||||
Options:
 | 
			
		||||
.Bl -tag -width indent
 | 
			
		||||
.It Fl
 | 
			
		||||
Error messages are placed at the end of the specified
 | 
			
		||||
message file for recompiling part of a large
 | 
			
		||||
.Nm
 | 
			
		||||
ed
 | 
			
		||||
program.
 | 
			
		||||
.El
 | 
			
		||||
.Pp
 | 
			
		||||
.Nm
 | 
			
		||||
finds error messages in the source by
 | 
			
		||||
searching for the string
 | 
			
		||||
.Li \&`error("'
 | 
			
		||||
in the input stream.
 | 
			
		||||
Each time it occurs, the C string starting at the
 | 
			
		||||
.Sq \&"\&
 | 
			
		||||
is stored
 | 
			
		||||
in the message file followed by a null character and a new-line character;
 | 
			
		||||
The new source is restructured with
 | 
			
		||||
.Xr lseek 2
 | 
			
		||||
pointers into the error message file for retrieval.
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
char efilname = "/usr/lib/pi_strings";
 | 
			
		||||
int efil = -1;
 | 
			
		||||
 | 
			
		||||
error(a1, a2, a3, a4)
 | 
			
		||||
\&{
 | 
			
		||||
	char buf[256];
 | 
			
		||||
 | 
			
		||||
	if (efil \*[Lt] 0) {
 | 
			
		||||
		efil = open(efilname, 0);
 | 
			
		||||
		if (efil \*[Lt] 0) {
 | 
			
		||||
oops:
 | 
			
		||||
			perror(efilname);
 | 
			
		||||
			exit 1 ;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (lseek(efil, a1, 0) \*[Lt] 0 || read(efil, buf, 256) \*[Le] 0)
 | 
			
		||||
		goto oops;
 | 
			
		||||
	printf(buf, a2, a3, a4);
 | 
			
		||||
}
 | 
			
		||||
.Ed
 | 
			
		||||
.Sh SEE ALSO
 | 
			
		||||
.Xr xstr 1 ,
 | 
			
		||||
.Xr lseek 2
 | 
			
		||||
.Sh HISTORY
 | 
			
		||||
.Nm
 | 
			
		||||
appeared in
 | 
			
		||||
.Bx 1 .
 | 
			
		||||
.Sh BUGS
 | 
			
		||||
.Nm
 | 
			
		||||
was intended for the limited architecture of the PDP-11 family.
 | 
			
		||||
Very few programs actually use it.
 | 
			
		||||
It is not an efficient method, the error messages
 | 
			
		||||
should be stored in the program text.
 | 
			
		||||
							
								
								
									
										321
									
								
								usr.bin/mkstr/mkstr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								usr.bin/mkstr/mkstr.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,321 @@
 | 
			
		||||
/*	$NetBSD: mkstr.c,v 1.16 2012/03/20 20:34:58 matt Exp $	*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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. 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#ifndef lint
 | 
			
		||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
 | 
			
		||||
 The Regents of the University of California.  All rights reserved.");
 | 
			
		||||
#endif /* not lint */
 | 
			
		||||
 | 
			
		||||
#ifndef lint
 | 
			
		||||
#if 0
 | 
			
		||||
static char sccsid[] = "@(#)mkstr.c	8.1 (Berkeley) 6/6/93";
 | 
			
		||||
#else
 | 
			
		||||
__RCSID("$NetBSD: mkstr.c,v 1.16 2012/03/20 20:34:58 matt Exp $");
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* not lint */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define	ungetchar(c)	ungetc(c, stdin)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
const char	usagestr[] =	"usage: %s [ - ] mesgfile prefix file ...\n";
 | 
			
		||||
char	name[100], *np;
 | 
			
		||||
 | 
			
		||||
void process(void);
 | 
			
		||||
int main(int, char **);
 | 
			
		||||
int match(const char *);
 | 
			
		||||
int octdigit(char);
 | 
			
		||||
void inithash(void);
 | 
			
		||||
long hashit(const char *, char, long);
 | 
			
		||||
void copystr(void);
 | 
			
		||||
int fgetNUL(char *, int, FILE *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(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++;
 | 
			
		||||
	strlcpy(name, argv[0], sizeof(name));
 | 
			
		||||
	np = name + strlen(name);
 | 
			
		||||
	argc--, argv++;
 | 
			
		||||
	do {
 | 
			
		||||
		strlcpy(np, argv[0], sizeof(name) - (np - name));
 | 
			
		||||
		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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
process(void)
 | 
			
		||||
{
 | 
			
		||||
	int 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();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
match(const char *ocp)
 | 
			
		||||
{
 | 
			
		||||
	const char *cp;
 | 
			
		||||
	int c;
 | 
			
		||||
 | 
			
		||||
	for (cp = ocp + 1; *cp; cp++) {
 | 
			
		||||
		c = getchar();
 | 
			
		||||
		if (c != *cp) {
 | 
			
		||||
			while (ocp < cp)
 | 
			
		||||
				putchar(*ocp++);
 | 
			
		||||
			ungetchar(c);
 | 
			
		||||
			return (0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
copystr(void)
 | 
			
		||||
{
 | 
			
		||||
	int c, ch;
 | 
			
		||||
	char buf[512];
 | 
			
		||||
	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("%ld", hashit(buf, 1, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
octdigit(char c)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (c >= '0' && c <= '7');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
inithash(void)
 | 
			
		||||
{
 | 
			
		||||
	char buf[512];
 | 
			
		||||
	long mesgpt = 0;
 | 
			
		||||
 | 
			
		||||
	rewind(mesgread);
 | 
			
		||||
	while (fgetNUL(buf, sizeof buf, mesgread) != 0) {
 | 
			
		||||
		hashit(buf, 0, mesgpt);
 | 
			
		||||
		mesgpt += strlen(buf) + 2;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define	NBUCKETS	511
 | 
			
		||||
 | 
			
		||||
struct	hash {
 | 
			
		||||
	long	hval;
 | 
			
		||||
	long	hpt;
 | 
			
		||||
	struct	hash *hnext;
 | 
			
		||||
} *bucket[NBUCKETS];
 | 
			
		||||
 | 
			
		||||
long
 | 
			
		||||
hashit(const char *str, char really, long fakept)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	struct hash *hp;
 | 
			
		||||
	char buf[512];
 | 
			
		||||
	long hashval = 0;
 | 
			
		||||
	const char *cp;
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
	hp = NULL;	/* XXX gcc */
 | 
			
		||||
#endif
 | 
			
		||||
	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, hp->hpt, 0);
 | 
			
		||||
			fgetNUL(buf, sizeof buf, mesgread);
 | 
			
		||||
/*
 | 
			
		||||
			fprintf(stderr, "Got (from %ld) %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 %ld\n", str, hp->hval, hp->hpt);
 | 
			
		||||
*/
 | 
			
		||||
	return (hp->hpt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fgetNUL(char *obuf, int rmdr, FILE *file)
 | 
			
		||||
{
 | 
			
		||||
	int c;
 | 
			
		||||
	char *buf = obuf;
 | 
			
		||||
 | 
			
		||||
	while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)
 | 
			
		||||
		*buf++ = c;
 | 
			
		||||
	*buf++ = 0;
 | 
			
		||||
	getc(file);
 | 
			
		||||
	return ((feof(file) || ferror(file)) ? 0 : 1);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user