[comp.sources.unix] v11i079: C cross-reference database system, Part02/03

rsalz@uunet.UU.NET (Rich Salz) (09/26/87)

Submitted-by: sun!suneast!kumquat!gmcgary (Greg Mcgary - Sun ECD Software)
Posting-number: Volume 11, Issue 79
Archive-name: id/Part02



#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	basename.c
#	bitcount.c
#	bitops.c
#	bitsvec.c
#	bsearch.c
#	bzero.c
#	document.c
#	fid.c
#	gets0.c
#	getsFF.c
#	getscan.c
#	hash.c
#	idx.c
#	init.c
#	lid.c
export PATH; PATH=/bin:$PATH
echo shar: extracting "'basename.c'" '(433 characters)'
sed 's/^X//' << \SHAR_EOF > 'basename.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)basename.c	1.1 86/10/09";
X
X#include	<string.h>
X
Xchar *basename();
Xchar *dirname();
X
Xchar *
Xbasename(path)
X	char		*path;
X{
X	char		*base;
X
X	if ((base = strrchr(path, '/')) == 0)
X		return path;
X	else
X		return ++base;
X}
X
Xchar *
Xdirname(path)
X	char		*path;
X{
X	char		*base;
X
X	if ((base = strrchr(path, '/')) == 0)
X		return ".";
X	else
X		return strnsav(path, base - path);
X}
SHAR_EOF
if test 433 -ne "`wc -c < 'basename.c'`"
then
	echo shar: error transmitting "'basename.c'" '(should have been 433 characters)'
fi
echo shar: extracting "'bitcount.c'" '(643 characters)'
sed 's/^X//' << \SHAR_EOF > 'bitcount.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bitcount.c	1.1 86/10/09";
X
Xint bitCount();
Xint bitsCount();
X
X/*
X	Count the number of 1 bits in the given integer.
X*/
Xstatic char bitcnt[] = {
X/*	0 1 2 3 4 5 6 7	8 9 a b c d e f	*/
X	0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4
X};
Xint
XbitCount(mask)
X	register unsigned	mask;
X{
X	register int	nybbles = 8;
X	register int	cnt = 0;
X
X	while (mask && nybbles--) {
X		cnt += bitcnt[mask&0xf];
X		mask >>= 4;
X	}
X	return cnt;
X}
X
Xint
XbitsCount(bitv, n)
X	register char	*bitv;
X	register int	n;
X{
X	register int	count = 0;
X
X	while (n--) {
X		count += bitcnt[*bitv&0xf] + bitcnt[(*bitv>>4)&0xf];
X		bitv++;
X	}
X}
SHAR_EOF
if test 643 -ne "`wc -c < 'bitcount.c'`"
then
	echo shar: error transmitting "'bitcount.c'" '(should have been 643 characters)'
fi
echo shar: extracting "'bitops.c'" '(992 characters)'
sed 's/^X//' << \SHAR_EOF > 'bitops.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bitops.c	1.1 86/10/09";
X
X#include	<bitops.h>
X
Xchar *bitsset();
Xchar *bitsclr();
Xchar *bitsand();
Xchar *bitsxor();
Xint bitstst();
Xint bitsany();
X
Xchar *
Xbitsset(s1, s2, n)
X	register char	*s1;
X	register char	*s2;
X	register int	n;
X{
X	while (n--)
X		*s1++ |= *s2++;
X
X	return s1;
X}
X
Xchar *
Xbitsclr(s1, s2, n)
X	register char	*s1;
X	register char	*s2;
X	register int	n;
X{
X	while (n--)
X		*s1++ &= ~*s2++;
X
X	return s1;
X}
X
Xchar *
Xbitsand(s1, s2, n)
X	register char	*s1;
X	register char	*s2;
X	register int	n;
X{
X	while (n--)
X		*s1++ &= *s2++;
X
X	return s1;
X}
X
Xchar *
Xbitsxor(s1, s2, n)
X	register char	*s1;
X	register char	*s2;
X	register int	n;
X{
X	while (n--)
X		*s1++ ^= *s2++;
X
X	return s1;
X}
X
Xint
Xbitstst(s1, s2, n)
X	register char	*s1;
X	register char	*s2;
X	register int	n;
X{
X	while (n--)
X		if (*s1++ & *s2++)
X			return 1;
X
X	return 0;
X}
X
Xint
Xbitsany(s, n)
X	register char	*s;
X	register int	n;
X{
X	while (n--)
X		if (*s++)
X			return 1;
X
X	return 0;
X}
SHAR_EOF
if test 992 -ne "`wc -c < 'bitops.c'`"
then
	echo shar: error transmitting "'bitops.c'" '(should have been 992 characters)'
fi
echo shar: extracting "'bitsvec.c'" '(1614 characters)'
sed 's/^X//' << \SHAR_EOF > 'bitsvec.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bitsvec.c	1.1 86/10/09";
X
X#include	<stdio.h>
X#include	<bitops.h>
X#include	<string.h>
X#include	<extern.h>
X#include	<id.h>
X
Xint vecToBits();
Xint bitsToVec();
Xchar *intToStr();
Xint getsFF();
Xint strToInt();
Xvoid skipFF();
X
Xint
XvecToBits(bitArray, vec, size)
X	register char	*bitArray;
X	register char	*vec;
X	int		size;
X{
X	register int	i;
X	int		count;
X
X	for (count = 0; (*vec & 0xff) != 0xff; count++) {
X		i = strToInt(vec, size);
X		BITSET(bitArray, i);
X		vec += size;
X	}
X	return count;
X}
X
Xint
XbitsToVec(vec, bitArray, bitCount, size)
X	register char	*vec;
X	char		*bitArray;
X	int		bitCount;
X	int		size;
X{
X	register char	*element;
X	register int	i;
X	int		count;
X
X	for (count = i = 0; i < bitCount; i++) {
X		if (!BITTST(bitArray, i))
X			continue;
X		element = intToStr(i, size);
X		switch (size) {
X		case 4: *vec++ = *element++;
X		case 3: *vec++ = *element++;
X		case 2: *vec++ = *element++;
X		case 1: *vec++ = *element++;
X		}
X		count++;
X	}
X	*vec++ = 0xff;
X
X	return count;
X}
X
Xchar *
XintToStr(i, size)
X	register int	i;
X	int		size;
X{
X	static char	buf0[4];
X	register char	*bufp = &buf0[size];
X
X	switch (size)
X	{
X	case 4:	*--bufp = (i & 0xff); i >>= 8;
X	case 3: *--bufp = (i & 0xff); i >>= 8;
X	case 2: *--bufp = (i & 0xff); i >>= 8;
X	case 1: *--bufp = (i & 0xff);
X	}
X	return buf0;
X}
X
Xint
XstrToInt(bufp, size)
X	register char	*bufp;
X	int		size;
X{
X	register int	i = 0;
X
X	bufp--;
X	switch (size)
X	{
X	case 4: i |= (*++bufp & 0xff); i <<= 8;
X	case 3: i |= (*++bufp & 0xff); i <<= 8;
X	case 2: i |= (*++bufp & 0xff); i <<= 8;
X	case 1: i |= (*++bufp & 0xff);
X	}
X	return i;
X}
SHAR_EOF
if test 1614 -ne "`wc -c < 'bitsvec.c'`"
then
	echo shar: error transmitting "'bitsvec.c'" '(should have been 1614 characters)'
