[comp.sources.unix] v24i089: Program identifier database tools, Part01/07

rsalz@bbn.com (Rich Salz) (06/06/91)

Submitted-by: Tom Horsley <tom@hcx2.ssd.csd.harris.com>
Posting-number: Volume 24, Issue 89
Archive-name: mkid2/part01

[ The Subject line, my choice, is not very good.  MKID, however, is
  a very good program.  -r$ ]

   An ID database is simply a file containing a list of file names, a
list of identifiers, and a binary relation (stored as a bit matrix)
indicating which of the identifiers appear in each file.  With this
database and some tools to manipulate the data, a host of tasks
become simpler and faster. You can `grep' through hundreds of files
for a name, skipping the files that don't contain the name.  You can
search for all the memos containing references to a project.  You can
edit every file that calls some function, adding a new required
argument. Anyone with a large software project to maintain, or a
large set of text files to organize can benefit from the ID database
and the tools that manipulate it.

   There are several programs in the ID family.  The `mkid' program
scans the files, finds the identifiers and builds the ID database. 
The `lid' and `aid' tools are used to generate lists of file names
containing an identifier (perhaps to recompile every file that
references a macro which just changed). The `eid' program will invoke
an editor on each of the files containing an identifier and the `gid'
program will `grep' for an identifier in the subset of files known to
contain it.  The `pid' tool is used to query the path names of the
files in the database (rather than the contents).  Finally, the `iid'
tool is an interactive program supporting complex queries to
intersect and join sets of file names.

#! /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 1 (of 7)."
# Contents:  MANIFEST README Status TODO basename.c bitcount.c bitops.c
#   bitops.h bitsvec.c bool.h bsearch.c bzero.c document.c extern.h
#   fid.1 fid.c gets0.c getsFF.c gid.el hash.c id.h idx.c init.c
#   kshgetwd.c numtst.c opensrc.c patchlevel.h radix.h stoi.c string.h
#   tty.c uerror.c wmatch.c
# Wrapped by tom@hcx2 on Tue Feb 26 10:03:00 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1757 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X Makefile                   3	
X README                     1	
X Status                     1	
X TODO                       1	
X TUTORIAL                   4	
X basename.c                 1	
X bitcount.c                 1	
X bitops.c                   1	
X bitops.h                   1	
X bitsvec.c                  1	
X bool.h                     1	
X bsearch.c                  1	
X bzero.c                    1	
X cannoname.c                2	
X document.c                 1	
X extern.h                   1	
X fid.1                      1	
X fid.c                      1	
X gets0.c                    1	
X getsFF.c                   1	
X getscan.c                  3	
X gid.el                     1	
X hash.c                     1	
X id.h                       1	
X id.texinfo                 7	
X idx.c                      1	
X iid.1                      2	
X iid.help                   2	
X iid.y                      4	
X iiddef.h                   3	
X iidfun.c                   5	
X init.c                     1	
X kshgetwd.c                 1	
X lid.1                      3	
X lid.c                      6	
X mkid.1                     2	
X mkid.c                     5	
X numtst.c                   1	
X opensrc.c                  1	
X patchlevel.h               1	
X paths.c                    2	
X radix.h                    1	
X scan-asm.c                 3	
X scan-c.c                   4	
X scan-text.c                2	
X stoi.c                     1	
X string.h                   1	
X symfunc.el                 2	
X tty.c                      1	
X uerror.c                   1	
X unsymlink.c                2	
X wmatch.c                   1	
END_OF_FILE
if test 1757 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2051 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XHere is the overview section of the id.texinfo document:
X
XOverview
X********
X
X   An ID database is simply a file containing a list of file names, a
Xlist of identifiers, and a binary relation (stored as a bit matrix)
Xindicating which of the identifiers appear in each file.  With this
Xdatabase and some tools to manipulate the data, a host of tasks
Xbecome simpler and faster. You can `grep' through hundreds of files
Xfor a name, skipping the files that don't contain the name.  You can
Xsearch for all the memos containing references to a project.  You can
Xedit every file that calls some function, adding a new required
Xargument. Anyone with a large software project to maintain, or a
Xlarge set of text files to organize can benefit from the ID database
Xand the tools that manipulate it.
X
X   There are several programs in the ID family.  The `mkid' program
Xscans the files, finds the identifiers and builds the ID database. 
XThe `lid' and `aid' tools are used to generate lists of file names
Xcontaining an identifier (perhaps to recompile every file that
Xreferences a macro which just changed). The `eid' program will invoke
Xan editor on each of the files containing an identifier and the `gid'
Xprogram will `grep' for an identifier in the subset of files known to
Xcontain it.  The `pid' tool is used to query the path names of the
Xfiles in the database (rather than the contents).  Finally, the `iid'
Xtool is an interactive program supporting complex queries to
Xintersect and join sets of file names.
X
XThat ends the overview.
X
X
XTo build and install mkid, look through the Makefile - all the various
Xconfiguration options are (more or less :-) documented there. Change them
Xaround to work for your system, and type "make" to build the programs.
X
XTo make the texinfo online documentation type "make id-info".
X
XTo make the printed manual construct the .dvi file with "make id.dvi".  You
Xwill have to figure out how printing .dvi files works on your system (talk
Xto a local TeX guru -- if you don't have TeX, you won't be able to print the
Xmanual, sorry).
END_OF_FILE
if test 2051 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Status' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Status'\"
else
echo shar: Extracting \"'Status'\" \(1537 characters\)
sed "s/^X//" >'Status' <<'END_OF_FILE'
XIn the original alt.sources posting, this file started off:
X
X   This is the mkid package originally posted to the net around September of
X   1987 by Greg McGary (who then vanished from the net). Since then I have been
X   extensively hacking it, and so have others. In an effort to have all of us
X   benefit from the modifications and improvements we all have made, I have
X   (probably foolishly :-) volunteered to "take over" mkid.
X
XSince then, Greg has revealed that he is still alive and on the net, and
Xhe apparently has lots of plans for mkid revisions (but not much time to
Xdo them -- a situation we are probably all familiar with).
X
XAnyway, after I post this version to comp.sources.unix, I will probably
Xlet Greg take over as the official maintainer.
X
XThis version contains some cleanup work done since the alt.sources posting
X(but no major changes). It also comes with a brand new id.texinfo file
Xcontaining the latest and greatest documentation for the tools (Note: I have
Xno plans to upgrade the man pages, the texinfo doc is the only place where
Xthe latest and greatest options are documented right now).
X
XThis is the final posting to alt.sources. It contains the patches to upgrade
Xthe original alt.sources posting to what I now have. If a few days go past
Xwith no additional bugs cropping up, I will send it all off to
Xcomp.sources.unix.
X
XYou can reach me (Tom Horsley) at:
X   tahorsley@csd.harris.com or ...!uunet!hcx1!tahorsley
X
XThe email address I have for Greg McGary is:
X   gm@blip.wsrcc.com or ...!uunet!wsrcc!blip!gm
END_OF_FILE
if test 1537 -ne `wc -c <'Status'`; then
    echo shar: \"'Status'\" unpacked with wrong size!
fi
# end of 'Status'
fi
if test -f 'TODO' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'TODO'\"
else
echo shar: Extracting \"'TODO'\" \(546 characters\)
sed "s/^X//" >'TODO' <<'END_OF_FILE'
XEnhancements:
X~~~~~~~~~~~~~
Xmkid:
X	handle attributes: IDN_NOISE
X	add makefile scanner
X
Xgetid-c:
X	add stuff to recognize float & double constants properly.
X
X[lgea]id:
X	recursively search sub-dirs for ID databases and optionally
X		merge everything into one BIG list
Xlid:
X	print attribute flags, add cmd-line args to query by flags
X	break out searching junk into lib-funcs that are useful to editors
X
XNew Applications:
X~~~~~~~~~~~~~~~~~
Xignid:
X	frob the IDN_NOISE attribute of an id in an existing ID database.
X		takes ids on command line or stdin.
END_OF_FILE
if test 546 -ne `wc -c <'TODO'`; then
    echo shar: \"'TODO'\" unpacked with wrong size!
fi
# end of 'TODO'
fi
if test -f 'basename.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'basename.c'\"
else
echo shar: Extracting \"'basename.c'\" \(433 characters\)
sed "s/^X//" >'basename.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 433 -ne `wc -c <'basename.c'`; then
    echo shar: \"'basename.c'\" unpacked with wrong size!
fi
# end of 'basename.c'
fi
if test -f 'bitcount.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitcount.c'\"
else
echo shar: Extracting \"'bitcount.c'\" \(643 characters\)
sed "s/^X//" >'bitcount.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 643 -ne `wc -c <'bitcount.c'`; then
    echo shar: \"'bitcount.c'\" unpacked with wrong size!
fi
# end of 'bitcount.c'
fi
if test -f 'bitops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitops.c'\"
else
echo shar: Extracting \"'bitops.c'\" \(992 characters\)
sed "s/^X//" >'bitops.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 992 -ne `wc -c <'bitops.c'`; then
    echo shar: \"'bitops.c'\" unpacked with wrong size!
fi
# end of 'bitops.c'
fi
if test -f 'bitops.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitops.h'\"
else
echo shar: Extracting \"'bitops.h'\" \(537 characters\)
sed "s/^X//" >'bitops.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)bitops.h	1.1 86/10/09 */
X
X#define	BITTST(ba, bn)	((ba)[(bn) >> 3] &  (1 << ((bn) & 0x07)))
X#define	BITSET(ba, bn)	((ba)[(bn) >> 3] |= (1 << ((bn) & 0x07)))
X#define	BITCLR(ba, bn)	((ba)[(bn) >> 3] &=~(1 << ((bn) & 0x07)))
X#define	BITAND(ba, bn)	((ba)[(bn) >> 3] &= (1 << ((bn) & 0x07)))
X#define	BITXOR(ba, bn)	((ba)[(bn) >> 3] ^= (1 << ((bn) & 0x07)))
X
Xextern char *bitsand();
Xextern char *bitsclr();
Xextern char *bitsset();
Xextern char *bitsxor();
Xextern int bitsany();
Xextern int bitstst();
END_OF_FILE
if test 537 -ne `wc -c <'bitops.h'`; then
    echo shar: \"'bitops.h'\" unpacked with wrong size!
fi
# end of 'bitops.h'
fi
if test -f 'bitsvec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitsvec.c'\"
else
echo shar: Extracting \"'bitsvec.c'\" \(1614 characters\)
sed "s/^X//" >'bitsvec.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 1614 -ne `wc -c <'bitsvec.c'`; then
    echo shar: \"'bitsvec.c'\" unpacked with wrong size!
fi
# end of 'bitsvec.c'
fi
if test -f 'bool.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bool.h'\"
else
echo shar: Extracting \"'bool.h'\" \(128 characters\)
sed "s/^X//" >'bool.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)bool.h	1.1 86/10/09 */
X
Xtypedef	int	bool;
X#define	TRUE	(0==0)
X#define	FALSE	(0!=0)
END_OF_FILE
if test 128 -ne `wc -c <'bool.h'`; then
    echo shar: \"'bool.h'\" unpacked with wrong size!
fi
# end of 'bool.h'
fi
if test -f 'bsearch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bsearch.c'\"
else
echo shar: Extracting \"'bsearch.c'\" \(692 characters\)
sed "s/^X//" >'bsearch.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 692 -ne `wc -c <'bsearch.c'`; then
    echo shar: \"'bsearch.c'\" unpacked with wrong size!
fi
# end of 'bsearch.c'
fi
if test -f 'bzero.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bzero.c'\"
else
echo shar: Extracting \"'bzero.c'\" \(199 characters\)
sed "s/^X//" >'bzero.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 199 -ne `wc -c <'bzero.c'`; then
    echo shar: \"'bzero.c'\" unpacked with wrong size!
fi
# end of 'bzero.c'
fi
if test -f 'document.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'document.c'\"
else
echo shar: Extracting \"'document.c'\" \(188 characters\)
sed "s/^X//" >'document.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 188 -ne `wc -c <'document.c'`; then
    echo shar: \"'document.c'\" unpacked with wrong size!
fi
# end of 'document.c'
fi
if test -f 'extern.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'extern.h'\"
else
echo shar: Extracting \"'extern.h'\" \(1386 characters\)
sed "s/^X//" >'extern.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)extern.h	1.1 86/10/09 */
X
X/* miscellaneous external declarations */
X
Xextern FILE *initID();
Xextern char *getFilter();
Xextern FILE *openSrcFILE();
Xextern void closeSrcFILE();
Xextern char *(*getScanner())();
Xextern char *basename();
Xextern char *bsearch();
Xextern char *calloc();
Xextern char *coRCS();
Xextern char *dirname();
Xextern char *getAsmId();
Xextern char *getCId();
Xextern char *getLanguage();
Xextern char *getTextId();
Xextern char *getSCCS();
Xextern char *getVhilId();
Xextern char *getenv();
Xextern char *hashSearch();
Xextern char *intToStr();
Xextern char *malloc();
Xextern char *regcmp();
Xextern char *regex();
Xextern char *rootName();
Xextern char *spanPath();
Xextern char *relPath();
Xextern char *LookUp();
Xextern char *suffName();
Xextern char *uerror();
Xextern int bitCount();
Xextern int bitsCount();
Xextern int bitsToVec();
Xextern int canCrunch();
Xextern int dtoi();
Xextern int fgets0();
Xextern int getsFF();
Xextern int h1str();
Xextern int h2str();
Xextern int strToInt();
Xextern int otoi();
Xextern int radix();
Xextern int stoi();
Xextern int vecToBits();
Xextern int wordMatch();
Xextern int xtoi();
Xextern void bzero();
Xextern void document();
Xextern void filerr();
Xextern void setAsmArgs();
Xextern void setCArgs();
Xextern void setScanArgs();
Xextern void setTextArgs();
Xextern void skipFF();
X
Xextern char *MyName;
Xextern int errno;
END_OF_FILE
if test 1386 -ne `wc -c <'extern.h'`; then
    echo shar: \"'extern.h'\" unpacked with wrong size!
fi
# end of 'extern.h'
fi
if test -f 'fid.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fid.1'\"
else
echo shar: Extracting \"'fid.1'\" \(576 characters\)
sed "s/^X//" >'fid.1' <<'END_OF_FILE'
X.TH FID 1
X.SH NAME
Xfid \- query id database for specific files
X.SH SYNOPSIS
X.B fid
X.RB [ \-f \^file]
Xfile1 [ file2 ]
X.SH DESCRIPTION
X.I Fid
Xis a query tool for the id database. If you specify a single file
Xname as an argument, it prints a list of all the identifiers that
Xoccur in that file.
X.PP
XWhen you give it two file names it takes the intersection. It prints
Xonly the list of identifiers that occur in both files.
X.PP
XThe following options are recognized:
X.TP 10
X.BR \-f file\^
XUse
X.I file\^
Xas the database instead of the default
X.BR ID .
X.SH SEE ALSO
Xmkid(1),
Xlid(1).
END_OF_FILE
if test 576 -ne `wc -c <'fid.1'`; then
    echo shar: \"'fid.1'\" unpacked with wrong size!
fi
# end of 'fid.1'
fi
if test -f 'fid.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fid.c'\"
else
echo shar: Extracting \"'fid.c'\" \(2394 characters\)
sed "s/^X//" >'fid.c' <<'END_OF_FILE'
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	if ((idFile = LookUp(idFile)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
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}
END_OF_FILE
if test 2394 -ne `wc -c <'fid.c'`; then
    echo shar: \"'fid.c'\" unpacked with wrong size!
fi
# end of 'fid.c'
fi
if test -f 'gets0.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gets0.c'\"
else
echo shar: Extracting \"'gets0.c'\" \(575 characters\)
sed "s/^X//" >'gets0.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 575 -ne `wc -c <'gets0.c'`; then
    echo shar: \"'gets0.c'\" unpacked with wrong size!
fi
# end of 'gets0.c'
fi
if test -f 'getsFF.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getsFF.c'\"
else
echo shar: Extracting \"'getsFF.c'\" \(418 characters\)
sed "s/^X//" >'getsFF.c' <<'END_OF_FILE'
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}
END_OF_FILE
if test 418 -ne `wc -c <'getsFF.c'`; then
    echo shar: \"'getsFF.c'\" unpacked with wrong size!
fi
# end of 'getsFF.c'
fi
if test -f 'gid.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gid.el'\"
else
echo shar: Extracting \"'gid.el'\" \(788 characters\)
sed "s/^X//" >'gid.el' <<'END_OF_FILE'
X;;; put this in your GnuEmacs startup file  '~/.emacs' .
X;;; or autoload it from some other file. -wsr
X
X(require 'symfunc)
X
X(defun gid (command)
X  "Run gid, with user-specified args, and collect output in a buffer.
XWhile gid runs asynchronously, you can use the \\[next-error] command
Xto find the text that gid hits refer to."
X  (interactive (list (read-input "Run gid (with args): "
X				 (symbol-around-point))))
X  (require 'compile)
X  (compile1
X     (concat "gid " command)
X     "No more gid hits" "gid"
X  )
X)
X
X(defun aid (command)
X  "Run aid, with user-specified args, and collect output in a buffer."
X  (interactive (list (read-input "Run aid (with args): "
X				 (symbol-around-point))))
X  (require 'compile)
X  (compile1
X     (concat "aid -k " command)
X     "No aid hits" "aid"
X  )
X)
END_OF_FILE
if test 788 -ne `wc -c <'gid.el'`; then
    echo shar: \"'gid.el'\" unpacked with wrong size!
fi
# end of 'gid.el'
fi
if test -f 'hash.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hash.c'\"
else
echo shar: Extracting \"'hash.c'\" \(2237 characters\)
sed "s/^X//" >'hash.c' <<'END_OF_FILE'
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	unsigned int	(*h1)();	/* primary hash function */
X	unsigned int	(*h2)();	/* secondary hash function */
X	int		(*compar)();	/* key comparison function */
X	long		*probes;
X{
X	register unsigned int	hash1;
X	register unsigned 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}
END_OF_FILE
if test 2237 -ne `wc -c <'hash.c'`; then
    echo shar: \"'hash.c'\" unpacked with wrong size!
fi
# end of 'hash.c'
fi
if test -f 'id.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'id.h'\"
else
echo shar: Extracting \"'id.h'\" \(1716 characters\)
sed "s/^X//" >'id.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)id.h	1.1 86/10/09 */
X
X#define	IDFILE	"ID"
X
Xstruct idhead {
X	char	idh_magic[2];	/* magic number */
X#define	IDH_MAGIC "\311\304"	/* magic-number ("ID" with hi bits) */
X	short	idh_vers;	/* id-file version number */
X#define	IDH_VERS	2	/* current version */
X	int	idh_argc;	/* # of args for mkid update */
X	int	idh_pthc;	/* # of paths for mkid update */
X	int	idh_namc;	/* # of identifiers */
X	int	idh_vecc;	/* # of bytes in a path vector entry */
X	int	idh_bsiz;	/* # of bytes in entry (bufsiz for lid) */
X	long	idh_argo;	/* file offset of args for mkid update */
X	long	idh_namo;	/* file offset of identifier names */
X	long	idh_endo;	/* file offset of EOF */
X};
X
Xstruct idarg {
X	struct idarg	*ida_next;
X	char	*ida_arg;
X	int	ida_index;
X	char	ida_flags;
X#define	IDA_ADJUST	0x01
X#define	IDA_SCAN	0x02
X#define	IDA_PATH	0x04
X#define	IDA_ARG		0x08
X#define	IDA_BLANK	0x10
X};
X
Xstruct idname {
X	char	*idn_name;
X	char	*idn_bitv;
X	char	idn_flags;
X#define	IDN_SOLO	0x01	/* occurs only once */
X#define	IDN_NUMBER	0x02	/* is a number */
X#define	IDN_NAME	0x04	/* is a name */
X#define	IDN_STRING	0x08	/* is a string */
X#define	IDN_LITERAL	0x10	/* occurs as a literal (not string) */
X#define	IDN_NOISE	0x20	/* occurs very frequently */
X};
X
X/*
X	Extract the various logical fields of a name:
X
X	NAME: null-terminated ascii string
X	TAG:  index of name within a sorted array of all names
X	SOLO: boolean indicating that this name occurs exactly once
X*/
X#define	ID_PATHS(b) ((b)+strlen(b)+1)
X#define	ID_FLAGS(b) (*(b))
X#define	ID_STRING(b) ((b)+1)
X
X#define	NEW(type)	((type *)calloc(1, sizeof(type)))
X
X#define	GETARG(argc, argv)	((argc)--, *(argv)++)
X#define	UNGETARG(argc, argv)	((argc)++, *--(argv))
END_OF_FILE
if test 1716 -ne `wc -c <'id.h'`; then
    echo shar: \"'id.h'\" unpacked with wrong size!
fi
# end of 'id.h'
fi
if test -f 'idx.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'idx.c'\"
else
echo shar: Extracting \"'idx.c'\" \(1437 characters\)
sed "s/^X//" >'idx.c' <<'END_OF_FILE'
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	char		*suffix;
X	char		*filter;
X
X	if ((getId = getScanner(getLanguage(suffix=strrchr(path, '.')))) == NULL)
X		return;
X	if ((srcFILE = openSrcFILE(path, sccsDir, rcsDir, filter=getFilter(suffix))) == NULL)
X		return;
X
X	while ((key = (*getId)(srcFILE, &flags)) != NULL)
X		puts(key);
X
X	closeSrcFILE(srcFILE, filter);
X}
END_OF_FILE
if test 1437 -ne `wc -c <'idx.c'`; then
    echo shar: \"'idx.c'\" unpacked with wrong size!
fi
# end of 'idx.c'
fi
if test -f 'init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'init.c'\"
else
echo shar: Extracting \"'init.c'\" \(1442 characters\)
sed "s/^X//" >'init.c' <<'END_OF_FILE'
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
X/* initID opens idFile, reads the header into idhp (and verifies the magic
X * number), then builds the idArgs list holding the names of all the
X * files recorded in the database.
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}
END_OF_FILE
if test 1442 -ne `wc -c <'init.c'`; then
    echo shar: \"'init.c'\" unpacked with wrong size!
fi
# end of 'init.c'
fi
if test -f 'kshgetwd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kshgetwd.c'\"
else
echo shar: Extracting \"'kshgetwd.c'\" \(1781 characters\)
sed "s/^X//" >'kshgetwd.c' <<'END_OF_FILE'
X#include <string.h>
X#include <sys/param.h>
X#include <sys/stat.h>
X
Xextern char * getenv();
Xextern void cannoname();
Xextern char * unsymlink();
Xextern char * getwd();
X
X/* kshgetwd is a routine that acts just like getwd, but is optimized
X * for ksh users, taking advantage of the fact that ksh maintains
X * an environment variable named PWD holding path name of the
X * current working directory.
X *
X * The primary motivation for this is not really that it is algorithmically
X * simpler, but that it is much less likely to bother NFS if we can just
X * guess the name of the current working directory using the hint that
X * ksh maintains. Anything that avoids NFS gettar failed messages is
X * worth doing.
X */
Xchar *
Xkshgetwd(pathname)
X   char *   pathname;
X{
X   struct stat kshstat, dotstat ;
X   char        kshname[MAXPATHLEN] ;
X   char *      kshp ;
X
X   kshp = getenv("PWD") ;
X   if (kshp) {
X      /* OK, there was a PWD environment variable */
X      strcpy(kshname, kshp) ;
X      if (unsymlink(kshname)) {
X         /* And we could resolve the symbolic links through it */
X         if (kshname[0] == '/') {
X            /* And the name we have is an absolute path name */
X            if (stat(kshname, &kshstat) == 0) {
X               /* And we can stat the name */
X               if (stat(".", &dotstat) == 0) {
X                  /* And we can stat "." */
X                  if ((kshstat.st_dev == dotstat.st_dev) &&
X                      (kshstat.st_ino == dotstat.st_ino)) {
X                     /* By golly, that name is the same file as "." ! */
X                     return(strcpy(pathname, kshname)) ;
X                  }
X               }
X            }
X         }
X      }
X   }
X   /* Oh well, something did not work out right, do it the hard way */
X   return(getwd(pathname)) ;
X}
END_OF_FILE
if test 1781 -ne `wc -c <'kshgetwd.c'`; then
    echo shar: \"'kshgetwd.c'\" unpacked with wrong size!
fi
# end of 'kshgetwd.c'
fi
if test -f 'numtst.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'numtst.c'\"
else
echo shar: Extracting \"'numtst.c'\" \(60 characters\)
sed "s/^X//" >'numtst.c' <<'END_OF_FILE'
X000004
X00010
X012
X020
X04
X0x00004
X0x00010
X0x00a
X0XA
X10
X16
X4
X8
END_OF_FILE
if test 60 -ne `wc -c <'numtst.c'`; then
    echo shar: \"'numtst.c'\" unpacked with wrong size!
fi
# end of 'numtst.c'
fi
if test -f 'opensrc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'opensrc.c'\"
else
echo shar: Extracting \"'opensrc.c'\" \(2529 characters\)
sed "s/^X//" >'opensrc.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)opensrc.c	1.1 86/10/09";
X
X#include	<stdio.h>
X#include	<string.h>
X#include	<sys/types.h>
X#include	<sys/stat.h>
X
Xchar *findSrcFILE();
Xchar *getSCCS();
Xchar *coRCS();
X
XFILE *
XopenSrcFILE(path, sccsDir, rcsDir, filter)
X	char		*path;
X	char		*sccsDir;
X	char		*rcsDir;
X	char		*filter;
X{
X	char		*command = NULL;
X	char		*what = NULL;
X	char		*get = "get SCCS file";
X	char		*checkout = "checkout RCS file";
X	char		*dirName;
X	char		*baseName;
X	struct stat	statb;
X	char		popcom[1024];
X	FILE		*srcFILE;
X
X	if (stat(path, &statb) != 0) {
X		if ((baseName = strrchr(path, '/')) == NULL) {
X			dirName = ".";
X			baseName = path;
X		} else {
X			dirName = path;
X			*baseName++ = '\0';
X		}
X
X		if (rcsDir && (command = coRCS(dirName, baseName, rcsDir)))
X			what = checkout;
X		else if (sccsDir && (command = getSCCS(dirName, baseName, sccsDir)))
X			what = get;
X		else if ((command = coRCS(dirName, baseName, "RCS"))
X		     ||  (command = coRCS(dirName, baseName, ".")))
X			what = checkout;
X		else if ((command = getSCCS(dirName, baseName, "SCCS"))
X		     ||  (command = getSCCS(dirName, baseName, "sccs"))
X		     ||  (command = getSCCS(dirName, baseName, ".")))
X			what = get;
X
X		if (dirName == path)
X			*--baseName = '/';
X
X		if (!command) {
X			filerr("open", path);
X			return NULL;
X		}
X
X		system(command);
X		fprintf(stderr, "%s\n", command);
X	}
X	if (stat(path, &statb) != 0) {
X		filerr("open", path);
X		return NULL;
X	}
X	if (filter != NULL) {
X		sprintf(popcom,filter,path);
X		srcFILE = popen(popcom, "r");
X	} else {
X		srcFILE = fopen(path, "r");
X	}
X	if (srcFILE == NULL) {
X		filerr("open", path);
X	}
X	return srcFILE;
X}
X
Xvoid
XcloseSrcFILE(fp, filter)
X	FILE		*fp;
X	char		*filter;
X{
X	if (filter != NULL) {
X		pclose(fp);
X	} else {
X		fclose(fp);
X	}
X}
X
Xchar *
XgetSCCS(dir, base, sccsDir)
X	char		*dir;
X	char		*base;
X	char		*sccsDir;
X{
X	static char	cmdBuf[BUFSIZ];
X	char		fileBuf[BUFSIZ];
X	struct stat	statBuf;
X
X	if (!*sccsDir)
X		sccsDir = ".";
X
X	sprintf(fileBuf, "%s/%s/s.%s", dir, sccsDir, base);
X	if (stat(fileBuf, &statBuf) < 0)
X		return NULL;
X	sprintf(cmdBuf, "cd %s; get -s %s/s.%s", dir, sccsDir, base);
X
X	return cmdBuf;
X}
X
Xchar *
XcoRCS(dir, base, rcsDir)
X	char		*dir;
X	char		*base;
X	char		*rcsDir;
X{
X	static char	cmdBuf[BUFSIZ];
X	char		fileBuf[BUFSIZ];
X	struct stat	statBuf;
X
X	if (!*rcsDir)
X		rcsDir = ".";
X
X	sprintf(fileBuf, "%s/%s/%s,v", dir, rcsDir, base);
X	if (stat(fileBuf, &statBuf) < 0)
X		return NULL;
X	sprintf(cmdBuf, "cd %s; co -q %s/%s,v", dir, rcsDir, base);
X
X	return cmdBuf;
X}
END_OF_FILE
if test 2529 -ne `wc -c <'opensrc.c'`; then
    echo shar: \"'opensrc.c'\" unpacked with wrong size!
fi
# end of 'opensrc.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 2
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'radix.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'radix.h'\"
else
echo shar: Extracting \"'radix.h'\" \(225 characters\)
sed "s/^X//" >'radix.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)radix.h	1.1 86/10/09 */
X
X#define	RADIX_DEC	(1 << (10 - 1))
X#define	RADIX_OCT	(1 << (010 - 1))
X#define	RADIX_HEX	(1 << (0x10 - 1))
X#define	RADIX_ALL	(RADIX_DEC|RADIX_OCT|RADIX_HEX)
END_OF_FILE
if test 225 -ne `wc -c <'radix.h'`; then
    echo shar: \"'radix.h'\" unpacked with wrong size!
fi
# end of 'radix.h'
fi
if test -f 'stoi.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stoi.c'\"
else
echo shar: Extracting \"'stoi.c'\" \(1883 characters\)
sed "s/^X//" >'stoi.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)stoi.c	1.1 86/10/09";
X
X#include	<radix.h>
X#include	<ctype.h>
X
Xint dtoi();
Xint otoi();
Xint radix();
Xint stoi();
Xint xtoi();
X
X/*
X	Use the C lexical rules to determine an ascii number's radix.
X	The radix is returned as a bit map, so that more than one radix
X	may apply.  In particular, it is impossible to determine the
X	radix of 0, so return all possibilities.
X*/
Xint
Xradix(name)
X	register char	*name;
X{
X	if (!isdigit(*name))
X		return 0;
X	if (*name != '0')
X		return RADIX_DEC;
X	name++;
X	if (*name == 'x' || *name == 'X')
X		return RADIX_HEX;
X	while (*name && *name == '0')
X		name++;
X	return (RADIX_OCT | ((*name)?0:RADIX_DEC));
X}
X
X/*
X	Convert an ascii string number to an integer.
X	Determine the radix before converting.
X*/
Xint
Xstoi(name)
X	char		*name;
X{
X	switch (radix(name))
X	{
X	case RADIX_DEC:	return(dtoi(name));
X	case RADIX_OCT:	return(otoi(&name[1]));
X	case RADIX_HEX:	return(xtoi(&name[2]));
X	case RADIX_DEC|RADIX_OCT: return(0);
X	default:	return(-1);
X	}
X}
X
X/*
X	Convert an ascii octal number to an integer.
X*/
Xint
Xotoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (*name >= '0' && *name <= '7') {
X		n *= 010;
X		n += *name++ - '0';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
X
X/*
X	Convert an ascii decimal number to an integer.
X*/
Xint
Xdtoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (isdigit(*name)) {
X		n *= 10;
X		n += *name++ - '0';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
X
X/*
X	Convert an ascii hex number to an integer.
X*/
Xint
Xxtoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (isxdigit(*name)) {
X		n *= 0x10;
X		if (isdigit(*name))
X			n += *name++ - '0';
X		else if (islower(*name))
X			n += 0xa + *name++ - 'a';
X		else
X			n += 0xA + *name++ - 'A';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
END_OF_FILE
if test 1883 -ne `wc -c <'stoi.c'`; then
    echo shar: \"'stoi.c'\" unpacked with wrong size!
fi
# end of 'stoi.c'
fi
if test -f 'string.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'string.h'\"
else
echo shar: Extracting \"'string.h'\" \(525 characters\)
sed "s/^X//" >'string.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)string.h	1.1 86/10/09 */
X
X#ifdef RINDEX
X#define	strchr	index
X#define	strrchr	rindex
X#endif
X
Xextern char
X	*strcpy(),
X	*strncpy(),
X	*strcat(),
X	*strncat(),
X	*strchr(),
X	*strrchr(),
X	*strpbrk(),
X	*strtok();
X
Xextern long
X	strtol();
X
Xextern char	*calloc();
X
X#define	strequ(s1, s2)		(strcmp((s1), (s2)) == 0)
X#define	strnequ(s1, s2, n)	(strncmp((s1), (s2), (n)) == 0)
X#define	strsav(s)		(strcpy(calloc(1, strlen(s)+1), (s)))
X#define	strnsav(s, n)		(strncpy(calloc(1, (n)+1), (s), (n)))
END_OF_FILE
if test 525 -ne `wc -c <'string.h'`; then
    echo shar: \"'string.h'\" unpacked with wrong size!
fi
# end of 'string.h'
fi
if test -f 'tty.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tty.c'\"
else
echo shar: Extracting \"'tty.c'\" \(1114 characters\)
sed "s/^X//" >'tty.c' <<'END_OF_FILE'
X#ifdef TERMIO
X#include	<sys/termio.h>
X
Xstruct termio linemode, charmode, savemode;
X
Xsavetty()
X{
X	ioctl(0, TCGETA, &savemode);
X	charmode = linemode = savemode;
X
X	charmode.c_lflag &= ~(ECHO|ICANON|ISIG);
X	charmode.c_cc[VMIN] = 1;
X	charmode.c_cc[VTIME] = 0;
X
X	linemode.c_lflag |= (ECHO|ICANON|ISIG);
X	linemode.c_cc[VEOF] = 'd'&037;
X	linemode.c_cc[VEOL] = 0377;
X}
X
Xrestoretty()
X{
X	ioctl(0, TCSETA, &savemode);
X}
X
Xlinetty()
X{
X	ioctl(0, TCSETA, &linemode);
X}
X
Xchartty()
X{
X	ioctl(0, TCSETA, &charmode);
X}
X
X#else
X#include	<sgtty.h>
X
Xstruct sgttyb linemode, charmode, savemode;
X
Xsavetty()
X{
X#ifdef TIOCGETP
X	ioctl(0, TIOCGETP, &savemode);
X#else
X	gtty(0, &savemode);
X#endif
X	charmode = linemode = savemode;
X
X	charmode.sg_flags &= ~ECHO;
X	charmode.sg_flags |= RAW;
X
X	linemode.sg_flags |= ECHO;
X	linemode.sg_flags &= ~RAW;
X}
X
Xrestoretty()
X{
X#ifdef TIOCSETP
X	ioctl(0, TIOCSETP, &savemode);
X#else
X	stty(0, &savemode);
X#endif
X}
X
Xlinetty()
X{
X#ifdef TIOCSETP
X	ioctl(0, TIOCSETP, &linemode);
X#else
X	stty(0, &savemode);
X#endif
X}
X
Xchartty()
X{
X#ifdef TIOCSETP
X	ioctl(0, TIOCSETP, &charmode);
X#else
X	stty(0, &savemode);
X#endif
X}
X#endif
END_OF_FILE
if test 1114 -ne `wc -c <'tty.c'`; then
    echo shar: \"'tty.c'\" unpacked with wrong size!
fi
# end of 'tty.c'
fi
if test -f 'uerror.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uerror.c'\"
else
echo shar: Extracting \"'uerror.c'\" \(586 characters\)
sed "s/^X//" >'uerror.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)uerror.c	1.1 86/10/09";
X
X#include	<stdio.h>
X
Xchar *uerror();
Xvoid filerr();
X
Xextern int	errno;
Xextern int	sys_nerr;
Xextern char	*sys_errlist[];
Xextern char	*MyName;
X
Xchar	cannot[] = "%s: Cannot %s `%s' (%s)\n";
X
Xchar *
Xuerror()
X{
X	static char	errbuf[10];
X
X	if (errno == 0 || errno >= sys_nerr) {
X		sprintf(errbuf, "error %d", errno);
X		return(errbuf);
X	}
X	return(sys_errlist[errno]);
X}
X
Xvoid
Xfilerr(syscall, fileName)
X	char		*syscall;
X	char		*fileName;
X{
X	fprintf(stderr, cannot, MyName, syscall, fileName, uerror());
X}
END_OF_FILE
if test 586 -ne `wc -c <'uerror.c'`; then
    echo shar: \"'uerror.c'\" unpacked with wrong size!
