[comp.sources.unix] v24i091: Program identifier database tools, Part03/07

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

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

#! /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 3 (of 7)."
# Contents:  Makefile getscan.c iiddef.h lid.1 scan-asm.c
# Wrapped by tom@hcx2 on Tue Feb 26 10:03:03 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(7491 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#!/bin/make -f
X
X# Copyright (c) 1986, Greg McGary
X# @(#)makefile	1.3 86/11/06
X
X# --------------------------------------------------------------------
X# System Dependent Configuration:
X#   Choose a pre-packaged set of options below, or roll your own.
X#   The relevant options are as follows:
X#
X# * If you have the `PW' library which includes the regular-expression
X#   funcions regcmp(3) and regex(3), then use `-DREGEX' in DEFS, and
X#   `-lPW' in LIBS.  If you have the regular-expression functions
X#   re_comp(3) and re_exec(3), use `-DRE_EXEC' in DEFS.  If you don't
X#   have any regular-expression functions, don't add either to DEFS.
X#
X# * If you do not have the 4.2 directory access libraries, add `-lndir'
X#   to LIBS, and define `-DNDIR' in DEFS. 
X#
X# * If your string libraries have index(3) and rindex(3) instead of
X#   strchr(3) and strrchr(3), use `-DRINDEX' in DEFS.
X#
X# * If your compiler chokes on pointers to functions returning void,
X#   use `-Dvoid=int' in DEFS.
X#
X# * If you have setlinebuf(3) in your stdio to set line-buffering on
X#   a stream, use `-DERRLINEBUF' in DEFS.
X#
X# * If you have a System-III/V terminal driver, define `TERMIO' in DEFS.
X#
X# * If you have ranlib(1), define `RANLIB' as such.  If you don't have
X#   it, set `RANLIB' to something harmless like `@:', or `echo'
X#
X# * If you want lists of file names compressed with csh {} notation by
X#   default, set -DCRUNCH_DEFAULT=1. If you want files printed with no
X#   "crunching", set -DCRUNCH_DEFAULT=0. (The -k and -g options allow
X#   runtime control regardless of the builtin default).
X#
X# * If your system supports the alloca() function for allocating space
X#   on the stack, defined -DUSE_ALLOCA
X# --------------------------------------------------------------------
X
XDEFS	=	-Dvoid=int -DREGEX -DTERMIO	# typical System-V defs
X# DEFS	=	-DREGEX -DNDIR -DTERMIO	# typical System-V defs
X# DEFS	=	-Dvoid=int -DRINDEX -DRE_EXEC -DNDIR	# typical V7 defs
X# DEFS	=	-Dvoid=int -DRINDEX -DRE_EXEC -DERRLINEBUF	# BSD defs
X
XLIBS	=	-lc -lPW	# typical System-V libs
X# LIBS	=	-lndir -lPW	# typical System-V libs
X# LIBS	=	-lndir	# typical V7 libs
X# LIBS	=	# typical BSD libs (none)
X
XRANLIB	=	@:	# system doesn't have ranlib (Sys-V)
X# RANLIB	=	ranlib	# system has ranlib (typically V7 & BSD)
X
XCRUNCH  =       -DCRUNCH_DEFAULT=1      # Original default - crunch file names
X#CRUNCH =       -DCRUNCH_DEFAULT=0      # Don't crunch names by default
X
XALLOCA  =       -DUSE_ALLOCA            # alloca support exists on system
X#ALLOCA =                               # system has no alloca() function
X
X# --------------------------------------------------------------------
X# Compilation / Loading options:
X#   Choose options to generate a system as an installed product,
X#   for debugging, or for performance profiling.
X# --------------------------------------------------------------------
X
X# CCFLG	=	-g -DDEBUG 	# debugging
X# CCFLG	=	-p	# profiling
XCCFLG	=	-O3 -g	# production
X
X# LDFLG	=	-g	# debugging
X# LDFLG	=	-p	# profiling
XLDFLG	=	# production
X
XCC	=	hc
X
X# --------------------------------------------------------------------
X
XSHELL =		/bin/ksh
XTARGETS =	libid.a $(PROGS)
XPROGS =		mkid lid idx fid iid $(LIDLINKS)
XDESTINATION_DIR = /usr/local
XMANDIR =        /usr/catman/local_man/man1
X
XLIDLINKS = 	gid aid eid pid
XCFLAGS =	$(CCFLG) -I. $(DEFS) $(CRUNCH) $(ALLOCA)
XLDFLAGS =	$(LDFLG) libid.a $(LIBS)
X
XOFILES =	init.o getscan.o scan-c.o scan-asm.o bsearch.o hash.o \
X		bitops.o basename.o gets0.o getsFF.o paths.o opensrc.o \
X		stoi.o uerror.o document.o bitcount.o wmatch.o bitsvec.o \
X		tty.o bzero.o scan-text.o cannoname.o kshgetwd.o unsymlink.o
X
XTEXJUNK=id.aux id.cp id.cps id.dvi id.fn id.fns id.ky id.kys id.log id.pg \
X	id.pgs id.toc id.tp id.tps id.vr id.vrs id-info
X
X# --------------------------------------------------------------------
X
Xall:		$(TARGETS)
X
Xlibid.a:	$(OFILES)
X		ar rv $@ $?
X		$(RANLIB) $@
X
Xmkid:		mkid.o libid.a
X		$(CC) -o $@ $@.o $(LDFLAGS)
X
Xfid:		fid.o libid.a
X		$(CC) -o $@ $@.o $(LDFLAGS)
X
Xlid:		lid.o libid.a
X		$(CC) -o $@ $@.o $(LDFLAGS)
X
Xidx:		idx.o libid.a
X		$(CC) -o $@ $@.o $(LDFLAGS)
X
Xiid:		iid.o iidfun.o
X		$(CC) -o iid iid.o iidfun.o $(LDFLG) $(LIBS)
X
Xiid.c:		iid.y
X		rm -f iid.c
X		yacc iid.y
X		mv y.tab.c iid.c
X
Xiidfun.o:	iidfun.c iiddef.h
X
Xiid.o:		iid.c iiddef.h
X		$(CC) $(CFLAGS) -DDEF -c iid.c
X
X$(LIDLINKS): lid
X		-/bin/rm -f $@
X		ln lid $@
X
Xinstall: installbin installman
X
Xinstallman:	fid.1 iid.1 lid.1 mkid.1
X		cp fid.1 iid.1 lid.1 mkid.1 $(MANDIR)
X		cd $(MANDIR) ; rm -f fid.1.z iid.1.z lid.1.z mkid.1.z aid.1.z \
X		                     gid.1.z eid.1.z
X		cd $(MANDIR) ; chmod 666 fid.1 iid.1 lid.1 mkid.1
X		cd $(MANDIR) ; mantocatman fid.1
X		cd $(MANDIR) ; mantocatman iid.1
X		cd $(MANDIR) ; mantocatman lid.1
X		cd $(MANDIR) ; mantocatman mkid.1
X		cd $(MANDIR) ; rm -f fid.1 iid.1 lid.1 mkid.1
X
Xinstallbin: $(PROGS)
X		chmod 777 $(PROGS)
X		-mv $(DESTINATION_DIR)/mkid $(DESTINATION_DIR)/OLDmkid
X		-mv $(DESTINATION_DIR)/lid $(DESTINATION_DIR)/OLDlid
X		-mv $(DESTINATION_DIR)/idx $(DESTINATION_DIR)/OLDidx
X		-mv $(DESTINATION_DIR)/fid $(DESTINATION_DIR)/OLDfid
X		-mv $(DESTINATION_DIR)/gid $(DESTINATION_DIR)/OLDgid
X		-mv $(DESTINATION_DIR)/aid $(DESTINATION_DIR)/OLDaid
X		-mv $(DESTINATION_DIR)/eid $(DESTINATION_DIR)/OLDeid
X		-mv $(DESTINATION_DIR)/pid $(DESTINATION_DIR)/OLDpid
X		-mv $(DESTINATION_DIR)/iid $(DESTINATION_DIR)/OLDiid
X		-rm -f $(DESTINATION_DIR)/iid.help
X		cp mkid $(DESTINATION_DIR)/mkid
X		cp lid $(DESTINATION_DIR)/lid
X		cp idx $(DESTINATION_DIR)/idx
X		cp fid $(DESTINATION_DIR)/fid
X		cp iid $(DESTINATION_DIR)/iid
X		cp iid.help $(DESTINATION_DIR)/iid.help
X		chmod 444 $(DESTINATION_DIR)/iid.help
X		ln $(DESTINATION_DIR)/lid $(DESTINATION_DIR)/gid
X		ln $(DESTINATION_DIR)/lid $(DESTINATION_DIR)/aid
X		ln $(DESTINATION_DIR)/lid $(DESTINATION_DIR)/eid
X		ln $(DESTINATION_DIR)/lid $(DESTINATION_DIR)/pid
X
Xclean:
X		rm -f $(TARGETS) *.o iid.c core a.out $(TEXJUNK)
X
Xid.tar:
X		cd ..; tar cvbf 20 id/id.tar id/*.[ch1-8] id/makefile id/TODO id/TUTORIAL
X
Xid.tar.Z:	id.tar
X		compress -b 14 <id.tar >id.tar.Z
X
Xid.shar:	id.shar-1 id.shar-2 id.shar-3
X
Xid.shar-1:
X		shar $(SHARFLAGS) TUTORIAL TODO makefile *.h *.[1-8] >$@
X
Xid.shar-2:
X		shar $(SHARFLAGS) [a-l]*.c >$@
X
Xid.shar-3:
X		shar $(SHARFLAGS) [m-z]*.c >$@
X
Xdebug:
X	make CCFLG='-g -DDEBUG' LDFLG='-g'
X
XID::
X	/bin/rm -f ID
X	mkid *.[chy]
X
XTAGS::
X	/bin/rm -f TAGS
X	etags -tw *.[chy]
X
X# TeX stuff - these actions count on several things being installed on
X# your system:
X#
X# tex - the document processor
X# texinfo.tex - the texinfo macro package used to format the document
X# texindex - the index sorting program used to generate the index
X# makeinfo - the program to turn texinfo files into online documentation
X#
X# A tex distribution tape can be obtained from the University of Washington.
X# send email to: elisabet@max.u.washington.edu for more info.
X#
X# The other texinfo tools are part of the Gnuemacs distribution and can
X# be obtained via FTP from prep.ai.mit.edu
X
X# Make the online info file by running makeinfo - texinfo-format-buffer from
X# within emacs probably will not work very well.
Xid-info: id.texinfo
X	makeinfo id.texinfo
X
X# If you are running TeX from a clean directory, need to run once to get
X# the initial .aux file with the cross reference info in it.
Xid.aux: id.texinfo
X	tex id.texinfo
X	texindex id.??
X
X# Running TeX twice here is probably overkill, but it makes absolutely sure
X# the index agrees with the actual location of text.
Xid.dvi: id.aux
X	tex id.texinfo
X	texindex id.??
X	tex id.texinfo
END_OF_FILE
if test 7491 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'getscan.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getscan.c'\"
else
echo shar: Extracting \"'getscan.c'\" \(7141 characters\)
sed "s/^X//" >'getscan.c' <<'END_OF_FILE'
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 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	char	*lt_filter;
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,	NULL},
X#define	SCAN_ASM	(&langtab[1])
X{&langtab[2],	"asm",		getAsmId,	setAsmArgs,	NULL},
X#define	SCAN_ADA	(&langtab[2])
X{&langtab[3],	"ada",		getAdaId,	setAdaArgs,	NULL},
X#define	SCAN_PASCAL	(&langtab[3])
X{&langtab[4],	"pascal",	getPascalId,	setPascalArgs,	NULL},
X#define	SCAN_LISP	(&langtab[4])
X{&langtab[5],	"lisp",		getLispId,	setLispArgs,	NULL},
X#define	SCAN_TEXT	(&langtab[5])
X{&langtab[6],	"text",		getTextId,	setTextArgs,	NULL},
X#define SCAN_VHIL	(&langtab[6])
X{&langtab[7],	"vhil",		getVhilId,	setCArgs,	NULL},
X#define SCAN_TEX	(&langtab[7])
X{&langtab[8],	"tex",		getTextId,	setTextArgs,	"detex -i %s"},
X#define SCAN_ROFF	(&langtab[8])
X{&langtab[9],	"roff",		getTextId,	setTextArgs,	"sed '/^\\.so/d' < %s | deroff"},
X#define SCAN_CATMAN	(&langtab[9])
X{&langtab[10],	"catman",	getTextId,	setTextArgs,	"pcat %s | col -b"},
X{ NULL, 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{&sufftab[7],	".x",	SCAN_VHIL	},
X{&sufftab[8],	".l",	SCAN_C		},	/* lex */
X{&sufftab[9],	".doc",	SCAN_TEXT	},
X{&sufftab[10],	".1",	SCAN_ROFF	},
X{&sufftab[11],	".tex",	SCAN_TEX	},
X{&sufftab[12],	".z",	SCAN_CATMAN	},
X{&sufftab[13],	"",	SCAN_TEXT	},	/* default to text */
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 *
XgetFilter(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_filter);
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>] [-S<lang>/<lang>/<filter>]\n", MyName);
X	exit(1);
X}
Xvoid
XsetScanArgs(op, arg)
X	int		op;
X	char		*arg;
X{
X	struct langtab	*ltp, *ltp2;
X	struct sufftab	*stp;
X	char		*lhs, *lhs2;
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 (stp->st_lang->lt_filter)
X				printf(" (%s)", stp->st_lang->lt_filter);
X		}
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 (stp->st_lang->lt_filter)
X					printf(" (%s)", stp->st_lang->lt_filter);
X			}
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", stp->st_suffix, stp->st_lang->lt_name);
X		if (stp->st_lang->lt_filter)
X			printf(" (%s)",stp->st_lang->lt_filter);
X		printf("\n");
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	} else if (*arg == '/') {
X		*arg++ = '\0';
X		if ((ltp = langSlot(lhs))->lt_next == NULL) {
X			ltp->lt_name = lhs;
X			ltp->lt_getid = getTextId;
X			ltp->lt_setargs = setTextArgs;
X			ltp->lt_filter = NULL;
X			ltp->lt_next = NEW(struct langtab);
X		}
X		lhs2 = arg;
X		arg = strchr(arg, '/');
X		if (arg == NULL) {
X			ltp2 = ltp;
X		} else {
X			*arg++ = '\0';
X			if ((ltp2 = langSlot(lhs2))->lt_next == NULL) {
X				fprintf(stderr,"%s: language %s not defined.\n", MyName, lhs2);
X				ltp2 = ltp;
X			}
X		}
X		ltp->lt_getid = ltp2->lt_getid;
X		ltp->lt_setargs = ltp2->lt_setargs;
X		if ((ltp->lt_filter != NULL) && (!strequ(arg, ltp->lt_filter))){
X			fprintf(stderr, "%s: Note: `%s/%s' overrides `%s/%s'\n", MyName, lhs, arg, lhs, ltp->lt_filter);
X		}
X		ltp->lt_filter = arg;
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}
END_OF_FILE
if test 7141 -ne `wc -c <'getscan.c'`; then
    echo shar: \"'getscan.c'\" unpacked with wrong size!