fi
echo shar: extracting "'bsearch.c'" '(692 characters)'
sed 's/^X//' << \SHAR_EOF > 'bsearch.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bsearch.c	1.1 86/10/09";
X
Xchar *bsearch();
X
X/*
X	Binary search -- from Knuth (6.2.1) Algorithm B
X*/
Xchar *
Xbsearch(key, base, nel, width, compar)
X	char		*key;
X	register char	*base;
X	unsigned int	nel;
X	int		width;
X	int		(*compar)();
X{
X	register char	*last;
X	register char	*position;
X	register int	result;
X	int		width2;
X
X	width2 = width * 2;
X	last = &base[width * (nel - 1)];
X
X	while (last >= base) {
X		position = &base[width * ((last - base)/width2)];
X		
X		if ((result = (*compar)(key, position)) == 0)
X			return position;
X		if (result < 0)
X			last = position - width;
X		else
X			base = position + width;
X	}
X	return (char *)0;
X}
SHAR_EOF
if test 692 -ne "`wc -c < 'bsearch.c'`"
then
	echo shar: error transmitting "'bsearch.c'" '(should have been 692 characters)'
fi
echo shar: extracting "'bzero.c'" '(199 characters)'
sed 's/^X//' << \SHAR_EOF > 'bzero.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bzero.c	1.1 86/10/09";
X
Xvoid bzero();
X
Xvoid
Xbzero(s, n)
X	register char	*s;
X	register int	n;
X{
X	if (n) do
X		*s++ = 0;
X	while (--n);
X}
SHAR_EOF
if test 199 -ne "`wc -c < 'bzero.c'`"
then
	echo shar: error transmitting "'bzero.c'" '(should have been 199 characters)'
fi
echo shar: extracting "'document.c'" '(188 characters)'
sed 's/^X//' << \SHAR_EOF > 'document.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)document.c	1.1 86/10/09";
X
Xvoid document();
X
Xvoid
Xdocument(doc)
X	char		**doc;
X{
X	while (*doc)
X		printf("%s\n", *doc++);
X}
SHAR_EOF
if test 188 -ne "`wc -c < 'document.c'`"
then
	echo shar: error transmitting "'document.c'" '(should have been 188 characters)'
fi
echo shar: extracting "'fid.c'" '(2362 characters)'
sed 's/^X//' << \SHAR_EOF > 'fid.c'
Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
Xstatic char sccsid[] = "@(#)fid.c	1.2 86/10/17";
X
X#include	<bool.h>
X#include	<stdio.h>
X#include	<string.h>
X#include	<ctype.h>
X#include	<radix.h>
X#include	<id.h>
X#include	<bitops.h>
X#include	<extern.h>
X
Xvoid fileId();
X
XFILE		*IdFILE;
Xstruct idhead	Idh;
Xstruct idarg	*IdArgs;
X
Xchar *MyName;
Xstatic void
Xusage()
X{
X	fprintf(stderr, "Usage: %s [-f<file>] file1 file2\n", MyName);
X	exit(1);
X}
Xmain(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*idFile = IDFILE;
X	char		*arg;
X	float		occurPercent = 0.0;
X	int		occurNumber = 0;
X	int		op;
X
X	MyName = basename(GETARG(argc, argv));
X
X	while (argc) {
X		arg = GETARG(argc, argv);
X		switch (op = *arg++)
X		{
X		case '-':
X		case '+':
X			break;
X		default:
X			UNGETARG(argc, argv);
X			goto argsdone;
X		}
X		while (*arg) switch (*arg++)
X		{
X		case 'f': idFile = arg; goto nextarg;
X		default: usage();
X		}
X	nextarg:;
X	}
Xargsdone:
X
X	idFile = spanPath(getDirToName(idFile), idFile);
X	if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
X
X	if (argc < 1 || argc > 2)
X		usage();
X
X	fileId(argc, argv);
X	exit(0);
X}
X
Xvoid
XfileId(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*buf;
X	int		want, got;
X	int		bitoff[2];
X	int		i, j;
X	int		argLength;
X	int		pathLength;
X	int		lengthDiff;
X	char		*pathVec;
X	register struct idarg	*idArgs;
X
X	want = 0;
X	for (j = 0; j < argc; j++, argv++) {
X		want |= (1<<j);
X		argLength = strlen(*argv);
X		bitoff[j] = -1;
X		for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X			pathLength = strlen(idArgs->ida_arg);
X			if (argLength > pathLength)
X				continue;
X			lengthDiff = pathLength - argLength;
X			if (strequ(&idArgs->ida_arg[lengthDiff], *argv)) {
X				bitoff[j] = i;
X				break;
X			}
X		}
X		if (bitoff[j] < 0) {
X			fprintf(stderr, "%s: not found\n", *argv);
X			exit(1);
X		}
X	}
X
X	buf = malloc((int)Idh.idh_bsiz);
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	for (i = 0; i < Idh.idh_namc; i++) {
X		pathVec = 1 + buf + fgets0(buf, Idh.idh_bsiz, IdFILE);
X		getsFF(pathVec, IdFILE);
X		got = 0;
X		while ((*pathVec & 0xff) != 0xff) {
X			j = strToInt(pathVec, Idh.idh_vecc);
X			if ((want & (1<<0)) && j == bitoff[0])
X				got |= (1<<0);
X			if ((want & (1<<1)) && j == bitoff[1])
X				got |= (1<<1);
X			if (got == want) {
X				printf("%s\n", ID_STRING(buf));
X				break;
X			}
X			pathVec += Idh.idh_vecc;
X		}
X	}
X}
SHAR_EOF
if test 2362 -ne "`wc -c < 'fid.c'`"
then
	echo shar: error transmitting "'fid.c'" '(should have been 2362 characters)'
