rsalz@bbn.com (Rich Salz) (06/06/91)
Submitted-by: Tom Horsley <tom@hcx2.ssd.csd.harris.com> Posting-number: Volume 24, Issue 94 Archive-name: mkid2/part06 #! /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 6 (of 7)." # Contents: lid.c # Wrapped by tom@hcx2 on Tue Feb 26 10:03:07 1991 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'\" \(20773 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#ifndef CRUNCH_DEFAULT X#define CRUNCH_DEFAULT TRUE 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 = CRUNCH_DEFAULT; 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 'g': CrunchOn = TRUE; 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 continue; 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 20773 -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 6 \(of 7\). cp /dev/null ark6isdone 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.