fi
# end of 'getscan.c'
fi
if test -f 'iiddef.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'iiddef.h'\"
else
echo shar: Extracting \"'iiddef.h'\" \(6331 characters\)
sed "s/^X//" >'iiddef.h' <<'END_OF_FILE'
X/* Definitions used by the iid program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
Xextern char * getenv() ;
Xextern int getopt() ;
Xextern char * optarg ;
Xextern int optind ;
X#define TRUE 1
X#define FALSE 0
X
X#ifdef DEF
X#define EXTERN
X#define INIT(a) =(a)
X#else
X#define EXTERN extern
X#define INIT(a)
X#endif
X
X#define BITS_PER_BYTE 8                /* used by bit set manipulation */
X
X#define HASH_SIZE 947                  /* size of hash table for file names */
X
X#ifndef HELPFILE
X#define HELPFILE "/usr/local/iid.help" /* The help file location */
X#endif
X
X#define INIT_FILES 8000                /* start with bits for this many */
X
X#define INIT_SETSPACE 500              /* start with room for this many */
X
X#define MAX(a,b) (((a)<(b))?(b):(a))
X
X#define MAXCMD 1024                    /* input command buffer size */
X
X#define MIN(a,b) (((a)>(b))?(b):(a))
X
X#ifndef PAGER
X#define PAGER "pg"
X#endif
X
X#define PROMPT "iid> "
X
X/* set_type is the struct defining a set of file names
X * The file names are stored in a symbol table and assigned
X * unique numbers. The set is a bit set of file numbers.
X * One of these set structs is calloced for each new set
X * constructed, the size allocated depends on the max file
X * bit number. An array of pointers to sets are kept to
X * represent the complete set of sets.
X */
X
Xtypedef struct set_struct {
X   char *                 set_desc ;   /* string describing the set */
X   int                    set_num ;    /* the set number */
X   int                    set_size ;   /* number of long words in set */
X   unsigned long int      set_tail ;   /* set extended with these bits */
X   unsigned long int      set_data[1] ;/* the actual set data (calloced) */
X} set_type ;
X
X/* id_type is one element of an id_list
X */
X
Xtypedef struct id_struct {
X   struct id_struct *     next_id ;    /* Linked list of IDs */
X   char                   id [ 1 ] ;   /* calloced data holding id string */
X} id_type ;
X
X/* id_list_type is used during parsing to build lists of
X * identifiers that will eventually represent arguments
X * to be passed to the database query programs.
X */
X
Xtypedef struct id_list_struct {
X   int                    id_count ;   /* count of IDs in the list */
X   id_type * *            end_ptr_ptr ;/* pointer to link word at end of list */
X   id_type *              id_list ;    /* pointer to list of IDs */
X} id_list_type ;
X
X/* symtab_type is used to record file names in the symbol table.
X */
Xtypedef struct symtab_struct {
X   struct symtab_struct * hash_link ;  /* list of files with same hash code */
X   int                    mask_word ;  /* word in bit vector */
X   unsigned long          mask_bit ;   /* bit in word */
X   char                   name [ 1 ] ; /* the file name */
X} symtab_type ;
X
Xextern void DescribeSets();
Xextern id_list_type * ExtendList();
Xextern void FlushSets();
Xextern void InitIid();
Xextern id_list_type * InitList();
Xextern symtab_type * InstallFile();
Xextern void OneDescription();
Xextern void PrintSet();
Xextern void RunPager();
Xextern set_type * RunProg();
Xextern void RunShell();
Xextern void ScanInit();
Xextern void SetDirectory();
Xextern set_type * SetIntersect();
Xextern set_type * SetInverse();
Xextern id_list_type * SetList();
Xextern set_type * SetUnion();
Xextern int yylex();
X
X/* LidCommand is the command to run for a Lid_group. It is set
X * to "lid -kmn" if explicitly preceeded by "lid", otherwise
X * it is the default command which is determined by an option.
X */
XEXTERN char * LidCommand ;
X
X/* DefaultCommand is the default command for a Lid_group. If
X * the -a option is given to iid, it is set to use 'aid'.
X */
XEXTERN char * DefaultCommand INIT("lid -kmn") ;
X
X/* FileList is a lexically ordered list of file symbol table
X * pointers. It is dynamically expanded when necessary.
X */
XEXTERN symtab_type * *    FileList INIT(NULL) ;
X
X/* FileSpace is the number of long ints in TheFiles array.
X */
XEXTERN int                FileSpace INIT(0) ;
X
X/* HashTable is the symbol table used to store file names. Each
X * new name installed is assigned the next consecutive file number.
X */
XEXTERN symtab_type *      HashTable [ HASH_SIZE ] ;
X
X/* HelpSet is a dummy set containing only one bit set which corresponds
X * to the help file name. Simply a cheesy way to maximize sharing of
X * the code that runs the pager.
X */
XEXTERN set_type *         HelpSet ;
X
X/* high_bit is a unsigned long with the most significant bit set.
X */
XEXTERN unsigned long      high_bit ;
X
X/* ListSpace is the amount of space avail in the FileList.
X */
XEXTERN int                ListSpace INIT(0) ;
X
X/* MaxCurFile - max word that has any bit currently set in the
X * TheFiles array.
X */
XEXTERN int                MaxCurFile INIT(0) ;
X
X/* NextFileNum is the file number that will be assigned to the next
X * new file name seen when it is installed in the symtab.
X */
XEXTERN int                NextFileNum INIT(0) ;
X
X/* NextMaskBit is the bit within the next mask word that will
X * correspond to the next file added to the symbol table.
X */
XEXTERN unsigned long      NextMaskBit ;
X
X/* NextMaskWord is the next word number to be assigned to a file
X * bit mask entry.
X */
XEXTERN int                NextMaskWord INIT(0) ;
X
X/* NextSetNum is the number that will be assigned to the next set
X * created. Starts at 0 because I am a C programmer.
X */
XEXTERN int                NextSetNum INIT(0) ;
X
X/* The PAGER program to run on a SHOW command.
X */
XEXTERN char               Pager[MAXCMD] ;
X
X/* Prompt - the string to use for a prompt.
X */
XEXTERN char               Prompt[MAXCMD] ;
X
X/* SetSpace is the number of pointers available in TheSets. TheSets
X * is realloced when we run out of space.
X */
XEXTERN int                SetSpace INIT(0) ;
X
X/* TheFiles is a bit set used to construct the initial set of files
X * generated while running one of the subprograms. It is copied to
X * the alloced set once we know how many bits are set.
X */
XEXTERN unsigned long *    TheFiles INIT(NULL) ;
X
X/* TheSets is a dynamically allocated array of pointers pointing
X * the sets that have been allocated. It represents the set of
X * sets.
X */
XEXTERN set_type * *       TheSets INIT(NULL) ;
X
X/* VerboseQuery controls the actions of the semantic routines during
X * the process of a query. If TRUE the sets are described as they
X * are constructed.
X */
XEXTERN int                VerboseQuery ;
END_OF_FILE
if test 6331 -ne `wc -c <'iiddef.h'`; then
    echo shar: \"'iiddef.h'\" unpacked with wrong size!