fi
echo shar: extracting "'gets0.c'" '(575 characters)'
sed 's/^X//' << \SHAR_EOF > 'gets0.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)gets0.c	1.1 86/10/09";
X
X#include	<stdio.h>
X
Xint fgets0();
X
X/*
X	This is like fgets(3s), except that lines are
X	delimited by NULs rather than newlines.  Also,
X	we return the number of characters gotten rather
X	than the address of buf0.
X*/
Xint
Xfgets0(buf0, size, inFILE)
X	char		*buf0;
X	int		size;
X	register FILE	*inFILE;
X{
X	register char	*buf;
X	register int	c;
X	register char	*end;
X
X	buf = buf0;
X	end = &buf[size];
X	while ((c = getc(inFILE)) > 0 && buf < end)
X		*buf++ = c;
X	*buf = '\0';
X	return (buf - buf0);
X}
SHAR_EOF
if test 575 -ne "`wc -c < 'gets0.c'`"
then
	echo shar: error transmitting "'gets0.c'" '(should have been 575 characters)'
fi
echo shar: extracting "'getsFF.c'" '(418 characters)'
sed 's/^X//' << \SHAR_EOF > 'getsFF.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)getsFF.c	1.1 86/10/09";
X
X#include	<stdio.h>
X
Xint getsFF();
Xvoid skipFF();
X
Xint
XgetsFF(buf0, inFILE)
X	char		*buf0;
X	register FILE	*inFILE;
X{
X	register char	*buf = buf0;
X
X	while (((*buf++ = getc(inFILE)) & 0xff) != 0xff)
X		;
X	return (buf - buf0 - 1);
X}
X
Xvoid
XskipFF(inFILE)
X	register FILE	*inFILE;
X{
X	while ((getc(inFILE) & 0xff) != 0xff)
X		;
X	return;
X}
SHAR_EOF
if test 418 -ne "`wc -c < 'getsFF.c'`"
then
	echo shar: error transmitting "'getsFF.c'" '(should have been 418 characters)'
fi
echo shar: extracting "'getscan.c'" '(5672 characters)'
sed 's/^X//' << \SHAR_EOF > 'getscan.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)getscan.c	1.1 86/10/09";
X
X#include	<stdio.h>
X#include	<string.h>
X#include	<id.h>
X#include	<ctype.h>
X#include	<extern.h>
X
Xchar *getLanguage();
Xchar *(*getScanner())();
Xvoid setScanArgs();
X
Xstatic struct sufftab *suffSlot();
Xstatic struct langtab *langSlot();
Xstatic void sorryNoScan();
X
Xvoid setAdaArgs(lang) { sorryNoScan(lang); }
Xchar *getAdaId() { setAdaArgs("ada"); return NULL; }
X
Xvoid setPascalArgs(lang) { sorryNoScan(lang); }
Xchar *getPascalId() { setPascalArgs("pascal"); return NULL; }
X
Xvoid setTextArgs(lang) { sorryNoScan(lang); }
Xchar *getTextId() { setTextArgs("plain text"); return NULL; }
X
Xvoid setRoffArgs(lang) { sorryNoScan(lang); }
Xchar *getRoffId() { setRoffArgs("[nt]roff"); return NULL; }
X
Xvoid setTeXArgs(lang) { sorryNoScan(lang); }
Xchar *getTeXId() { setTeXArgs("TeX"); return NULL; }
X
Xvoid setLispArgs(lang) { sorryNoScan(lang); }
Xchar *getLispId() { setLispArgs("lisp"); return NULL; }
X
Xstruct langtab {
X	struct langtab	*lt_next;
X	char	*lt_name;
X	char	*(*lt_getid)();
X	void	(*lt_setargs)();
X};
X
Xstruct sufftab {
X	struct sufftab	*st_next;
X	char	*st_suffix;
X	struct langtab *st_lang;
X};
X
X
Xstruct langtab langtab[] = {
X#define	SCAN_C		(&langtab[0])
X{	&langtab[1],	"c",		getCId,		setCArgs	},
X#define	SCAN_ASM	(&langtab[1])
X{	&langtab[2],	"asm",		getAsmId,	setAsmArgs	},
X#define	SCAN_ADA	(&langtab[2])
X{	&langtab[3],	"ada",		getAdaId,	setAdaArgs	},
X#define	SCAN_PASCAL	(&langtab[3])
X{	&langtab[4],	"pascal",	getPascalId,	setPascalArgs	},
X#define	SCAN_LISP	(&langtab[4])
X{	&langtab[5],	"lisp",		getLispId,	setLispArgs	},
X#define	SCAN_TEXT	(&langtab[5])
X{	&langtab[6],	"text",		getTextId,	setTextArgs	},
X#define	SCAN_ROFF	(&langtab[6])
X{	&langtab[7],	"roff",		getRoffId,	setRoffArgs	},
X#define	SCAN_TEX	(&langtab[7])
X{	&langtab[8],	"tex",		getTeXId,	setTeXArgs	},
X{ NULL, NULL, NULL, NULL }
X};
X
X/*
X	This is a rather incomplete list of default associations
X	between suffixes and languages.  You may add more to the
X	default list, or you may define them dynamically with the
X	`-S<suff>=<lang>' argument to mkid(1) and idx(1).  e.g. to
X	associate a `.ada' suffix with the Ada language, use
X	`-S.ada=ada'
X*/
Xstruct sufftab sufftab[] = {
X{	&sufftab[1],	".c",	SCAN_C		},
X{	&sufftab[2],	".h",	SCAN_C		},
X{	&sufftab[3],	".y",	SCAN_C		},
X{	&sufftab[4],	".s",	SCAN_ASM	},
X{	&sufftab[5],	".p",	SCAN_PASCAL	},
X{	&sufftab[6],	".pas",	SCAN_PASCAL	},
X{ NULL, NULL, NULL },
X};
X
X/*
X	Return an index into the langtab array for the given suffix.
X*/
Xstatic struct sufftab *
XsuffSlot(suffix)
X	register char	*suffix;
X{
X	register struct sufftab	*stp;
X
X	if (suffix == NULL)
X		suffix = "";
X
X	for (stp = sufftab; stp->st_next; stp = stp->st_next)
X		if (strequ(stp->st_suffix, suffix))
X			return stp;
X	return stp;
X}
X
Xstatic struct langtab *
XlangSlot(lang)
X	char		*lang;
X{
X	register struct langtab	*ltp;
X
X	if (lang == NULL)
X		lang = "";
X
X	for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next)
X		if (strequ(ltp->lt_name, lang))
X			return ltp;
X	return ltp;
X}
X
Xchar *
XgetLanguage(suffix)
X	char		*suffix;
X{
X	struct sufftab	*stp;
X
X	if ((stp = suffSlot(suffix))->st_next == NULL)
X		return NULL;
X	return (stp->st_lang->lt_name);
X}
X
Xchar *(*
XgetScanner(lang))()
X	char		*lang;
X{
X	struct langtab	*ltp;
X
X	if ((ltp = langSlot(lang))->lt_next == NULL)
X		return NULL;
X	return (ltp->lt_getid);
X}
X
Xstatic void
Xusage()
X{
X	fprintf(stderr, "Usage: %s [-S<suffix>=<lang>] [+S(+|-)<arg>] [-S<lang>(+|-)<arg>]\n", MyName);
X	exit(1);
X}
Xvoid
XsetScanArgs(op, arg)
X	int		op;
X	char		*arg;
X{
X	struct langtab	*ltp;
X	struct sufftab	*stp;
X	char		*lhs;
X	int		count = 0;
X
X	lhs = arg;
X	while (isalnum(*arg) || *arg == '.')
X		arg++;
X
X	if (strequ(lhs, "?=?")) {
X		for (stp = sufftab; stp->st_next; stp = stp->st_next)
X			printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, stp->st_lang->lt_name);
X		if (count)
X			putchar('\n');
X		return;
X	}
X
X	if (strnequ(lhs, "?=", 2)) {
X		lhs += 2;
X		if ((ltp = langSlot(lhs))->lt_next == NULL) {
X			printf("No scanner for language `%s'\n", lhs);
X			return;
X		}
X		for (stp = sufftab; stp->st_next; stp = stp->st_next)
X			if (stp->st_lang == ltp)
X				printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, ltp->lt_name);
X		if (count)
X			putchar('\n');
X		return;
X	}
X
X	if (strequ(arg, "=?")) {
X		lhs[strlen(lhs)-2] = '\0';
X		if ((stp = suffSlot(lhs))->st_next == NULL) {
X			printf("No scanner assigned to suffix `%s'\n", lhs);
X			return;
X		}
X		printf("%s=%s\n", stp->st_suffix, stp->st_lang->lt_name);
X		return;
X	}
X
X	if (*arg == '=') {
X		*arg++ = '\0';
X		
X		if ((ltp = langSlot(arg))->lt_next == NULL) {
X			fprintf(stderr, "%s: Language undefined: %s\n", MyName, arg);
X			return;
X		}
X		if ((stp = suffSlot(lhs))->st_next == NULL) {
X			stp->st_suffix = lhs;
X			stp->st_lang = ltp;
X			stp->st_next = NEW(struct sufftab);
X		} else if (!strequ(arg, stp->st_lang->lt_name)) {
X			fprintf(stderr, "%s: Note: `%s=%s' overrides `%s=%s'\n", MyName, lhs, arg, lhs, stp->st_lang->lt_name);
X			stp->st_lang = ltp;
X		}
X		return;
X	}
X	
X	if (op == '+') {
X		switch (op = *arg++)
X		{
X		case '+':
X		case '-':
X		case '?':
X			break;
X		default:
X			usage();
X		}
X		for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next)
X			(*ltp->lt_setargs)(NULL, op, arg);
X		return;
X	}
X
X	if (*arg == '-' || *arg == '+' || *arg == '?') {
X		op = *arg;
X		*arg++ = '\0';
X		
X		if ((ltp = langSlot(lhs))->lt_next == NULL) {
X			fprintf(stderr, "%s: Language undefined: %s\n", MyName, lhs);
X			return;
X		}
X		(*ltp->lt_setargs)(lhs, op, arg);
X		return;
X	}
X
X	usage();
X}
X
X/*
X	Notify user of unimplemented scanners.
X*/
Xstatic void
XsorryNoScan(lang)
X	char		*lang;
X{
X	if (lang == NULL)
X		return;
X	fprintf(stderr, "Sorry, no scanner is implemented for %s...\n", lang);
X}
SHAR_EOF
if test 5672 -ne "`wc -c < 'getscan.c'`"
then
	echo shar: error transmitting "'getscan.c'" '(should have been 5672 characters)'
