home *** CD-ROM | disk | FTP | other *** search
- static char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
- static char sccsid[] = "@(#)lid.c 1.4 86/11/06";
-
- #include <bool.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <signal.h>
- #include <errno.h>
- #include <radix.h>
- #include <id.h>
- #include <bitops.h>
- #include <extern.h>
-
- #ifdef REGEX
- extern char *regex();
- extern char *regcmp();
- #endif
- #ifdef RE_EXEC
- extern char *re_comp();
- extern int re_exec();
- #endif
-
- bool isMagic();
- char **bitsToArgv();
- char *fileRE();
- char *strcpos();
- int skipToArgv();
- int findAnchor();
- int findApropos();
- #if REGEX || RE_EXEC
- int findRegExp();
- #endif
- int matchPaths();
- int findNonUnique();
- int findNumber();
- int findPlain();
- int idCompare();
- long searchName();
- void editId();
- void grepId();
- void lookId();
-
- #ifdef USG
- #define TOLOWER(c) (isupper(c) ? _tolower(c) : (c))
- #else
- #define TOLOWER(c) (isupper(c) ? tolower(c) : (c))
- #endif
-
- /*
- * Sorry about all the globals, but it's really cleaner this way.
- */
- FILE *IdFILE;
- bool Merging;
- bool Radix;
- bool EchoOn = TRUE;
- bool CrunchOn = TRUE;
- bool pathRegExp = FALSE;
- bool matchBase = FALSE;
- char IdDir[BUFSIZ];
- long AnchorOffset;
- int BitArraySize;
- char PWDname[BUFSIZ];
- struct idhead Idh;
- struct idarg *IdArgs;
- int (*FindFunc)() = NULL;
- int Solo = 0;
- #define IGNORE_SOLO(buf) \
- ( \
- (Solo == '-' && !(ID_FLAGS(buf) & IDN_SOLO)) \
- || (Solo == '+' && (ID_FLAGS(buf) & IDN_SOLO)) \
- )
-
- char *MyName;
- static void
- usage()
- {
- fprintf(stderr, "Usage: %s [-f<file>] [-u<n>] [-r<dir>] [-mewdoxasknc] patterns...\n", MyName);
- exit(1);
- }
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *idFile = IDFILE;
- char *arg;
- long val;
- void (*doit)();
- bool forceMerge = FALSE;
- int uniqueLimit = 0;
- int useIDpath = TRUE;
- int usePWDpath = FALSE;
- int useRELpath = FALSE;
- char * RELpath;
- int op;
-
- MyName = basename(GETARG(argc, argv));
-
- while (argc) {
- arg = GETARG(argc, argv);
- switch (op = *arg++)
- {
- case '-':
- case '+':
- break;
- default:
- UNGETARG(argc, argv);
- goto argsdone;
- }
- while (*arg) switch (*arg++)
- {
- case 'f': idFile = arg; goto nextarg;
- case 'u': uniqueLimit = stoi(arg); goto nextarg;
- case 'm': forceMerge = TRUE; break;
- #if REGEX || RE_EXEC
- case 'e': FindFunc = findRegExp; pathRegExp = TRUE; break;
- #endif
- case 'w': FindFunc = findPlain; break;
- case 'd': Radix |= RADIX_DEC; break;
- case 'o': Radix |= RADIX_OCT; break;
- case 'x': Radix |= RADIX_HEX; break;
- case 'a': Radix |= RADIX_ALL; break;
- case 's': Solo = op; break;
- case 'k': CrunchOn = FALSE; break;
- case 'n': EchoOn = FALSE; break;
- case 'c': useIDpath = FALSE; usePWDpath = TRUE; break;
- case 'b': matchBase = TRUE; break;
- case 'r': useIDpath = FALSE; useRELpath = TRUE;
- RELpath = arg; goto nextarg;
- default:
- usage();
- }
- nextarg:;
- }
- argsdone:
-
- if (usePWDpath && useRELpath) {
- fprintf(stderr,"%s: please use only one of -c or -r\n",MyName);
- usage();
- }
- /* Look for the ID database up the tree */
- if ((idFile = LookUp(idFile)) == NULL) {
- filerr("open", idFile);
- exit(1);
- }
- /* Find out current directory to relate names to */
- if (kshgetwd(PWDname) == NULL) {
- fprintf(stderr,"%s: cannot determine current directory\n",MyName);
- exit(1);
- }
- strcat(PWDname,"/");
- /* Determine absolute path name that database files are relative to */
- if (useIDpath) {
- strcpy(IdDir, spanPath(PWDname, idFile));
- *(strrchr(IdDir, '/') + 1) = '\0';
- } else if (usePWDpath) {
- strcpy(IdDir, PWDname);
- } else {
- strcpy(IdDir, spanPath(PWDname, RELpath));
- strcat(IdDir, "/");
- }
- if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
- filerr("open", idFile);
- exit(1);
- }
- BitArraySize = (Idh.idh_pthc + 7) >> 3;
-
- switch (MyName[0])
- {
- case 'a':
- FindFunc = findApropos;
- /*FALLTHROUGH*/
- case 'l':
- doit = lookId;
- break;
- case 'g':
- doit = grepId;
- break;
- case 'e':
- doit = editId;
- break;
- case 'p':
- FindFunc = matchPaths;
- doit = lookId;
- break;
- default:
- MyName = "[algep]id";
- usage();
- }
-
- if (argc == 0) {
- UNGETARG(argc, argv);
- *argv = ".";
- }
-
- while (argc) {
- arg = GETARG(argc, argv);
- if (FindFunc)
- ;
- else if ((radix(arg)) && (val = stoi(arg)) >= 0)
- FindFunc = findNumber;
- #if REGEX || RE_EXEC
- else if (isMagic(arg))
- FindFunc = findRegExp;
- #endif
- else if (arg[0] == '^')
- FindFunc = findAnchor;
- else
- FindFunc = findPlain;
-
- if ((doit == lookId && !forceMerge)
- || (FindFunc == findNumber && bitCount(Radix) > 1 && val > 7))
- Merging = FALSE;
- else
- Merging = TRUE;
-
- if (uniqueLimit) {
- if (!findNonUnique(uniqueLimit, doit))
- fprintf(stderr, "All identifiers are unique within the first %d characters\n", uniqueLimit);
- exit(0);
- } else if (!(*FindFunc)(arg, doit)) {
- fprintf(stderr, "%s: not found\n", arg);
- continue;
- }
- }
- exit(0);
- }
-
- void
- lookId(name, argv)
- char *name;
- register char **argv;
- {
- register char *arg;
- register bool crunching = FALSE;
- register char *dir;
-
- if (EchoOn) printf("%-14s ", name);
- while (*argv) {
- arg = *argv++;
- if (*argv && CrunchOn && canCrunch(arg, *argv)) {
- if (crunching)
- printf(",%s", rootName(arg));
- else if ((dir = dirname(arg)) && dir[0] == '.' && dir[1] == '\0')
- printf("{%s", rootName(arg));
- else
- printf("%s/{%s", dir, rootName(arg));
- /*}}*/
- crunching = TRUE;
- } else {
- if (crunching) /*{*/
- printf(",%s}%s", rootName(arg), suffName(arg));
- else
- fputs(arg, stdout);
- crunching = FALSE;
- if (*argv)
- putchar(' ');
- }
- }
- putchar('\n');
- }
-
- void
- grepId(name, argv)
- char *name;
- char **argv;
- {
- FILE *gidFILE;
- char *gidName;
- char buf[BUFSIZ];
- char *delimit = "[^a-zA-Z0-9_]";
- char *re;
- char *reCompiled;
- int lineNumber;
-
- if (!Merging || (re = fileRE(name, delimit, delimit)) == NULL)
- re = NULL;
- #ifdef REGEX
- else if ((reCompiled = regcmp(re, 0)) == NULL) {
- fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
- return;
- }
- #endif
- #ifdef RE_EXEC
- else if ((reCompiled = re_comp(re)) != NULL) {
- fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
- return;
- }
- #endif
-
- buf[0] = ' '; /* sentry */
- while (*argv) {
- if ((gidFILE = fopen(gidName = *argv++, "r")) == NULL) {
- filerr("open", gidName);
- continue;
- }
- lineNumber = 0;
- while (fgets(&buf[1], sizeof(buf), gidFILE)) {
- lineNumber++;
- if (re) {
- #ifdef REGEX
- if (regex(reCompiled, buf) == NULL)
- #endif
- #ifdef RE_EXEC
- if (!re_exec(buf))
- #endif
- continue;
- } else if (!wordMatch(name, buf))
- continue;
- printf("%s:%d: %s", gidName, lineNumber, &buf[1]);
- }
- fclose(gidFILE);
- }
- }
-
- void
- editId(name, argv)
- char *name;
- char **argv;
- {
- char reBuf[BUFSIZ];
- char edArgBuf[BUFSIZ];
- char *re;
- int c;
- int skip;
- static char *editor, *eidArg, *eidRightDel, *eidLeftDel;
-
- if (editor == NULL && (editor = getenv("EDITOR")) == NULL) {
- char *ucb_vi = "/usr/ucb/vi";
- char *bin_vi = "/usr/bin/vi";
-
- if (access(ucb_vi, 01) == 0)
- editor = ucb_vi;
- else if (access(bin_vi, 01) == 0)
- editor = bin_vi;
- else
- editor = "/bin/ed"; /* YUCK! */
- if (editor == ucb_vi || editor == bin_vi) {
- eidArg = "+1;/%s/";
- eidLeftDel = "\\<";
- eidRightDel = "\\>";
- }
- }
- if (eidLeftDel == NULL) {
- eidArg = getenv("EIDARG");
- if ((eidLeftDel = getenv("EIDLDEL")) == NULL)
- eidLeftDel = "";
- if ((eidRightDel = getenv("EIDRDEL")) == NULL)
- eidRightDel = "";
- }
-
- lookId(name, argv);
- savetty();
- for (;;) {
- printf("Edit? [y1-9^S/nq] "); fflush(stdout);
- chartty();
- c = (getchar() & 0177);
- restoretty();
- switch (TOLOWER(c))
- {
- case '/': case ('s'&037):
- putchar('/');
- /*FALLTHROUGH*/
- if ((skip = skipToArgv(argv)) < 0)
- continue;
- argv += skip;
- goto editit;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- putchar(c);
- skip = c - '0';
- break;
- case 'y':
- putchar(c);
- /*FALLTHROUGH*/
- case '\n':
- case '\r':
- skip = 0;
- break;
- case 'q':
- putchar(c);
- putchar('\n');
- exit(0);
- case 'n':
- putchar(c);
- putchar('\n');
- return;
- default:
- putchar(c);
- putchar('\n');
- continue;
- }
-
- putchar('\n');
- while (skip--)
- if (*++argv == NULL)
- continue;
- break;
- }
- editit:
-
- if (!Merging || (re = fileRE(name, eidLeftDel, eidRightDel)) == NULL)
- sprintf(re = reBuf, "%s%s%s", eidLeftDel, name, eidRightDel);
-
- switch (fork())
- {
- case -1:
- fprintf(stderr, "%s: Cannot fork (%s)\n", MyName, uerror());
- exit(1);
- case 0:
- argv--;
- if (eidArg) {
- argv--;
- sprintf(edArgBuf, eidArg, re);
- argv[1] = edArgBuf;
- }
- argv[0] = editor;
- execv(editor, argv);
- filerr("exec", editor);
- default:
- {
- int (*oldint)() = signal(SIGINT, SIG_IGN);
- int (*oldquit)() = signal(SIGQUIT, SIG_IGN);
-
- while(wait(0) == -1 && errno == EINTR)
- /* loop */;
-
- (void) signal(SIGINT, oldint);
- (void) signal(SIGQUIT, oldquit);
- }
- break;
- }
- }
-
- int
- skipToArgv(argv)
- char **argv;
- {
- char pattern[BUFSIZ];
- int count;
-
- if (gets(pattern) == NULL)
- return -1;
-
- for (count = 0; *argv; count++, argv++)
- if (strcpos(*argv, pattern))
- return count;
- return -1;
- }
-
- int
- findPlain(arg, doit)
- char *arg;
- void (*doit)();
- {
- static char *buf, *bitArray;
- int size;
-
- if (searchName(arg) == 0)
- return 0;
- if (buf == NULL) {
- buf = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- if ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) == 0)
- return 0;
- size++;
- getsFF(&buf[size], IdFILE);
- if (IGNORE_SOLO(buf))
- return 0;
-
- vecToBits(bitArray, &buf[size], Idh.idh_vecc);
- (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
- return 1;
- }
-
- int
- findAnchor(arg, doit)
- register char *arg;
- void (*doit)();
- {
- static char *buf, *bitArray;
- int count, size;
- int len;
-
- if (searchName(++arg) == 0)
- return 0;
-
- if (buf == NULL) {
- buf = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- len = strlen(arg);
- count = 0;
- while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
- size++;
- getsFF(&buf[size], IdFILE);
- if (IGNORE_SOLO(buf))
- continue;
- if (!strnequ(arg, ID_STRING(buf), len))
- break;
- vecToBits(bitArray, &buf[size], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
- if (Merging && count)
- (*doit)(--arg, bitsToArgv(bitArray));
-
- return count;
- }
-
- #if REGEX || RE_EXEC
- int
- findRegExp(re, doit)
- char *re;
- void (*doit)();
- {
- static char *buf, *bitArray;
- int count, size;
- char *reCompiled;
-
- #ifdef REGEX
- if ((reCompiled = regcmp(re, 0)) == NULL) {
- fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
- return 0;
- }
- #endif
- #ifdef RE_EXEC
- if ((reCompiled = re_comp(re)) != NULL) {
- fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
- return 0;
- }
- #endif
- fseek(IdFILE, Idh.idh_namo, 0);
-
- if (buf == NULL) {
- buf = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- count = 0;
- while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
- size++;
- getsFF(&buf[size], IdFILE);
- if (IGNORE_SOLO(buf))
- continue;
- #ifdef REGEX
- if (regex(reCompiled, ID_STRING(buf)) == NULL)
- #endif
- #ifdef RE_EXEC
- if (!re_exec(ID_STRING(buf)))
- #endif
- continue;
- vecToBits(bitArray, &buf[size], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
- if (Merging && count)
- (*doit)(re, bitsToArgv(bitArray));
-
- return count;
- }
- #endif
-
- int
- findNumber(arg, doit)
- char *arg;
- void (*doit)();
- {
- static char *buf, *bitArray;
- int count, size;
- register int rdx = 0;
- register int val;
- register bool hitDigits = FALSE;
-
- if ((val = stoi(arg)) <= 7)
- rdx |= RADIX_ALL;
- else
- rdx = radix(arg);
- fseek(IdFILE, Idh.idh_namo, 0);
-
- if (buf == NULL) {
- buf = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- count = 0;
- while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
- size++;
- getsFF(&buf[size], IdFILE);
- if (hitDigits) {
- if (!isdigit(*ID_STRING(buf)))
- break;
- } else if (isdigit(*ID_STRING(buf)))
- hitDigits = TRUE;
-
- if (!((Radix ? Radix : rdx) & radix(ID_STRING(buf)))
- || stoi(ID_STRING(buf)) != val)
- continue;
- vecToBits(bitArray, &buf[size], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
- if (Merging && count)
- (*doit)(arg, bitsToArgv(bitArray));
-
- return count;
- }
-
- /*
- Find identifiers that are non-unique within
- the first `count' characters.
- */
- int
- findNonUnique(limit, doit)
- int limit;
- void (*doit)();
- {
- static char *buf1, *buf2, *bitArray;
- register char *old;
- register char *new;
- register int consecutive;
- char *cptmp;
- int itmp;
- int count, oldsize, newsize;
- char *name;
-
- if (limit <= 1)
- usage();
-
- fseek(IdFILE, Idh.idh_namo, 0);
-
- if (buf1 == NULL) {
- buf1 = malloc(Idh.idh_bsiz);
- buf2 = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- name = calloc(1, limit+2);
- name[0] = '^';
- old = buf1;
- *ID_STRING(new = buf2) = '\0';
- count = consecutive = 0;
- while ((oldsize = fgets0(old, Idh.idh_bsiz, IdFILE)) > 0) {
- oldsize++;
- getsFF(&old[oldsize], IdFILE);
- if (!(ID_FLAGS(old) & IDN_NAME))
- continue;
- cptmp = old; old = new; new = cptmp;
- itmp = oldsize; oldsize = newsize; newsize = itmp;
- if (!strnequ(ID_STRING(new), ID_STRING(old), limit)) {
- if (consecutive && Merging) {
- strncpy(&name[1], ID_STRING(old), limit);
- (*doit)(name, bitsToArgv(bitArray));
- }
- consecutive = 0;
- continue;
- }
- if (!consecutive++) {
- vecToBits(bitArray, &old[oldsize], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(old), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
- vecToBits(bitArray, &new[newsize], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(new), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
-
- return count;
- }
-
- int
- findApropos(arg, doit)
- char *arg;
- void (*doit)();
- {
- static char *buf, *bitArray;
- int count, size;
-
- fseek(IdFILE, Idh.idh_namo, 0);
-
- if (buf == NULL) {
- buf = malloc(Idh.idh_bsiz);
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- count = 0;
- while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
- size++;
- getsFF(&buf[size], IdFILE);
- if (IGNORE_SOLO(buf))
- continue;
- if (strcpos(ID_STRING(buf), arg) == NULL)
- continue;
- vecToBits(bitArray, &buf[size], Idh.idh_vecc);
- if (!Merging) {
- (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
- bzero(bitArray, BitArraySize);
- }
- count++;
- }
- if (Merging && count)
- (*doit)(arg, bitsToArgv(bitArray));
-
- return count;
- }
-
- /*
- if string `s2' occurs in `s1', return a pointer to the
- first match. Ignore differences in alphabetic case.
- */
- char *
- strcpos(s1, s2)
- char *s1;
- char *s2;
- {
- register char *s1p;
- register char *s2p;
- char *s1last;
-
- for (s1last = &s1[strlen(s1) - strlen(s2)]; s1 <= s1last; s1++)
- for (s1p = s1, s2p = s2; TOLOWER(*s1p) == TOLOWER(*s2p); s1p++)
- if (*++s2p == '\0')
- return s1;
- return NULL;
- }
-
- /*
- Convert the regular expression that we used to
- locate identifiers in the id database into one
- suitable for locating the identifiers in files.
- */
- char *
- fileRE(name0, leftDelimit, rightDelimit)
- char *name0;
- char *leftDelimit;
- char *rightDelimit;
- {
- static char reBuf[BUFSIZ];
- register char *name = name0;
-
- if (FindFunc == findNumber && Merging) {
- sprintf(reBuf, "%s0*[Xx]*0*%d[Ll]*%s", leftDelimit, stoi(name), rightDelimit);
- return reBuf;
- }
-
- if (!isMagic(name) && name[0] != '^')
- return NULL;
-
- if (name[0] == '^')
- name0++;
- else
- leftDelimit = "";
- while (*++name)
- ;
- if (*--name == '$')
- *name = '\0';
- else
- rightDelimit = "";
-
- sprintf(reBuf, "%s%s%s", leftDelimit, name0, rightDelimit);
- return reBuf;
- }
-
- long
- searchName(name)
- char *name;
- {
- long offset;
-
- AnchorOffset = 0;
- offset = (long)bsearch(name, (char *)(Idh.idh_namo-1), Idh.idh_endo-(Idh.idh_namo-1), 1, idCompare);
- if (offset == 0)
- offset = AnchorOffset;
- if (offset == 0)
- return 0;
- fseek(IdFILE, offset, 0);
- skipFF(IdFILE);
- return ftell(IdFILE);
- }
-
- int
- idCompare(key, offset)
- register char *key;
- long offset;
- {
- register int c;
-
- fseek(IdFILE, offset, 0);
- skipFF(IdFILE);
- getc(IdFILE);
-
- while (*key == (c = getc(IdFILE)))
- if (*key++ == '\0')
- return 0;
- if (*key == '\0' && FindFunc == findAnchor)
- AnchorOffset = offset;
-
- return *key - c;
- }
-
- /*
- Are there any magic Regular Expression meta-characters in name??
- */
- bool
- isMagic(name)
- register char *name;
- {
- char *magichar = "[]{}().*+^$";
- int backslash = 0;
-
- if (*name == '^')
- name++;
- while (*name) {
- if (*name == '\\')
- name++, backslash++;
- else if (strchr(magichar, *name))
- return TRUE;
- name++;
- }
- if (backslash)
- while (*name) {
- if (*name == '\\')
- strcpy(name, name+1);
- name++;
- }
- return FALSE;
- }
-
- char **
- bitsToArgv(bitArray)
- char *bitArray;
- {
- char * absname;
- char * relname;
- static char **argv;
- struct idarg *idArgs;
- register char **av;
- register int i;
- #define ARGV1stPATH 3 /* available argv[] slots before first pathname */
-
- if (argv == NULL)
- argv = (char **)malloc(sizeof(char *) * (Idh.idh_pthc + ARGV1stPATH + 2));
-
- av = argv + ARGV1stPATH;
- for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
- if (!BITTST(bitArray, i))
- continue;
- if (idArgs->ida_flags & IDA_BLANK) {
- printf("BOTCH: blank index!\n");
- abort();
- }
- if (!(idArgs->ida_flags & IDA_ADJUST)) {
- absname = spanPath(IdDir, idArgs->ida_arg);
- relname = relPath(PWDname, absname);
- idArgs->ida_arg = strsav(strlen(relname) > strlen(absname) ? absname : relname);
- idArgs->ida_flags |= IDA_ADJUST;
- }
- *av++ = idArgs->ida_arg;
- }
- *av = NULL;
- return (argv + ARGV1stPATH);
- }
-
- /* pathWildCard implements a simple pattern matcher that emulates the
- * shell wild card capability.
- *
- * * - any string of chars
- * ? - any char
- * [] - any char in set (if first char is !, any not in set)
- * \ - literal match next char
- */
- int
- pathWildCard(re, fn)
- char *re;
- char *fn;
- {
- register int c;
- register int i;
- char set[256];
- int revset;
-
- while ((c = *re++) != '\0') {
- if (c == '*') {
- if (*re == '\0') return 1; /* match anything at end */
- while (*fn != '\0') {
- if (pathWildCard(re,fn)) return 1;
- ++fn;
- }
- return 0;
- } else if (c == '?') {
- if (*fn++ == '\0') return 0;
- } else if (c == '[') {
- c = *re++;
- bzero(set,256);
- if (c == '!') {
- revset=1;
- c = *re++;
- } else {
- revset=0;
- }
- while (c != ']') {
- if (c == '\\') c = *re++;
- set[c]=1;
- if ((*re == '-') && (*(re+1) != ']')) {
- re+=1;
- while (++c <= *re) set[c]=1;
- ++re;
- }
- c = *re++;
- }
- if (revset) for (i=1;i<256;++i) set[i] = ! set[i];
- if (! set[*fn++]) return 0;
- } else {
- if (c == '\\') c = *re++;
- if (c != *fn++) return 0;
- }
- }
- return(*fn == '\0');
- }
-
- /* matchPaths implements the pid tool. This matches the *names* of files
- * in the database against the input pattern rather than the *contents*
- * of the files.
- */
- int
- matchPaths(re, doit)
- char *re;
- void (*doit)();
- {
- char * absname;
- static char *bitArray;
- struct idarg *idArgs;
- register int i;
- char *reCompiled;
- int count=0;
- int matched;
-
- if (pathRegExp) {
- #ifdef REGEX
- if ((reCompiled = regcmp(re, 0)) == NULL) {
- fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
- return 0;
- }
- #endif
- #ifdef RE_EXEC
- if ((reCompiled = re_comp(re)) != NULL) {
- fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
- return 0;
- }
- #endif
- }
-
- if (bitArray == NULL) {
- bitArray = malloc(BitArraySize);
- }
- bzero(bitArray, BitArraySize);
-
- for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
- if (idArgs->ida_flags & IDA_BLANK) continue;
- if (matchBase) {
- absname = strrchr(idArgs->ida_arg, '/');
- if (absname == NULL) {
- absname = idArgs->ida_arg;
- }
- } else {
- absname = spanPath(IdDir, idArgs->ida_arg);
- }
- if (pathRegExp) {
- #ifdef REGEX
- matched = (regex(reCompiled, absname) != NULL);
- #endif
- #ifdef RE_EXEC
- matched = (re_exec(absname));
- #endif
- } else {
- matched = pathWildCard(re, absname);
- }
- if (matched) {
- BITSET(bitArray, i);
- ++count;
- }
- }
- if (count)
- (*doit)(re, bitsToArgv(bitArray));
- return count;
- }
-