fi
# end of 'iiddef.h'
fi
if test -f 'lid.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lid.1'\"
else
echo shar: Extracting \"'lid.1'\" \(5678 characters\)
sed "s/^X//" >'lid.1' <<'END_OF_FILE'
X.TH LID 1
X.SH NAME
Xlid, gid, eid, aid, pid \- query id database
X.SH SYNOPSIS
X.B lid
X.RB [ \-f \^file]
X.RB [ \-u \^n]
X.RB [ \-r \^dir]
X.RB [ \-edoxamseknc]
Xpatterns...
X.PP
X.B gid
X.RB [ \-f \^file]
X.RB [ \-r \^dir]
X.RB [ \-edoxamsec]
Xpatterns...
X.PP
X.B eid
X.RB [ \-f \^file]
X.RB [ \-r \^dir]
X.RB [ \-doxamsec]
Xpatterns...
X.PP
X.B aid
X.RB [ \-f \^file]
X.RB [ \-r \^dir]
X.RB [ \-doxamsc]
Xpatterns...
X.PP
X.B pid
X.RB [ \-f \^file]
X.RB [ \-r \^dir]
X.RB [ \-ekncb]
Xpatterns...
X.SH DESCRIPTION
XThese commands provide a flexible query interface to the
X.I id
Xdatabase.
X.I Lid\^
Xdoes a lookup on
X.IR patters
Xand prints out lines in this way:
X.PP
X.nf
Xidname        ../hdir/hfile.h ../cdir/{cfile1,cfile2}.c
X.fi
X.PP
XNotice that multiple files with the same directory prefix
Xand suffix are concatenated in the globbing-set-notation of
X.IR csh (1).
XAlso notice that all of the
X.I id
Xdatabase query commands adjust the list of pathnames to be relative
Xto your current working directory, provided that
X.IR mkid (1)
Xwas used to build the database, and your working directory
Xis located within the sub-tree covered by the
X.I id
Xdatabase.
X.PP
XIf multiple names match on pattern, then there will be one line
Xof output per name.  The mnemonic significance of the name is
X\fI\|l(ookup) id\fP.
X.PP
X.I Gid
Xdoes a lookup and then searches for the names it matches in the
Xfiles where they occur.  The mnemonic for this name is
X\fI\|g(rep)id\fP. 
X.PP
X.I Eid
Xdoes a lookup, and then invokes an editor on all files with
Xthe matched name as an initial search string.  Of course, this
Xname stands for
X\fI\|e(dit) id\fP.
X.PP
X.I Eid
Xuses four environment variables to control its invocation of the
Xeditor.
XNaturally,
X.B EDITOR
Xis used to locate the editing program.
X.B EIDARG
Xis a
X.IR printf (3S)
Xstring used to specify the form of the initial-search-string
Xargument.  If the editor does not support such an argument,
Xthis variable may be left unset.
X.B EIDLDEL
Xand
X.B EIDRDEL
Xspecify the form of the left and right word-delimiters respectively.
XThe best way to explain the use of these last three variables is
Xwith an example.  Here are the proper settings for vi(1):
X.nf
XEIDARG='+/%s/'	# initial search argument template
XEIDLDEL='\\<'	# left word-delimiter
XEIDRDEL='\\>'	# right word-delimiter
X.fi
X.PP
X.I Patterns
Xmay be simple alpha-numeric strings, or regular expressions in the
Xstyle of
X.IR regcmp (3).
XIf the string contains no regular-expression meta-characters, it is
Xsearched for as a
X.IR word .
XIf the string contains meta-characters, or if the \-e argument is
Xsupplied, it is searched for as regular-expression.
X.PP
X.I Aid\^
Xproduces output in the style of
X.I lid\^
Xbut its pattern arguments are searched for as substrings within
Xthe identifiers in the database.  No regular-expression search
Xis performed, even if the pattern contains meta-characters.
XThe search is conducted in an alphabetic case insensitive manner.
XThe mnemonic for this name is
X\fI\|a(propos) id\fP. 
X.PP
X.I Pid\^
Xis used to match the input patterns against the names of the files
Xin the database rather than the contents of the files. The pattern
Xis assumed to be a simple shell wild card pattern unless the
X.B \-e
Xoption is given, in which case full regular expression matching
Xis used.
XThe
X.B \-b
Xoption can be used to restrict the match to just the basename portion
Xof the full absolute path name of the file.
XThe mnemonic for this name is
X\fI\|p(ath) id\fP. 
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.TP 10
X.BR \-u n
XLists all identifiers in the database that are non-unique within the first
X.I n
Xcharacters.  This facility is particularly helpful when porting a program
Xto a system whose compiler or linker has fewer significant characters
Xfor identifiers.
X.TP 10
X.BR \-r dir\^
XAssume the names stored in the database are relative to this directory.
XThis option is useful if you create the database in one place, then move
Xit somewhere else. Normally all the query tools assume the names in
Xthe database are relative to the location of the database.
X.TP 10
X.B \-c
XThis option is similar to
X.BR \-r ,
Xbut it tells the id query tool to assume the names in the ID database
Xare stored relative to the current working directory.
X.TP 10
X.B \-k
XSuppresses the use of \fL{\fP and \fL}\fP as a shorthand in the
Xgenerated list of file names. Each name is output in full.
X.TP 10
X.B \-n
XSuppresses printing the name of the search string, only the names of
Xthe files containing the string are printed. Together with the \fB\-k\fP
Xoption this can be used to generate lists of files to pass to other
Xprograms.
X.PP
X.TP 10
X.B \-b
XIn the
X.I pid
Xprogram, the
X.B \-b
Xoption is used to force pattern matching on just the base names of the
Xfile, otherwise the pattern matching is done on the full absolute file
Xname.
X.PP
XThe remaining options are for use in conjunction with numeric patterns:
X.TP 10
X.B \-doxa
XThese options may be specified in any combination.
XThey limit numeric matches to specific radixes.
XThe
X.BR \-d ,
X.BR \-o ,
Xand
X.B \-x
Xoptions limit matches to decimal, octal, and hexadecimal respectively.
XThe
X.BR \-a
Xoption is a shorthand for specifying all three radixes.
X.PP
XSearches for numbers 
Xare conducted numerically rather than lexically, so that all
Xrepresentations for a given number are potentially available
Xfrom a single search.
X.TP 10
X.B \-m
XMerge multiple lines of output into a single line.
X.TP 10
X.B \-s
XLimit the results of the search to identifiers that occur only
Xonce in the entire set of sources covered by the database.
XThis option is useful for finding identifiers that are defined
Xbut never used.
X.SH SEE ALSO
Xmkid(1),
Xfid(1).
END_OF_FILE
if test 5678 -ne `wc -c <'lid.1'`; then
    echo shar: \"'lid.1'\" unpacked with wrong size!