fi
echo shar: extracting "'hash.c'" '(2203 characters)'
sed 's/^X//' << \SHAR_EOF > 'hash.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)hash.c	1.1 86/10/09";
X
Xchar *hashSearch();
Xint h1str();
Xint h2str();
X
X/*
X	Look for `key' in the hash table starting at address `base'.
X	`base' is a table containing `nel' elements of size `width'.
X	The hashing strategy we use is open addressing.  Apply the
X	primary hash function `h1' and the secondary hash function
X	`h2' when searching for `key' or an empty slot.  `compar'
X	is the comparison function that should be used to compare
X	the key with an element of the table.  It is called with two
X	arguments.  The first argument is the address of the key, and
X	the second argument is the address of the hash table element
X	in question.  `compar' should return 0 if the key matches the
X	element or the empty slot, and non-zero otherwise.
X
X	If a pointer to a long is provided for `probes' we will keep
X	a running total of open addressing hash probes.
X*/
Xchar *
XhashSearch(key, base, nel, width, h1, h2, compar, probes)
X	char		*key;		/* key to locate */
X	char		*base;		/* base of hash table */
X	register int	nel;		/* number of elements in table */
X	int		width;		/* width of each element */
X	int		(*h1)();	/* primary hash function */
X	int		(*h2)();	/* secondary hash function */
X	int		(*compar)();	/* key comparison function */
X	long		*probes;
X{
X	register int	hash1;
X	register int	hash2;
X	register char	*slot;
X
X	hash1 = (*h1)(key) % nel;
X	slot = &base[hash1 * width];
X
X	if (probes)
X		(*probes)++;
X	if ((*compar)(key, slot) == 0)
X		return slot;
X
X	hash2 = (*h2)(key);
X	for (;;) {
X		hash1 = (hash1 + hash2) % nel;
X		slot = &base[hash1 * width];
X
X		if (probes)
X			(*probes)++;
X		if ((*compar)(key, slot) == 0)
X			return slot;
X	}
X}
X
X#define	ABS(n)		((n) < 0 ? -(n) : (n))
X
X/*
X	A Primary hash function for string keys.
X*/
Xint
Xh1str(key)
X	register char	*key;
X{
X	register int	sum;
X	register int	s;
X
X	for (sum = s = 0; *key; s++)
X		sum += ((*key++) << s);
X
X	return ABS(sum);
X}
X
X/*
X	A Secondary hash function for string keys.
X*/
Xint
Xh2str(key)
X	register char	*key;
X{
X	register int	sum;
X	register int	s;
X	char		*keysav;
X
X	keysav = key;
X	key = &key[strlen(key)];
X
X	for (sum = s = 0; key > keysav; s++)
X		sum += ((*--key) << s);
X
X	return ABS(sum) | 1;
X}
SHAR_EOF
if test 2203 -ne "`wc -c < 'hash.c'`"
then
	echo shar: error transmitting "'hash.c'" '(should have been 2203 characters)'
