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