mkid 11/11 (identifier cross reference tool)

Tom Horsley tom at ssd.csd.harris.com
Thu Dec 13 01:49:07 AEST 1990


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 11 (of 11)."
# Contents:  lid.c
# Wrapped by tom at hcx2 on Wed Dec 12 07:21:59 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'lid.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lid.c'\"
else
echo shar: Extracting \"'lid.c'\" \(20703 characters\)
sed "s/^X//" >'lid.c' <<'END_OF_FILE'
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	<signal.h>
X#include	<errno.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 matchPaths();
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;
Xbool            EchoOn = TRUE;
Xbool            CrunchOn = TRUE;
Xbool		pathRegExp = FALSE;
Xbool		matchBase = FALSE;
Xchar		IdDir[BUFSIZ];
Xlong		AnchorOffset;
Xint		BitArraySize;
Xchar		PWDname[BUFSIZ];
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>] [-r<dir>] [-mewdoxasknc] 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		useIDpath = TRUE;
X	int		usePWDpath = FALSE;
X	int		useRELpath = FALSE;
X	char *		RELpath;
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; pathRegExp = TRUE; 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		case 'k': CrunchOn = FALSE; break;
X		case 'n': EchoOn = FALSE; break;
X		case 'c': useIDpath = FALSE; usePWDpath = TRUE; break;
X		case 'b': matchBase = TRUE; break;
X		case 'r': useIDpath = FALSE; useRELpath = TRUE;
X			RELpath = arg; goto nextarg;
X		default:
X			usage();
X		}
X	nextarg:;
X	}
Xargsdone:
X
X	if (usePWDpath && useRELpath) {
X		fprintf(stderr,"%s: please use only one of -c or -r\n",MyName);
X		usage();
X	}
X	/* Look for the ID database up the tree */
X	if ((idFile = LookUp(idFile)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
X	/* Find out current directory to relate names to */
X	if (kshgetwd(PWDname) == NULL) {
X		fprintf(stderr,"%s: cannot determine current directory\n",MyName);
X		exit(1);
X	}
X	strcat(PWDname,"/");
X	/* Determine absolute path name that database files are relative to */
X	if (useIDpath) {
X		strcpy(IdDir, spanPath(PWDname, idFile));
X		*(strrchr(IdDir, '/') + 1) = '\0';
X	} else if (usePWDpath) {
X		strcpy(IdDir, PWDname);
X	} else {
X		strcpy(IdDir, spanPath(PWDname, RELpath));
X		strcat(IdDir, "/");
X	}
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	case 'p':
X		FindFunc = matchPaths;
X		doit = lookId;
X		break;
X	default:
X		MyName = "[algep]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	if (EchoOn) printf("%-14s ", name);
X	while (*argv) {
X		arg = *argv++;
X		if (*argv && CrunchOn && 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		{
X			int (*oldint)() = signal(SIGINT, SIG_IGN);
X			int (*oldquit)() = signal(SIGQUIT, SIG_IGN);
X
X			while(wait(0) == -1 && errno == EINTR)
X				/* loop */;
X
X			(void) signal(SIGINT, oldint);
X			(void) signal(SIGQUIT, oldquit);
X		}
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	char *		absname;
X	char *		relname;
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			absname = spanPath(IdDir, idArgs->ida_arg);
X			relname = relPath(PWDname, absname);
X			idArgs->ida_arg = strsav(strlen(relname) > strlen(absname) ? absname : relname);
X			idArgs->ida_flags |= IDA_ADJUST;
X		}
X		*av++ = idArgs->ida_arg;
X	}
X	*av = NULL;
X	return (argv + ARGV1stPATH);
X}
X
X/* pathWildCard implements a simple pattern matcher that emulates the
X * shell wild card capability.
X *
X *   * - any string of chars
X *   ? - any char
X *   [] - any char in set (if first char is !, any not in set)
X *   \ - literal match next char
X */
Xint
XpathWildCard(re, fn)
X	char		*re;
X	char		*fn;
X{
X	register int	c;
X	register int	i;
X	char		set[256];
X	int		revset;
X
X	while ((c = *re++) != '\0') {
X           if (c == '*') {
X           	if (*re == '\0') return 1; /* match anything at end */
X           	while (*fn != '\0') {
X           	   if (pathWildCard(re,fn)) return 1;
X           	   ++fn;
X           	}
X           	return 0;
X           } else if (c == '?') {
X           	if (*fn++ == '\0') return 0;
X           } else if (c == '[') {
X           	c = *re++;
X           	bzero(set,256);
X           	if (c == '!') {
X           		revset=1;
X           		c = *re++;
X           	} else {
X           		revset=0;
X           	}
X           	while (c != ']') {
X           	   if (c == '\\') c = *re++;
X           	   set[c]=1;
X           	   if ((*re == '-') && (*(re+1) != ']')) {
X           	      re+=1;
X           	      while (++c <= *re) set[c]=1;
X           	      ++re;
X           	   }
X           	   c = *re++;
X           	}
X           	if (revset) for (i=1;i<256;++i) set[i] = ! set[i];
X           	if (! set[*fn++]) return 0;
X           } else {
X           	if (c == '\\') c = *re++;
X           	if (c != *fn++) return 0;
X           }
X	}
X	return(*fn == '\0');
X}
X
X/* matchPaths implements the pid tool. This matches the *names* of files
X * in the database against the input pattern rather than the *contents*
X * of the files.
X */
Xint
XmatchPaths(re, doit)
X	char		*re;
X	void		(*doit)();
X{
X	char *		absname;
X	static char	*bitArray;
X	struct idarg	*idArgs;
X	register int	i;
X	char		*reCompiled;
X	int		count=0;
X	int		matched;
X
X	if (pathRegExp) {
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	}
X
X	if (bitArray == NULL) {
X		bitArray = malloc(BitArraySize);
X	}
X	bzero(bitArray, BitArraySize);
X
X	for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X		if (idArgs->ida_flags & IDA_BLANK) continue;
X		if (matchBase) {
X			absname = strrchr(idArgs->ida_arg, '/');
X			if (absname == NULL) {
X				absname = idArgs->ida_arg;
X			}
X		} else {
X			absname = spanPath(IdDir, idArgs->ida_arg);
X		}
X		if (pathRegExp) {
X#ifdef REGEX
X			matched = (regex(reCompiled, absname) != NULL);
X#endif
X#ifdef RE_EXEC
X			matched = (re_exec(absname));
X#endif
X		} else {
X			matched = pathWildCard(re, absname);
X		}
X		if (matched) {
X			BITSET(bitArray, i);
X			++count;
X		}
X	}
X	if (count)
X		(*doit)(re, bitsToArgv(bitArray));
X	return count;
X}
END_OF_FILE
if test 20703 -ne `wc -c <'lid.c'`; then
    echo shar: \"'lid.c'\" unpacked with wrong size!
fi
# end of 'lid.c'
fi
echo shar: End of archive 11 \(of 11\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
--
======================================================================
domain: tahorsley at csd.harris.com       USMail: Tom Horsley
  uucp: ...!uunet!hcx1!tahorsley               511 Kingbird Circle
                                               Delray Beach, FL  33444
+==== Censorship is the only form of Obscenity ======================+
|     (Wait, I forgot government tobacco subsidies...)               |
+====================================================================+



More information about the Alt.sources mailing list