fi
echo shar: extracting "'idx.c'" '(1358 characters)'
sed 's/^X//' << \SHAR_EOF > 'idx.c'
Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
Xstatic char sccsid[] = "@(#)idx.c	1.2 86/10/17";
X
X#include	<stdio.h>
X#include	<string.h>
X#include	<id.h>
X#include	<extern.h>
X
Xvoid idxtract();
X
Xchar	*MyName;
Xstatic void
Xusage()
X{
X	fprintf(stderr, "Usage: %s [-u] [+/-a<ccc>] [-c<ccc>] files\n", MyName);
X	exit(1);
X}
Xmain(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*arg;
X	int		op;
X	char		*sccsDir = NULL;
X	char		*rcsDir = NULL;
X
X	MyName = basename(GETARG(argc, argv));
X	while (argc) {
X		arg = GETARG(argc, argv);
X		switch (op = *arg++)
X		{
X		case '-':
X		case '+':
X			break;
X		default:
X			UNGETARG(argc, argv);
X			goto argsdone;
X		}
X		switch (*arg++)
X		{
X		case 's': sccsDir = arg; break;
X		case 'r': rcsDir = arg; break;
X		case 'S': setScanArgs(op, arg); break;
X		default: usage();
X		}
X	}
Xargsdone:
X
X	if (argc == 0)
X		usage();
X	while (argc)
X		idxtract(GETARG(argc, argv), sccsDir, rcsDir);
X	exit(0);
X}
X
Xvoid
Xidxtract(path, sccsDir, rcsDir)
X	char		*path;
X	char		*sccsDir;
X	char		*rcsDir;
X{
X	register char	*key;
X	register char	*(*getId)();
X	register FILE	*srcFILE;
X	char		*(*getScanner())();
X	int		flags;
X
X	if ((getId = getScanner(getLanguage(strrchr(path, '.')))) == NULL)
X		return;
X	if ((srcFILE = openSrcFILE(path, sccsDir, rcsDir)) == NULL)
X		return;
X
X	while ((key = (*getId)(srcFILE, &flags)) != NULL)
X		puts(key);
X
X	fclose(srcFILE);
X}
SHAR_EOF
if test 1358 -ne "`wc -c < 'idx.c'`"
then
	echo shar: error transmitting "'idx.c'" '(should have been 1358 characters)'
fi
echo shar: extracting "'init.c'" '(1259 characters)'
sed 's/^X//' << \SHAR_EOF > 'init.c'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)init.c	1.1 86/10/09";
X
X#include	<id.h>
X#include	<string.h>
X#include	<stdio.h>
X#include	<extern.h>
X
XFILE *
XinitID(idFile, idhp, idArgs)
X	char		*idFile;
X	struct idhead	*idhp;
X	struct idarg	**idArgs;
X{
X	FILE		*idFILE;
X	register int	i;
X	register char	*strings;
X	register struct idarg	*idArg;
X
X	if ((idFILE = fopen(idFile, "r")) == NULL)
X		return NULL;
X
X	fseek(idFILE, 0L, 0);
X	fread(idhp, sizeof(struct idhead), 1, idFILE);
X	if (!strnequ(idhp->idh_magic, IDH_MAGIC, sizeof(idhp->idh_magic))) {
X		fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
X		exit(1);
X	}
X	if (idhp->idh_vers != IDH_VERS) {
X		fprintf(stderr, "%s: ID version mismatch (want: %d, got: %d)\n", MyName, IDH_VERS, idhp->idh_vers);
X		exit(1);
X	}
X
X	fseek(idFILE, idhp->idh_argo, 0);
X	strings = malloc(i = idhp->idh_namo - idhp->idh_argo);
X	fread(strings, i, 1, idFILE);
X	idArg = *idArgs = (struct idarg *)calloc(idhp->idh_pthc, sizeof(struct idarg));
X	for (i = 0; i < idhp->idh_argc; i++) {
X		if (*strings == '+' || *strings == '-')
X			goto skip;
X		idArg->ida_flags = (*strings) ? 0 : IDA_BLANK;
X		idArg->ida_arg = strings;
X		idArg->ida_next = idArg + 1;
X		idArg++;
X	skip:
X		while (*strings++)
X			;
X	}
X	return idFILE;
X}
SHAR_EOF
if test 1259 -ne "`wc -c < 'init.c'`"
then
	echo shar: error transmitting "'init.c'" '(should have been 1259 characters)'
