mkid 11/11 (identifier cross reference tool)
Tom Horsley
tom at ssd.csd.harris.com
Thu Dec 13 01:49:07 AEST 1990
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 11 (of 11)."
# Contents: lid.c
# Wrapped by tom at hcx2 on Wed Dec 12 07:21:59 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'lid.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lid.c'\"
else
echo shar: Extracting \"'lid.c'\" \(20703 characters\)
sed "s/^X//" >'lid.c' <<'END_OF_FILE'
Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
Xstatic char sccsid[] = "@(#)lid.c 1.4 86/11/06";
X
X#include <bool.h>
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <signal.h>
X#include <errno.h>
X#include <radix.h>
X#include <id.h>
X#include <bitops.h>
X#include <extern.h>
X
X#ifdef REGEX
Xextern char *regex();
Xextern char *regcmp();
X#endif
X#ifdef RE_EXEC
Xextern char *re_comp();
Xextern int re_exec();
X#endif
X
Xbool isMagic();
Xchar **bitsToArgv();
Xchar *fileRE();
Xchar *strcpos();
Xint skipToArgv();
Xint findAnchor();
Xint findApropos();
X#if REGEX || RE_EXEC
Xint findRegExp();
X#endif
Xint matchPaths();
Xint findNonUnique();
Xint findNumber();
Xint findPlain();
Xint idCompare();
Xlong searchName();
Xvoid editId();
Xvoid grepId();
Xvoid lookId();
X
X#ifdef USG
X#define TOLOWER(c) (isupper(c) ? _tolower(c) : (c))
X#else
X#define TOLOWER(c) (isupper(c) ? tolower(c) : (c))
X#endif
X
X/*
X* Sorry about all the globals, but it's really cleaner this way.
X*/
XFILE *IdFILE;
Xbool Merging;
Xbool Radix;
Xbool EchoOn = TRUE;
Xbool CrunchOn = TRUE;
Xbool pathRegExp = FALSE;
Xbool matchBase = FALSE;
Xchar IdDir[BUFSIZ];
Xlong AnchorOffset;
Xint BitArraySize;
Xchar PWDname[BUFSIZ];
Xstruct idhead Idh;
Xstruct idarg *IdArgs;
Xint (*FindFunc)() = NULL;
Xint Solo = 0;
X#define IGNORE_SOLO(buf) \
X( \
X (Solo == '-' && !(ID_FLAGS(buf) & IDN_SOLO)) \
X || (Solo == '+' && (ID_FLAGS(buf) & IDN_SOLO)) \
X)
X
Xchar *MyName;
Xstatic void
Xusage()
X{
X fprintf(stderr, "Usage: %s [-f<file>] [-u<n>] [-r<dir>] [-mewdoxasknc] patterns...\n", MyName);
X exit(1);
X}
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X char *idFile = IDFILE;
X char *arg;
X long val;
X void (*doit)();
X bool forceMerge = FALSE;
X int uniqueLimit = 0;
X int useIDpath = TRUE;
X int usePWDpath = FALSE;
X int useRELpath = FALSE;
X char * RELpath;
X int op;
X
X MyName = basename(GETARG(argc, argv));
X
X while (argc) {
X arg = GETARG(argc, argv);
X switch (op = *arg++)
X {
X case '-':
X case '+':
X break;
X default:
X UNGETARG(argc, argv);
X goto argsdone;
X }
X while (*arg) switch (*arg++)
X {
X case 'f': idFile = arg; goto nextarg;
X case 'u': uniqueLimit = stoi(arg); goto nextarg;
X case 'm': forceMerge = TRUE; break;
X#if REGEX || RE_EXEC
X case 'e': FindFunc = findRegExp; pathRegExp = TRUE; break;
X#endif
X case 'w': FindFunc = findPlain; break;
X case 'd': Radix |= RADIX_DEC; break;
X case 'o': Radix |= RADIX_OCT; break;
X case 'x': Radix |= RADIX_HEX; break;
X case 'a': Radix |= RADIX_ALL; break;
X case 's': Solo = op; break;
X case 'k': CrunchOn = FALSE; break;
X case 'n': EchoOn = FALSE; break;
X case 'c': useIDpath = FALSE; usePWDpath = TRUE; break;
X case 'b': matchBase = TRUE; break;
X case 'r': useIDpath = FALSE; useRELpath = TRUE;
X RELpath = arg; goto nextarg;
X default:
X usage();
X }
X nextarg:;
X }
Xargsdone:
X
X if (usePWDpath && useRELpath) {
X fprintf(stderr,"%s: please use only one of -c or -r\n",MyName);
X usage();
X }
X /* Look for the ID database up the tree */
X if ((idFile = LookUp(idFile)) == NULL) {
X filerr("open", idFile);
X exit(1);
X }
X /* Find out current directory to relate names to */
X if (kshgetwd(PWDname) == NULL) {
X fprintf(stderr,"%s: cannot determine current directory\n",MyName);
X exit(1);
X }
X strcat(PWDname,"/");
X /* Determine absolute path name that database files are relative to */
X if (useIDpath) {
X strcpy(IdDir, spanPath(PWDname, idFile));
X *(strrchr(IdDir, '/') + 1) = '\0';
X } else if (usePWDpath) {
X strcpy(IdDir, PWDname);
X } else {
X strcpy(IdDir, spanPath(PWDname, RELpath));
X strcat(IdDir, "/");
X }
X if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
X filerr("open", idFile);
X exit(1);
X }
X BitArraySize = (Idh.idh_pthc + 7) >> 3;
X
X switch (MyName[0])
X {
X case 'a':
X FindFunc = findApropos;
X /*FALLTHROUGH*/
X case 'l':
X doit = lookId;
X break;
X case 'g':
X doit = grepId;
X break;
X case 'e':
X doit = editId;
X break;
X case 'p':
X FindFunc = matchPaths;
X doit = lookId;
X break;
X default:
X MyName = "[algep]id";
X usage();
X }
X
X if (argc == 0) {
X UNGETARG(argc, argv);
X *argv = ".";
X }
X
X while (argc) {
X arg = GETARG(argc, argv);
X if (FindFunc)
X ;
X else if ((radix(arg)) && (val = stoi(arg)) >= 0)
X FindFunc = findNumber;
X#if REGEX || RE_EXEC
X else if (isMagic(arg))
X FindFunc = findRegExp;
X#endif
X else if (arg[0] == '^')
X FindFunc = findAnchor;
X else
X FindFunc = findPlain;
X
X if ((doit == lookId && !forceMerge)
X || (FindFunc == findNumber && bitCount(Radix) > 1 && val > 7))
X Merging = FALSE;
X else
X Merging = TRUE;
X
X if (uniqueLimit) {
X if (!findNonUnique(uniqueLimit, doit))
X fprintf(stderr, "All identifiers are unique within the first %d characters\n", uniqueLimit);
X exit(0);
X } else if (!(*FindFunc)(arg, doit)) {
X fprintf(stderr, "%s: not found\n", arg);
X continue;
X }
X }
X exit(0);
X}
X
Xvoid
XlookId(name, argv)
X char *name;
X register char **argv;
X{
X register char *arg;
X register bool crunching = FALSE;
X register char *dir;
X
X if (EchoOn) printf("%-14s ", name);
X while (*argv) {
X arg = *argv++;
X if (*argv && CrunchOn && canCrunch(arg, *argv)) {
X if (crunching)
X printf(",%s", rootName(arg));
X else if ((dir = dirname(arg)) && dir[0] == '.' && dir[1] == '\0')
X printf("{%s", rootName(arg));
X else
X printf("%s/{%s", dir, rootName(arg));
X /*}}*/
X crunching = TRUE;
X } else {
X if (crunching) /*{*/
X printf(",%s}%s", rootName(arg), suffName(arg));
X else
X fputs(arg, stdout);
X crunching = FALSE;
X if (*argv)
X putchar(' ');
X }
X }
X putchar('\n');
X}
X
Xvoid
XgrepId(name, argv)
X char *name;
X char **argv;
X{
X FILE *gidFILE;
X char *gidName;
X char buf[BUFSIZ];
X char *delimit = "[^a-zA-Z0-9_]";
X char *re;
X char *reCompiled;
X int lineNumber;
X
X if (!Merging || (re = fileRE(name, delimit, delimit)) == NULL)
X re = NULL;
X#ifdef REGEX
X else if ((reCompiled = regcmp(re, 0)) == NULL) {
X fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
X return;
X }
X#endif
X#ifdef RE_EXEC
X else if ((reCompiled = re_comp(re)) != NULL) {
X fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
X return;
X }
X#endif
X
X buf[0] = ' '; /* sentry */
X while (*argv) {
X if ((gidFILE = fopen(gidName = *argv++, "r")) == NULL) {
X filerr("open", gidName);
X continue;
X }
X lineNumber = 0;
X while (fgets(&buf[1], sizeof(buf), gidFILE)) {
X lineNumber++;
X if (re) {
X#ifdef REGEX
X if (regex(reCompiled, buf) == NULL)
X#endif
X#ifdef RE_EXEC
X if (!re_exec(buf))
X#endif
X continue;
X } else if (!wordMatch(name, buf))
X continue;
X printf("%s:%d: %s", gidName, lineNumber, &buf[1]);
X }
X fclose(gidFILE);
X }
X}
X
Xvoid
XeditId(name, argv)
X char *name;
X char **argv;
X{
X char reBuf[BUFSIZ];
X char edArgBuf[BUFSIZ];
X char *re;
X int c;
X int skip;
X static char *editor, *eidArg, *eidRightDel, *eidLeftDel;
X
X if (editor == NULL && (editor = getenv("EDITOR")) == NULL) {
X char *ucb_vi = "/usr/ucb/vi";
X char *bin_vi = "/usr/bin/vi";
X
X if (access(ucb_vi, 01) == 0)
X editor = ucb_vi;
X else if (access(bin_vi, 01) == 0)
X editor = bin_vi;
X else
X editor = "/bin/ed"; /* YUCK! */
X if (editor == ucb_vi || editor == bin_vi) {
X eidArg = "+1;/%s/";
X eidLeftDel = "\\<";
X eidRightDel = "\\>";
X }
X }
X if (eidLeftDel == NULL) {
X eidArg = getenv("EIDARG");
X if ((eidLeftDel = getenv("EIDLDEL")) == NULL)
X eidLeftDel = "";
X if ((eidRightDel = getenv("EIDRDEL")) == NULL)
X eidRightDel = "";
X }
X
X lookId(name, argv);
X savetty();
X for (;;) {
X printf("Edit? [y1-9^S/nq] "); fflush(stdout);
X chartty();
X c = (getchar() & 0177);
X restoretty();
X switch (TOLOWER(c))
X {
X case '/': case ('s'&037):
X putchar('/');
X /*FALLTHROUGH*/
X if ((skip = skipToArgv(argv)) < 0)
X continue;
X argv += skip;
X goto editit;
X case '1': case '2': case '3': case '4':
X case '5': case '6': case '7': case '8': case '9':
X putchar(c);
X skip = c - '0';
X break;
X case 'y':
X putchar(c);
X /*FALLTHROUGH*/
X case '\n':
X case '\r':
X skip = 0;
X break;
X case 'q':
X putchar(c);
X putchar('\n');
X exit(0);
X case 'n':
X putchar(c);
X putchar('\n');
X return;
X default:
X putchar(c);
X putchar('\n');
X continue;
X }
X
X putchar('\n');
X while (skip--)
X if (*++argv == NULL)
X continue;
X break;
X }
Xeditit:
X
X if (!Merging || (re = fileRE(name, eidLeftDel, eidRightDel)) == NULL)
X sprintf(re = reBuf, "%s%s%s", eidLeftDel, name, eidRightDel);
X
X switch (fork())
X {
X case -1:
X fprintf(stderr, "%s: Cannot fork (%s)\n", MyName, uerror());
X exit(1);
X case 0:
X argv--;
X if (eidArg) {
X argv--;
X sprintf(edArgBuf, eidArg, re);
X argv[1] = edArgBuf;
X }
X argv[0] = editor;
X execv(editor, argv);
X filerr("exec", editor);
X default:
X {
X int (*oldint)() = signal(SIGINT, SIG_IGN);
X int (*oldquit)() = signal(SIGQUIT, SIG_IGN);
X
X while(wait(0) == -1 && errno == EINTR)
X /* loop */;
X
X (void) signal(SIGINT, oldint);
X (void) signal(SIGQUIT, oldquit);
X }
X break;
X }
X}
X
Xint
XskipToArgv(argv)
X char **argv;
X{
X char pattern[BUFSIZ];
X int count;
X
X if (gets(pattern) == NULL)
X return -1;
X
X for (count = 0; *argv; count++, argv++)
X if (strcpos(*argv, pattern))
X return count;
X return -1;
X}
X
Xint
XfindPlain(arg, doit)
X char *arg;
X void (*doit)();
X{
X static char *buf, *bitArray;
X int size;
X
X if (searchName(arg) == 0)
X return 0;
X if (buf == NULL) {
X buf = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X if ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) == 0)
X return 0;
X size++;
X getsFF(&buf[size], IdFILE);
X if (IGNORE_SOLO(buf))
X return 0;
X
X vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X return 1;
X}
X
Xint
XfindAnchor(arg, doit)
X register char *arg;
X void (*doit)();
X{
X static char *buf, *bitArray;
X int count, size;
X int len;
X
X if (searchName(++arg) == 0)
X return 0;
X
X if (buf == NULL) {
X buf = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X len = strlen(arg);
X count = 0;
X while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X size++;
X getsFF(&buf[size], IdFILE);
X if (IGNORE_SOLO(buf))
X continue;
X if (!strnequ(arg, ID_STRING(buf), len))
X break;
X vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X if (Merging && count)
X (*doit)(--arg, bitsToArgv(bitArray));
X
X return count;
X}
X
X#if REGEX || RE_EXEC
Xint
XfindRegExp(re, doit)
X char *re;
X void (*doit)();
X{
X static char *buf, *bitArray;
X int count, size;
X char *reCompiled;
X
X#ifdef REGEX
X if ((reCompiled = regcmp(re, 0)) == NULL) {
X fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
X return 0;
X }
X#endif
X#ifdef RE_EXEC
X if ((reCompiled = re_comp(re)) != NULL) {
X fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
X return 0;
X }
X#endif
X fseek(IdFILE, Idh.idh_namo, 0);
X
X if (buf == NULL) {
X buf = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X count = 0;
X while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X size++;
X getsFF(&buf[size], IdFILE);
X if (IGNORE_SOLO(buf))
X continue;
X#ifdef REGEX
X if (regex(reCompiled, ID_STRING(buf)) == NULL)
X#endif
X#ifdef RE_EXEC
X if (!re_exec(ID_STRING(buf)))
X#endif
X continue;
X vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X if (Merging && count)
X (*doit)(re, bitsToArgv(bitArray));
X
X return count;
X}
X#endif
X
Xint
XfindNumber(arg, doit)
X char *arg;
X void (*doit)();
X{
X static char *buf, *bitArray;
X int count, size;
X register int rdx = 0;
X register int val;
X register bool hitDigits = FALSE;
X
X if ((val = stoi(arg)) <= 7)
X rdx |= RADIX_ALL;
X else
X rdx = radix(arg);
X fseek(IdFILE, Idh.idh_namo, 0);
X
X if (buf == NULL) {
X buf = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X count = 0;
X while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X size++;
X getsFF(&buf[size], IdFILE);
X if (hitDigits) {
X if (!isdigit(*ID_STRING(buf)))
X break;
X } else if (isdigit(*ID_STRING(buf)))
X hitDigits = TRUE;
X
X if (!((Radix ? Radix : rdx) & radix(ID_STRING(buf)))
X || stoi(ID_STRING(buf)) != val)
X continue;
X vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X if (Merging && count)
X (*doit)(arg, bitsToArgv(bitArray));
X
X return count;
X}
X
X/*
X Find identifiers that are non-unique within
X the first `count' characters.
X*/
Xint
XfindNonUnique(limit, doit)
X int limit;
X void (*doit)();
X{
X static char *buf1, *buf2, *bitArray;
X register char *old;
X register char *new;
X register int consecutive;
X char *cptmp;
X int itmp;
X int count, oldsize, newsize;
X char *name;
X
X if (limit <= 1)
X usage();
X
X fseek(IdFILE, Idh.idh_namo, 0);
X
X if (buf1 == NULL) {
X buf1 = malloc(Idh.idh_bsiz);
X buf2 = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X name = calloc(1, limit+2);
X name[0] = '^';
X old = buf1;
X *ID_STRING(new = buf2) = '\0';
X count = consecutive = 0;
X while ((oldsize = fgets0(old, Idh.idh_bsiz, IdFILE)) > 0) {
X oldsize++;
X getsFF(&old[oldsize], IdFILE);
X if (!(ID_FLAGS(old) & IDN_NAME))
X continue;
X cptmp = old; old = new; new = cptmp;
X itmp = oldsize; oldsize = newsize; newsize = itmp;
X if (!strnequ(ID_STRING(new), ID_STRING(old), limit)) {
X if (consecutive && Merging) {
X strncpy(&name[1], ID_STRING(old), limit);
X (*doit)(name, bitsToArgv(bitArray));
X }
X consecutive = 0;
X continue;
X }
X if (!consecutive++) {
X vecToBits(bitArray, &old[oldsize], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(old), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X vecToBits(bitArray, &new[newsize], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(new), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X
X return count;
X}
X
Xint
XfindApropos(arg, doit)
X char *arg;
X void (*doit)();
X{
X static char *buf, *bitArray;
X int count, size;
X
X fseek(IdFILE, Idh.idh_namo, 0);
X
X if (buf == NULL) {
X buf = malloc(Idh.idh_bsiz);
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X count = 0;
X while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
X size++;
X getsFF(&buf[size], IdFILE);
X if (IGNORE_SOLO(buf))
X continue;
X if (strcpos(ID_STRING(buf), arg) == NULL)
X continue;
X vecToBits(bitArray, &buf[size], Idh.idh_vecc);
X if (!Merging) {
X (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
X bzero(bitArray, BitArraySize);
X }
X count++;
X }
X if (Merging && count)
X (*doit)(arg, bitsToArgv(bitArray));
X
X return count;
X}
X
X/*
X if string `s2' occurs in `s1', return a pointer to the
X first match. Ignore differences in alphabetic case.
X*/
Xchar *
Xstrcpos(s1, s2)
X char *s1;
X char *s2;
X{
X register char *s1p;
X register char *s2p;
X char *s1last;
X
X for (s1last = &s1[strlen(s1) - strlen(s2)]; s1 <= s1last; s1++)
X for (s1p = s1, s2p = s2; TOLOWER(*s1p) == TOLOWER(*s2p); s1p++)
X if (*++s2p == '\0')
X return s1;
X return NULL;
X}
X
X/*
X Convert the regular expression that we used to
X locate identifiers in the id database into one
X suitable for locating the identifiers in files.
X*/
Xchar *
XfileRE(name0, leftDelimit, rightDelimit)
X char *name0;
X char *leftDelimit;
X char *rightDelimit;
X{
X static char reBuf[BUFSIZ];
X register char *name = name0;
X
X if (FindFunc == findNumber && Merging) {
X sprintf(reBuf, "%s0*[Xx]*0*%d[Ll]*%s", leftDelimit, stoi(name), rightDelimit);
X return reBuf;
X }
X
X if (!isMagic(name) && name[0] != '^')
X return NULL;
X
X if (name[0] == '^')
X name0++;
X else
X leftDelimit = "";
X while (*++name)
X ;
X if (*--name == '$')
X *name = '\0';
X else
X rightDelimit = "";
X
X sprintf(reBuf, "%s%s%s", leftDelimit, name0, rightDelimit);
X return reBuf;
X}
X
Xlong
XsearchName(name)
X char *name;
X{
X long offset;
X
X AnchorOffset = 0;
X offset = (long)bsearch(name, (char *)(Idh.idh_namo-1), Idh.idh_endo-(Idh.idh_namo-1), 1, idCompare);
X if (offset == 0)
X offset = AnchorOffset;
X if (offset == 0)
X return 0;
X fseek(IdFILE, offset, 0);
X skipFF(IdFILE);
X return ftell(IdFILE);
X}
X
Xint
XidCompare(key, offset)
X register char *key;
X long offset;
X{
X register int c;
X
X fseek(IdFILE, offset, 0);
X skipFF(IdFILE);
X getc(IdFILE);
X
X while (*key == (c = getc(IdFILE)))
X if (*key++ == '\0')
X return 0;
X if (*key == '\0' && FindFunc == findAnchor)
X AnchorOffset = offset;
X
X return *key - c;
X}
X
X/*
X Are there any magic Regular Expression meta-characters in name??
X*/
Xbool
XisMagic(name)
X register char *name;
X{
X char *magichar = "[]{}().*+^$";
X int backslash = 0;
X
X if (*name == '^')
X name++;
X while (*name) {
X if (*name == '\\')
X name++, backslash++;
X else if (strchr(magichar, *name))
X return TRUE;
X name++;
X }
X if (backslash)
X while (*name) {
X if (*name == '\\')
X strcpy(name, name+1);
X name++;
X }
X return FALSE;
X}
X
Xchar **
XbitsToArgv(bitArray)
X char *bitArray;
X{
X char * absname;
X char * relname;
X static char **argv;
X struct idarg *idArgs;
X register char **av;
X register int i;
X#define ARGV1stPATH 3 /* available argv[] slots before first pathname */
X
X if (argv == NULL)
X argv = (char **)malloc(sizeof(char *) * (Idh.idh_pthc + ARGV1stPATH + 2));
X
X av = argv + ARGV1stPATH;
X for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X if (!BITTST(bitArray, i))
X continue;
X if (idArgs->ida_flags & IDA_BLANK) {
X printf("BOTCH: blank index!\n");
X abort();
X }
X if (!(idArgs->ida_flags & IDA_ADJUST)) {
X absname = spanPath(IdDir, idArgs->ida_arg);
X relname = relPath(PWDname, absname);
X idArgs->ida_arg = strsav(strlen(relname) > strlen(absname) ? absname : relname);
X idArgs->ida_flags |= IDA_ADJUST;
X }
X *av++ = idArgs->ida_arg;
X }
X *av = NULL;
X return (argv + ARGV1stPATH);
X}
X
X/* pathWildCard implements a simple pattern matcher that emulates the
X * shell wild card capability.
X *
X * * - any string of chars
X * ? - any char
X * [] - any char in set (if first char is !, any not in set)
X * \ - literal match next char
X */
Xint
XpathWildCard(re, fn)
X char *re;
X char *fn;
X{
X register int c;
X register int i;
X char set[256];
X int revset;
X
X while ((c = *re++) != '\0') {
X if (c == '*') {
X if (*re == '\0') return 1; /* match anything at end */
X while (*fn != '\0') {
X if (pathWildCard(re,fn)) return 1;
X ++fn;
X }
X return 0;
X } else if (c == '?') {
X if (*fn++ == '\0') return 0;
X } else if (c == '[') {
X c = *re++;
X bzero(set,256);
X if (c == '!') {
X revset=1;
X c = *re++;
X } else {
X revset=0;
X }
X while (c != ']') {
X if (c == '\\') c = *re++;
X set[c]=1;
X if ((*re == '-') && (*(re+1) != ']')) {
X re+=1;
X while (++c <= *re) set[c]=1;
X ++re;
X }
X c = *re++;
X }
X if (revset) for (i=1;i<256;++i) set[i] = ! set[i];
X if (! set[*fn++]) return 0;
X } else {
X if (c == '\\') c = *re++;
X if (c != *fn++) return 0;
X }
X }
X return(*fn == '\0');
X}
X
X/* matchPaths implements the pid tool. This matches the *names* of files
X * in the database against the input pattern rather than the *contents*
X * of the files.
X */
Xint
XmatchPaths(re, doit)
X char *re;
X void (*doit)();
X{
X char * absname;
X static char *bitArray;
X struct idarg *idArgs;
X register int i;
X char *reCompiled;
X int count=0;
X int matched;
X
X if (pathRegExp) {
X#ifdef REGEX
X if ((reCompiled = regcmp(re, 0)) == NULL) {
X fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
X return 0;
X }
X#endif
X#ifdef RE_EXEC
X if ((reCompiled = re_comp(re)) != NULL) {
X fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
X return 0;
X }
X#endif
X }
X
X if (bitArray == NULL) {
X bitArray = malloc(BitArraySize);
X }
X bzero(bitArray, BitArraySize);
X
X for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X if (idArgs->ida_flags & IDA_BLANK) continue;
X if (matchBase) {
X absname = strrchr(idArgs->ida_arg, '/');
X if (absname == NULL) {
X absname = idArgs->ida_arg;
X }
X } else {
X absname = spanPath(IdDir, idArgs->ida_arg);
X }
X if (pathRegExp) {
X#ifdef REGEX
X matched = (regex(reCompiled, absname) != NULL);
X#endif
X#ifdef RE_EXEC
X matched = (re_exec(absname));
X#endif
X } else {
X matched = pathWildCard(re, absname);
X }
X if (matched) {
X BITSET(bitArray, i);
X ++count;
X }
X }
X if (count)
X (*doit)(re, bitsToArgv(bitArray));
X return count;
X}
END_OF_FILE
if test 20703 -ne `wc -c <'lid.c'`; then
echo shar: \"'lid.c'\" unpacked with wrong size!
fi
# end of 'lid.c'
fi
echo shar: End of archive 11 \(of 11\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 11 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
======================================================================
domain: tahorsley at csd.harris.com USMail: Tom Horsley
uucp: ...!uunet!hcx1!tahorsley 511 Kingbird Circle
Delray Beach, FL 33444
+==== Censorship is the only form of Obscenity ======================+
| (Wait, I forgot government tobacco subsidies...) |
+====================================================================+
More information about the Alt.sources
mailing list