fi
# end of 'uerror.c'
fi
if test -f 'wmatch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wmatch.c'\"
else
echo shar: Extracting \"'wmatch.c'\" \(830 characters\)
sed "s/^X//" >'wmatch.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)wmatch.c	1.1 86/10/09";
X
X#include	<bool.h>
X#include	<ctype.h>
X
Xbool wordMatch();
X
X/*
X	Does `name' occur in `line' delimited by non-alphanumerics??
X*/
Xbool
XwordMatch(name0, line)
X	char		*name0;
X	register char	*line;
X{
X	register char	*name = name0;
X#define IS_ALNUM(c)	(isalnum(c) || (c) == '_')
X
X	for (;;) {
X		/* find an initial-character match */
X		while (*line != *name) {
X			if (*line == '\n')
X				return FALSE;
X			line++;
X		}
X		/* do we have a word delimiter on the left ?? */
X		if (IS_ALNUM(line[-1])) {
X			line++;
X			continue;
X		}
X		/* march down both strings as long as we match */
X		while (*++name == *++line)
X			;
X		/* is this the end of `name', is there a word delimiter ?? */
X		if (*name == '\0' && !IS_ALNUM(*line))
X			return TRUE;
X		name = name0;
X	}
X}
END_OF_FILE
if test 830 -ne `wc -c <'wmatch.c'`; then
    echo shar: \"'wmatch.c'\" unpacked with wrong size!
fi
# end of 'wmatch.c'
fi
echo shar: End of archive 1 \(of 7\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.