fi
echo shar: extracting "'lid.c'" '(16134 characters)'
sed 's/^X//' << \SHAR_EOF > 'lid.c'
Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
Xstatic char sccsid[] = "@(#)lid.c	1.4 86/11/06";
X
X#include	<bool.h>
X#include	<stdio.h>
X#include	<string.h>
X#include	<ctype.h>
X#include	<radix.h>
X#include	<id.h>
X#include	<bitops.h>
X#include	<extern.h>
X
X#ifdef REGEX
Xextern char *regex();
Xextern char *regcmp();
X#endif
X#ifdef RE_EXEC
Xextern char *re_comp();
Xextern int re_exec();
X#endif
X
Xbool isMagic();
Xchar **bitsToArgv();
Xchar *fileRE();
Xchar *strcpos();
Xint skipToArgv();
Xint findAnchor();
Xint findApropos();
X#if REGEX || RE_EXEC
Xint findRegExp();
X#endif
Xint findNonUnique();
Xint findNumber();
Xint findPlain();
Xint idCompare();
Xlong searchName();
Xvoid editId();
Xvoid grepId();
Xvoid lookId();
X
X#ifdef USG
X#define	TOLOWER(c)	(isupper(c) ? _tolower(c) : (c))
X#else
X#define	TOLOWER(c)	(isupper(c) ? tolower(c) : (c))
X#endif
X
X/*
X*  Sorry about all the globals, but it's really cleaner this way.
X*/
XFILE		*IdFILE;
Xbool		Merging;
Xbool		Radix;
Xchar		*IdDir;
Xlong		AnchorOffset;
Xint		BitArraySize;
Xstruct idhead	Idh;
Xstruct idarg	*IdArgs;
Xint		(*FindFunc)() = NULL;
Xint		Solo = 0;
X#define	IGNORE_SOLO(buf) \
X( \
X	   (Solo == '-' && !(ID_FLAGS(buf) & IDN_SOLO)) \
X	|| (Solo == '+' &&  (ID_FLAGS(buf) & IDN_SOLO)) \
X)
X
Xchar *MyName;
Xstatic void
Xusage()
X{
X	fprintf(stderr, "Usage: %s [-f<file>] [-u<n>] [-mewdoxas] patterns...\n", MyName);
X	exit(1);
X}
Xmain(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*idFile = IDFILE;
X	char		*arg;
X	long		val;
X	void		(*doit)();
X	bool		forceMerge = FALSE;
X	int		uniqueLimit = 0;
X	int		op;
X
X	MyName = basename(GETARG(argc, argv));
X
X	while (argc) {
X		arg = GETARG(argc, argv);
X		switch (op = *arg++)
X		{
X		case '-':
X		case '+':
X			break;
X		default:
X			UNGETARG(argc, argv);
X			goto argsdone;
X		}
X		while (*arg) switch (*arg++)
X		{
X		case 'f': idFile = arg; goto nextarg;
X		case 'u': uniqueLimit = stoi(arg); goto nextarg;
X		case 'm': forceMerge = TRUE; break;
X#if REGEX || RE_EXEC
X		case 'e': FindFunc = findRegExp; break;
X#endif
X		case 'w': FindFunc = findPlain; break;
X		case 'd': Radix |= RADIX_DEC; break;
X		case 'o': Radix |= RADIX_OCT; break;
X		case 'x': Radix |= RADIX_HEX; break;
X		case 'a': Radix |= RADIX_ALL; break;
X		case 's': Solo = op; break;
X		default:
X			usage();
X		}
X	nextarg:;
X	}
Xargsdone:
X
X	IdDir = getDirToName(idFile);
X	idFile = spanPath(IdDir, idFile);
X	if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
X	BitArraySize = (Idh.idh_pthc + 7) >> 3;
X
X	switch (MyName[0])
X	{
X	case 'a':
X		FindFunc = findApropos;
X		/*FALLTHROUGH*/
X	case 'l':
X		doit = lookId;
X		break;
X	case 'g':
X		doit = grepId;
X		break;
X	case 'e':
X		doit = editId;
X		break;
X	default:
X		MyName = "[alge]id";
X		usage();
X	}
X
X	if (argc == 0) {
X		UNGETARG(argc, argv);
X		*argv = ".";
X	}
X
X	while (argc) {
X		arg = GETARG(argc, argv);
X		if (FindFunc)
X			;
X		else if ((radix(arg)) && (val = stoi(arg)) >= 0)
X			FindFunc = findNumber;
X#if REGEX || RE_EXEC
X		else if (isMagic(arg))
X			FindFunc = findRegExp;
X#endif
X		else if (arg[0] == '^')
X			FindFunc = findAnchor;
X		else
X			FindFunc = findPlain;
X
X		if ((doit == lookId && !forceMerge)
X		|| (FindFunc == findNumber && bitCount(Radix) > 1 && val > 7))
X			Merging = FALSE;
X		else
X			Merging = TRUE;
X
X		if (uniqueLimit) {
X			if (!findNonUnique(uniqueLimit, doit))
X				fprintf(stderr, "All identifiers are unique within the first %d characters\n", uniqueLimit);
X			exit(0);
X		} else if (!(*FindFunc)(arg, doit)) {
X			fprintf(stderr, "%s: not found\n", arg);
X			continue;
X		}
X	}
X	exit(0);
X}
X
Xvoid
XlookId(name, argv)
X	char		*name;
X	register char	**argv;
X{
X	register char	*arg;
X	register bool	crunching = FALSE;
X	register char	*dir;
X
X	printf("%-14s ", name);
X	while (*argv) {
X		arg = *argv++;
X		if (*argv && canCrunch(arg, *argv)) {
X			if (crunching)
X				printf(",%s", rootName(arg));
X			else if ((dir = dirname(arg)) && dir[0] == '.' && dir[1] == '\0')
X				printf("{%s", rootName(arg));
X			else
X				printf("%s/{%s", dir, rootName(arg));
X			/*}}*/
X			crunching = TRUE;
X		} else {
X			if (crunching) /*{*/
X				printf(",%s}%s", rootName(arg), suffName(arg));
X			else
X				fputs(arg, stdout);
X			crunching = FALSE;
X			if (*argv)
X				putchar(' ');
X		}
X	}
X	putchar('\n');
X}
X
Xvoid
XgrepId(name, argv)
X	char		*name;
X	char		**argv;
X{
X	FILE		*gidFILE;
X	char		*gidName;
X	char		buf[BUFSIZ];
X	char		*delimit = "[^a-zA-Z0-9_]";
X	char		*re;
X	char		*reCompiled;
X	int		lineNumber;
X
X	if (!Merging || (re = fileRE(name, delimit, delimit)) == NULL)
X		re = NULL;
X#ifdef REGEX
X	else if ((reCompiled = regcmp(re, 0)) == NULL) {
X		fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
X		return;
X	}
X#endif
X#ifdef RE_EXEC
X	else if ((reCompiled = re_comp(re)) != NULL) {
X		fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
X		return;
X	}
X#endif
X
X	buf[0] = ' ';	/* sentry */
X	while (*argv) {
X		if ((gidFILE = fopen(gidName = *argv++, "r")) == NULL) {
X			filerr("open", gidName);
X			continue;
X		}
X		lineNumber = 0;
X		while (fgets(&buf[1], sizeof(buf), gidFILE)) {
X			lineNumber++;
X			if (re) {
X#ifdef REGEX
X				if (regex(reCompiled, buf) == NULL)
X#endif
X#ifdef RE_EXEC
X				if (!re_exec(buf))
X#endif
X					continue;
X			} else if (!wordMatch(name, buf))
X				continue;
X			printf("%s:%d: %s", gidName, lineNumber, &buf[1]);
X		}
X		fclose(gidFILE);
X	}
X}
X
Xvoid
XeditId(name, argv)
X	char		*name;
X	char		**argv;
X{
X	char		reBuf[BUFSIZ];
X	char		edArgBuf[BUFSIZ];
X	char		*re;
X	int		c;
X	int		skip;
X	static char	*editor, *eidArg, *eidRightDel, *eidLeftDel;
X
X	if (editor == NULL && (editor = getenv("EDITOR")) == NULL) {
X		char	*ucb_vi = "/usr/ucb/vi";
X		char	*bin_vi = "/usr/bin/vi";
X
X		if (access(ucb_vi, 01) == 0)
X			editor = ucb_vi;
X		else if (access(bin_vi, 01) == 0)
X			editor = bin_vi;
X		else
X			editor = "/bin/ed";	/* YUCK! */
X		if (editor == ucb_vi || editor == bin_vi) {
X			eidArg = "+1;/%s/";
X			eidLeftDel = "\\<";
X			eidRightDel = "\\>";
X		}
X	}
X	if (eidLeftDel == NULL) {
X		eidArg = getenv("EIDARG");
X		if ((eidLeftDel = getenv("EIDLDEL")) == NULL)
X			eidLeftDel = "";
X		if ((eidRightDel = getenv("EIDRDEL")) == NULL)
X			eidRightDel = "";
X	}
X
X	lookId(name, argv);
X	savetty();
X	for (;;) {
X		printf("Edit? [y1-9^S/nq] "); fflush(stdout);
X		chartty();
X		c = (getchar() & 0177);
X		restoretty();
X		switch (TOLOWER(c))
X		{
X		case '/': case ('s'&037):
X			putchar('/');
X			/*FALLTHROUGH*/
X			if ((skip = skipToArgv(argv)) < 0)
X				continue;
X			argv += skip;
X			goto editit;
X		case '1': case '2': case '3': case '4':
X		case '5': case '6': case '7': case '8': case '9':
X			putchar(c);
X			skip = c - '0';
X			break;
X		case 'y':
X			putchar(c);
X			/*FALLTHROUGH*/
X		case '\n':
X		case '\r':
X			skip = 0;
X			break;
X		case 'q':
X			putchar(c);
X			putchar('\n');
X			exit(0);
X		case 'n':
X			putchar(c);
X			putchar('\n');
X			return;
X		default:
X			putchar(c);
X			putchar('\n');
X			continue;
X		}
X
X		putchar('\n');
X		while (skip--)
X			if (*++argv == NULL)
X				continue;
X		break;
X	}
Xeditit:
X
X	if (!Merging || (re = fileRE(name, eidLeftDel, eidRightDel)) == NULL)
X		sprintf(re = reBuf, "%s%s%s", eidLeftDel, name, eidRightDel);
X
X	switch (fork())
X	{
X	case -1:
X		fprintf(stderr, "%s: Cannot fork (%s)\n", MyName, uerror());
X		exit(1);
X	case 0:
X		argv--;
X		if (eidArg) {
X			argv--;
X			sprintf(edArgBuf, eidArg, re);
X			argv[1] = edArgBuf;
X		}
X		argv[0] = editor;
X		execv(editor, argv);
X		filerr("exec", editor);
X	default:
X		wait(0);
X		break;
X	}
X}
X
Xint
XskipToArgv(argv)
X	char		**argv;
X{
X	char		pattern[BUFSIZ];
X	int		count;
X
X	if (gets(pattern) == NULL)
X		return -1;
X	
X	for (count = 0; *argv; count++, argv++)
X		if (strcpos(*argv, pattern))
X			return count;
X	return -1;
X}
X
Xint
XfindPlain(arg, doit)
X	char		*arg;
X	void		(*doit)();
X{
X	static char	*buf, *bitArray;
X	int		size;
X
X	if (searchName(arg) == 0)
X		return 0;
X	if (buf == NULL) {
X		buf = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	if ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) == 0)
X		return 0;
X	size++;
X	getsFF(&buf[size], IdFILE);
X	if (IGNORE_SOLO(buf))
X		return 0;
X
X	vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X	(*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X	return 1;
X}
X
Xint
XfindAnchor(arg, doit)
X	register char	*arg;
X	void		(*doit)();
X{
X	static char	*buf, *bitArray;
X	int		count, size;
X	int		len;
X
X	if (searchName(++arg) == 0)
X		return 0;
X
X	if (buf == NULL) {
X		buf = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	len = strlen(arg);
X	count = 0;
X	while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X		size++;
X		getsFF(&buf[size], IdFILE);
X		if (IGNORE_SOLO(buf))
X			continue;
X		if (!strnequ(arg, ID_STRING(buf), len))
X			break;
X		vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X		if (!Merging) {
X			(*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X			bzero(bitArray, BitArraySize);
X		}
X		count++;
X	}
X	if (Merging && count)
X		(*doit)(--arg, bitsToArgv(bitArray));
X
X	return count;
X}
X
X#if REGEX || RE_EXEC
Xint
XfindRegExp(re, doit)
X	char		*re;
X	void		(*doit)();
X{
X	static char	*buf, *bitArray;
X	int		count, size;
X	char		*reCompiled;
X
X#ifdef REGEX
X	if ((reCompiled = regcmp(re, 0)) == NULL) {
X		fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
X		return 0;
X	}
X#endif
X#ifdef RE_EXEC
X	if ((reCompiled = re_comp(re)) != NULL) {
X		fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
X		return 0;
X	}
X#endif
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	if (buf == NULL) {
X		buf = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	count = 0;
X	while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X		size++;
X		getsFF(&buf[size], IdFILE);
X		if (IGNORE_SOLO(buf))
X			continue;
X#ifdef REGEX
X		if (regex(reCompiled, ID_STRING(buf)) == NULL)
X#endif
X#ifdef RE_EXEC
X		if (!re_exec(ID_STRING(buf)))
X#endif
X			continue;
X		vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X		if (!Merging) {
X			(*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X			bzero(bitArray, BitArraySize);
X		}
X		count++;
X	}
X	if (Merging && count)
X		(*doit)(re, bitsToArgv(bitArray));
X
X	return count;
X}
X#endif
X
Xint
XfindNumber(arg, doit)
X	char		*arg;
X	void		(*doit)();
X{
X	static char	*buf, *bitArray;
X	int		count, size;
X	register int	rdx = 0;
X	register int	val;
X	register bool	hitDigits = FALSE;
X
X	if ((val = stoi(arg)) <= 7)
X		rdx |= RADIX_ALL;
X	else
X		rdx = radix(arg);
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	if (buf == NULL) {
X		buf = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	count = 0;
X	while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X		size++;
X		getsFF(&buf[size], IdFILE);
X		if (hitDigits) {
X			if (!isdigit(*ID_STRING(buf)))
X				break;
X		} else if (isdigit(*ID_STRING(buf)))
X			hitDigits = TRUE;
X
X		if (!((Radix ? Radix : rdx) & radix(ID_STRING(buf)))
X		|| stoi(ID_STRING(buf)) != val)
X			continue;
X		vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X		if (!Merging) {
X			(*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X			bzero(bitArray, BitArraySize);
X		}
X		count++;
X	}
X	if (Merging && count)
X		(*doit)(arg, bitsToArgv(bitArray));
X
X	return count;
X}
X
X/*
X	Find identifiers that are non-unique within
X	the first `count' characters.
X*/
Xint
XfindNonUnique(limit, doit)
X	int		limit;
X	void		(*doit)();
X{
X	static char	*buf1, *buf2, *bitArray;
X	register char	*old;
X	register char	*new;
X	register int	consecutive;
X	char		*cptmp;
X	int		itmp;
X	int		count, oldsize, newsize;
X	char		*name;
X
X	if (limit <= 1)
X		usage();
X
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	if (buf1 == NULL) {
X		buf1 = malloc(Idh.idh_bsiz);
X		buf2 = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	name = calloc(1, limit+2);
X	name[0] = '^';
X	old = buf1;
X	*ID_STRING(new = buf2) = '\0';
X	count = consecutive = 0;
X	while ((oldsize = fgets0(old, Idh.idh_bsiz, IdFILE)) > 0) {
X		oldsize++;
X		getsFF(&old[oldsize], IdFILE);
X		if (!(ID_FLAGS(old) & IDN_NAME))
X			continue;
X		cptmp = old; old = new; new = cptmp;
X		itmp = oldsize; oldsize = newsize; newsize = itmp;
X		if (!strnequ(ID_STRING(new), ID_STRING(old), limit)) {
X			if (consecutive && Merging) {
X				strncpy(&name[1], ID_STRING(old), limit); 
X				(*doit)(name, bitsToArgv(bitArray));
X			}
X			consecutive = 0;
X			continue;
X		}
X		if (!consecutive++) {
X			vecToBits(bitArray, &old[oldsize], Idh.idh_vecc);
X			if (!Merging) {
X				(*doit)(ID_STRING(old), bitsToArgv(bitArray));
X				bzero(bitArray, BitArraySize);
X			}
X			count++;
X		}
X		vecToBits(bitArray, &new[newsize], Idh.idh_vecc);
X		if (!Merging) {
X			(*doit)(ID_STRING(new), bitsToArgv(bitArray));
X			bzero(bitArray, BitArraySize);
X		}
X		count++;
X	}
X
X	return count;
X}
X
Xint
XfindApropos(arg, doit)
X	char		*arg;
X	void		(*doit)();
X{
X	static char	*buf, *bitArray;
X	int		count, size;
X
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	if (buf == NULL) {
X		buf = malloc(Idh.idh_bsiz);
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	count = 0;
X	while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X		size++;
X		getsFF(&buf[size], IdFILE);
X		if (IGNORE_SOLO(buf))
X			continue;
X		if (strcpos(ID_STRING(buf), arg) == NULL)
X			continue;
X		vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X		if (!Merging) {
X			(*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X			bzero(bitArray, BitArraySize);
X		}
X		count++;
X	}
X	if (Merging && count)
X		(*doit)(arg, bitsToArgv(bitArray));
X
X	return count;
X}
X
X/*
X	if string `s2' occurs in `s1', return a pointer to the
X	first match.  Ignore differences in alphabetic case.
X*/
Xchar *
Xstrcpos(s1, s2)
X	char		*s1;
X	char		*s2;
X{
X	register char	*s1p;
X	register char	*s2p;
X	char		*s1last;
X
X	for (s1last = &s1[strlen(s1) - strlen(s2)]; s1 <= s1last; s1++)
X		for (s1p = s1, s2p = s2; TOLOWER(*s1p) == TOLOWER(*s2p); s1p++)
X			if (*++s2p == '\0')
X				return s1;
X	return NULL;
X}
X
X/*
X	Convert the regular expression that we used to
X	locate identifiers in the id database into one
X	suitable for locating the identifiers in files.
X*/
Xchar *
XfileRE(name0, leftDelimit, rightDelimit)
X	char		*name0;
X	char		*leftDelimit;
X	char		*rightDelimit;
X{
X	static char	reBuf[BUFSIZ];
X	register char	*name = name0;
X
X	if (FindFunc == findNumber && Merging) {
X		sprintf(reBuf, "%s0*[Xx]*0*%d[Ll]*%s", leftDelimit, stoi(name), rightDelimit);
X		return reBuf;
X	}
X
X	if (!isMagic(name) && name[0] != '^')
X		return NULL;
X
X	if (name[0] == '^')
X		name0++;
X	else
X		leftDelimit = "";
X	while (*++name)
X		;
X	if (*--name == '$')
X		*name = '\0';
X	else
X		rightDelimit = "";
X
X	sprintf(reBuf, "%s%s%s", leftDelimit, name0, rightDelimit);
X	return reBuf;
X}
X
Xlong
XsearchName(name)
X	char		*name;
X{
X	long		offset;
X
X	AnchorOffset = 0;
X	offset = (long)bsearch(name, (char *)(Idh.idh_namo-1), Idh.idh_endo-(Idh.idh_namo-1), 1, idCompare);
X	if (offset == 0)
X		offset = AnchorOffset;
X	if (offset == 0)
X		return 0;
X	fseek(IdFILE, offset, 0);
X	skipFF(IdFILE);
X	return ftell(IdFILE);
X}
X
Xint
XidCompare(key, offset)
X	register char	*key;
X	long		offset;
X{
X	register int	c;
X
X	fseek(IdFILE, offset, 0);
X	skipFF(IdFILE);
X	getc(IdFILE);
X
X	while (*key == (c = getc(IdFILE)))
X		if (*key++ == '\0')
X			return 0;
X	if (*key == '\0' && FindFunc == findAnchor)
X		AnchorOffset = offset;
X
X	return *key - c;
X}
X
X/*
X	Are there any magic Regular Expression meta-characters in name??
X*/
Xbool
XisMagic(name)
X	register char	*name;
X{
X	char		*magichar = "[]{}().*+^$";
X	int		backslash = 0;
X
X	if (*name == '^')
X		name++;
X	while (*name) {
X		if (*name == '\\')
X			name++, backslash++;
X		else if (strchr(magichar, *name))
X			return TRUE;
X		name++;
X	}
X	if (backslash)
X		while (*name) {
X			if (*name == '\\')
X				strcpy(name, name+1);
X			name++;
X		}
X	return FALSE;
X}
X
Xchar **
XbitsToArgv(bitArray)
X	char		*bitArray;
X{
X	static char	**argv;
X	struct idarg	*idArgs;
X	register char	**av;
X	register int	i;
X#define	ARGV1stPATH	3 /* available argv[] slots before first pathname */
X
X	if (argv == NULL)
X		argv = (char **)malloc(sizeof(char *) * (Idh.idh_pthc + ARGV1stPATH + 2));
X
X	av = argv + ARGV1stPATH;
X	for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X		if (!BITTST(bitArray, i))
X			continue;
X		if (idArgs->ida_flags & IDA_BLANK) {
X			printf("BOTCH: blank index!\n");
X			abort();
X		}
X		if (!(idArgs->ida_flags & IDA_ADJUST)) {
X			idArgs->ida_arg = strsav(spanPath(IdDir, idArgs->ida_arg));
X			idArgs->ida_flags |= IDA_ADJUST;
X		}
X		*av++ = idArgs->ida_arg;
X	}
X	*av = NULL;
X	return (argv + ARGV1stPATH);
X}
SHAR_EOF
if test 16134 -ne "`wc -c < 'lid.c'`"
then
	echo shar: error transmitting "'lid.c'" '(should have been 16134 characters)'
fi
#	End of shell archive
exit 0.