fi
# end of 'lid.1'
fi
if test -f 'scan-asm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scan-asm.c'\"
else
echo shar: Extracting \"'scan-asm.c'\" \(6157 characters\)
sed "s/^X//" >'scan-asm.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)scan-asm.c	1.2 86/11/06";
X
X#include	<bool.h>
X#include	<stdio.h>
X#include	<string.h>
X#include	<ctype.h>
X#include	<id.h>
X
Xchar *getAsmId();
Xvoid setAsmArgs();
X
Xstatic void clrCtype();
Xstatic void setCtype();
X
X#define	I1	0x01	/* 1st char of an identifier [a-zA-Z_] */
X#define	NM	0x02	/* digit [0-9a-fA-FxX] */
X#define	NL	0x04	/* newline: \n */
X#define	CM	0x08	/* assembler comment char: usually # or | */
X#define	IG	0x10	/* ignore `identifiers' with these chars in them */
X#define	C1	0x20	/* C comment introduction char: / */
X#define	C2	0x40	/* C comment termination  char: * */
X#define	EF	0x80	/* EOF */
X
X/* Assembly Language character classes */
X#define	ISID1ST(c)	((rct)[c]&(I1))
X#define	ISIDREST(c)	((rct)[c]&(I1|NM))
X#define	ISNUMBER(c)	((rct)[c]&(NM))
X#define	ISEOF(c)	((rct)[c]&(EF))
X#define	ISCOMMENT(c)	((rct)[c]&(CM))
X#define	ISBORING(c)	(!((rct)[c]&(EF|NL|I1|NM|CM|C1)))
X#define	ISCBORING(c)	(!((rct)[c]&(EF|NL)))
X#define	ISCCBORING(c)	(!((rct)[c]&(EF|C2)))
X#define	ISIGNORE(c)	((rct)[c]&(IG))
X
Xstatic char idctype[] = {
X
X	EF,
X
X	/*      0       1       2       3       4       5       6       7   */
X	/*    -----   -----   -----   -----   -----   -----   -----   ----- */
X
X	/*000*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*010*/	0,	0,	NL,	0,	0,	0,	0,	0,
X	/*020*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*030*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*040*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*050*/	0,	0,	C2,	0,	0,	0,	0,	C1,
X	/*060*/	NM,	NM,	NM,	NM,	NM,	NM,	NM,	NM,	
X	/*070*/	NM,	NM,	0,	0,	0,	0,	0,	0,
X	/*100*/	0,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1,
X	/*110*/	I1,	I1,	I1,	I1,	I1|NM,	I1,	I1,	I1,
X	/*120*/	I1,	I1,	I1,	I1,	I1,	I1,	I1,	I1,
X	/*130*/	I1|NM,	I1,	I1,	0,	0,	0,	0,	I1,
X	/*140*/	0,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1|NM,	I1,
X	/*150*/	I1,	I1,	I1,	I1,	I1|NM,	I1,	I1,	I1,
X	/*160*/	I1,	I1,	I1,	I1,	I1,	I1,	I1,	I1,
X	/*170*/	I1|NM,	I1,	I1,	0,	0,	0,	0,	0,
X
X	/*200*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*210*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*220*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*230*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*240*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*250*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*260*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*270*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*300*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*310*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*320*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*330*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*340*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*350*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*360*/	0,	0,	0,	0,	0,	0,	0,	0,
X	/*370*/	0,	0,	0,	0,	0,	0,	0,	0,
X
X};
X
Xstatic bool eatUnder = TRUE;
Xstatic bool preProcess = TRUE;
X
X/*
X	Grab the next identifier the assembly language
X	source file opened with the handle `inFILE'.
X	This state machine is built for speed, not elegance.
X*/
Xchar *
XgetAsmId(inFILE, flagP)
X	FILE		*inFILE;
X	int		*flagP;
X{
X	static char	idBuf[BUFSIZ];
X	register char	*rct = &idctype[1];
X	register int	c;
X	register char	*id = idBuf;
X	static bool	newLine = TRUE;
X
Xtop:
X	c = getc(inFILE);
X	if (preProcess > 0 && newLine) {
X		newLine = FALSE;
X		if (c != '#')
X			goto next;
X		while (ISBORING(c))
X			c = getc(inFILE);
X		if (!ISID1ST(c))
X			goto next;
X		id = idBuf;
X		*id++ = c;
X		while (ISIDREST(c = getc(inFILE)))
X			*id++ = c;
X		*id = '\0';
X		if (strequ(idBuf, "include")) {
X			while (c != '"' && c != '<')
X				c = getc(inFILE);
X			id = idBuf;
X			*id++ = c = getc(inFILE);
X			while ((c = getc(inFILE)) != '"' && c != '>')
X				*id++ = c;
X			*id = '\0';
X			*flagP = IDN_STRING;
X			return idBuf;
X		}
X		if (strnequ(idBuf, "if", 2)
X		|| strequ(idBuf, "define")
X		|| strequ(idBuf, "undef"))
X			goto next;
X		while (c != '\n')
X			c = getc(inFILE);
X		newLine = TRUE;
X		goto top;
X	}
X
Xnext:
X	while (ISBORING(c))
X		c = getc(inFILE);
X
X	if (ISCOMMENT(c)) {
X		while (ISCBORING(c))
X			c = getc(inFILE);
X		newLine = TRUE;
X	}
X
X	if (ISEOF(c)) {
X		newLine = TRUE;
X		return NULL;
X	}
X
X	if (c == '\n') {
X		newLine = TRUE;
X		goto top;
X	}
X
X	if (c == '/') {
X		if ((c = getc(inFILE)) != '*')
X			goto next;
X		c = getc(inFILE);
X		for (;;) {
X			while (ISCCBORING(c))
X				c = getc(inFILE);
X			if ((c = getc(inFILE)) == '/') {
X				c = getc(inFILE);
X				break;
X			} else if (ISEOF(c)) {
X				newLine = TRUE;
X				return NULL;
X			}
X		}
X		goto next;
X	}
X
X	id = idBuf;
X	if (eatUnder && c == '_' && !ISID1ST(c = getc(inFILE))) {
X		ungetc(c, inFILE);
X		return "_";
X	}
X	*id++ = c;
X	if (ISID1ST(c)) {
X		*flagP = IDN_NAME;
X		while (ISIDREST(c = getc(inFILE)))
X			*id++ = c;
X	} else if (ISNUMBER(c)) {
X		*flagP = IDN_NUMBER;
X		while (ISNUMBER(c = getc(inFILE)))
X			*id++ = c;
X	} else {
X		if (isprint(c))
X			fprintf(stderr, "junk: `%c'", c);
X		else
X			fprintf(stderr, "junk: `\\%03o'", c);
X		goto next;
X	}
X
X	*id = '\0';
X	for (id = idBuf; *id; id++)
X		if (ISIGNORE(*id))
X			goto next;
X	ungetc(c, inFILE);
X	*flagP |= IDN_LITERAL;
X	return idBuf;
X}
X
Xstatic void
XsetCtype(chars, type)
X	char		*chars;
X	int		type;
X{
X	char		*rct = &idctype[1];
X
X	while (*chars)
X		rct[*chars++] |= type;
X}
Xstatic void
XclrCtype(chars, type)
X	char		*chars;
X	int		type;
X{
X	char		*rct = &idctype[1];
X
X	while (*chars)
X		rct[*chars++] &= ~type;
X}
X
Xextern char	*MyName;
Xstatic void
Xusage(lang)
X	char		*lang;
X{
X	fprintf(stderr, "Usage: %s -S%s([-c<cc>] [-u] [(+|-)a<cc>] [(+|-)p] [(+|-)C])\n", MyName, lang);
X	exit(1);
X}
Xstatic char *asmDocument[] =
X{
X"The Assembler scanner arguments take the form -Sasm<arg>, where",
X"<arg> is one of the following: (<cc> denotes one or more characters)",
X"  -c<cc> . . . . <cc> introduce(s) a comment until end-of-line.",
X"  (+|-)u . . . . (Do|Don't) strip a leading `_' from ids.",
X"  (+|-)a<cc> . . Allow <cc> in ids, and (keep|ignore) those ids.",
X"  (+|-)p . . . . (Do|Don't) handle C-preprocessor directives.",
X"  (+|-)C . . . . (Do|Don't) handle C-style comments. (/* */)",
XNULL
X};
Xvoid
XsetAsmArgs(lang, op, arg)
X	char		*lang;
X	int		op;
X	char		*arg;
X{
X	if (op == '?') {
X		document(asmDocument);
X		return;
X	}
X	switch (*arg++)
X	{
X	case 'a':
X		setCtype(arg, I1|((op == '-') ? IG : 0));
X		break;
X	case 'c':
X		setCtype(arg, CM);
X		break;
X	case 'u':
X		eatUnder = (op == '+');
X		break;
X	case 'p':
X		preProcess = (op == '+');
X		break;
X	case 'C':
X		if (op == '+') {
X			setCtype("/", C1);
X			setCtype("*", C2);
X		} else {
X			clrCtype("/", C1);
X			clrCtype("*", C2);
X		}
X		break;
X	default:
X		if (lang)
X			usage(lang);
X		break;
X	}
X}
END_OF_FILE
if test 6157 -ne `wc -c <'scan-asm.c'`; then
    echo shar: \"'scan-asm.c'\" unpacked with wrong size!
fi
# end of 'scan-asm.c'
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
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.