diff options
author | Hidetoshi Shimokawa <simokawa@FreeBSD.org> | 1999-01-18 06:59:18 +0000 |
---|---|---|
committer | Hidetoshi Shimokawa <simokawa@FreeBSD.org> | 1999-01-18 06:59:18 +0000 |
commit | 3ba3e2cc4b63fa16707f51e735e751e62dd9526e (patch) | |
tree | 2d073c94248fff7dcaa8a3b1356933e1dcd784db /contrib/global/lib/find.c | |
parent | 0823b5bf088ea8520ea23a0c424e4ecab62491d5 (diff) |
Notes
Diffstat (limited to 'contrib/global/lib/find.c')
-rw-r--r-- | contrib/global/lib/find.c | 408 |
1 files changed, 344 insertions, 64 deletions
diff --git a/contrib/global/lib/find.c b/contrib/global/lib/find.c index 6203e008a6f5..4682beec1d6d 100644 --- a/contrib/global/lib/find.c +++ b/contrib/global/lib/find.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved. + * Copyright (c) 1996, 1997, 1998 Shigio Yamaguchi. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,114 +28,159 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * find.c 20-Oct-97 + * find.c 1-May-98 * */ +/* + * USEFIND use find(1) to traverse directory tree. + * Otherwise, use dirent(3) library. + */ +#define USEFIND + +#include <sys/param.h> + +#include <assert.h> +#include <ctype.h> +#ifndef USEFIND +#include <dirent.h> +#ifndef BSD4_4 +#include <sys/stat.h> +#endif +#endif #include <stdio.h> -#include <sys/types.h> +#include <stdlib.h> +#include <strings.h> #include <regex.h> -#include <sys/param.h> -#include "gparam.h" -#include "find.h" + +#include "conf.h" #include "die.h" +#include "find.h" +#include "gparam.h" #include "locatestring.h" +#include "makepath.h" +#include "strbuf.h" /* * usage of findxxx() * - * findopen(); + * findopen(db); * while (path = findread(&length)) { * ... * } * findclose(); * */ -static char *skippath[] = { - "y.tab.c", - "y.tab.h", - "SCCS/", - "RCS/", -}; -static char *ext[] = { - "c", - "h", - "y", - "s", - "S", -}; -static char findcom[MAXCOMLINE+1]; static regex_t skip_area; -static regex_t *skip; -static FILE *ip; +static regex_t *skip = &skip_area; static int opened; -int -issource(path) -char *path; +static void trim __P((char *)); + +/* + * trim: remove blanks and '\'. + */ +static void +trim(s) +char *s; { char *p; - if (!(p = locatestring(path, ".", 2))) - return 0; - ++p; - if (sizeof(ext) != 0) { - int i, lim = sizeof(ext)/sizeof(char *); - for (i = 0; i < lim; i++) - if (*ext[i] == *p && !strcmp(ext[i], p)) - return 1; + for (p = s; *s; s++) { + if (isspace(*s)) + continue; + if (*s == '\\' && *(s + 1)) + s++; + *p++ = *s; } - return 0; + *p = 0; } +#ifdef USEFIND +/*----------------------------------------------------------------------*/ +/* find command version */ +/*----------------------------------------------------------------------*/ +static FILE *ip; void -findopen(void) +findopen() { - char edit[512], *p, *q; - int i, lim; + char *findcom, *p, *q; + STRBUF *sb; + char *sufflist = NULL; + char *skiplist = NULL; - if (opened) - die("nested call to findopen."); + assert(opened == 0); opened = 1; - p = findcom; - strcpy(p, "find . \\( -type f -o -type l \\) \\("); - p += strlen(p); - lim = sizeof(ext)/sizeof(char *); - for (i = 0; i < lim; i++) { - sprintf(p, " -name '*.%s'%s", ext[i], (i + 1 < lim) ? " -o" : ""); - p += strlen(p); + + sb = stropen(); + if (!getconfs("suffixes", sb)) + die("cannot get suffixes data."); + sufflist = strdup(strvalue(sb)); + if (!sufflist) + die("short of memory."); + trim(sufflist); + strstart(sb); + if (getconfs("skip", sb)) { + skiplist = strdup(strvalue(sb)); + if (!skiplist) + die("short of memory."); + trim(skiplist); + } + + strstart(sb); + strputs(sb, "find . \\( -type f -o -type l \\) \\("); + for (p = sufflist; p; ) { + char *suff = p; + if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL) + *p++ = 0; + strputs(sb, " -name '*."); + strputs(sb, suff); + strputs(sb, "'"); + if (p) + strputs(sb, " -o"); } - sprintf(p, " \\) -print"); - if (sizeof(skippath) != 0) { - int i, lim = sizeof(skippath)/sizeof(char *); + strputs(sb, " \\) -print"); + findcom = strvalue(sb); + + if (skiplist) { + char *reg; + STRBUF *sbb = stropen(); /* * construct regular expression. */ - p = edit; - *p++ = '('; - for (i = 0; i < lim; i++) { - *p++ = '/'; - for (q = skippath[i]; *q; q++) { + strputc(sbb, '('); /* ) */ + for (p = skiplist; p; ) { + char *skipf = p; + if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL) + *p++ = 0; + strputc(sbb, '/'); + for (q = skipf; *q; q++) { if (*q == '.') - *p++ = '\\'; - *p++ = *q; + strputc(sbb, '\\'); + strputc(sbb, *q); } if (*(q - 1) != '/') - *p++ = '$'; - *p++ = '|'; + strputc(sbb, '$'); + if (p) + strputc(sbb, '|'); } - *(p - 1) = ')'; - *p = 0; + strputc(sbb, ')'); + reg = strvalue(sbb); /* * compile regular expression. */ - skip = &skip_area; - if (regcomp(skip, edit, REG_EXTENDED|REG_NEWLINE) != 0) + if (regcomp(skip, reg, REG_EXTENDED|REG_NEWLINE) != 0) die("cannot compile regular expression."); + strclose(sbb); } else { skip = (regex_t *)0; } if (!(ip = popen(findcom, "r"))) die("cannot execute find."); + strclose(sb); + if (sufflist) + free(sufflist); + if (skiplist) + free(skiplist); } char * findread(length) @@ -144,8 +189,12 @@ int *length; static char path[MAXPATHLEN+1]; char *p; + assert(opened == 1); while (fgets(path, MAXPATHLEN, ip)) { if (!skip || regexec(skip, path, 0, 0, 0) != 0) { + /* + * chop(path) + */ p = path + strlen(path) - 1; if (*p != '\n') die("output of find(1) is wrong (findread)."); @@ -155,11 +204,242 @@ int *length; return path; } } - return (char *)0; + return NULL; } void findclose(void) { + assert(opened == 1); pclose(ip); opened = 0; } +#else /* USEFIND */ +/*----------------------------------------------------------------------*/ +/* dirent version findxxx() */ +/*----------------------------------------------------------------------*/ +#define STACKSIZE 50 +static char dir[MAXPATHLEN+1]; /* directory path */ +static struct { + STRBUF *sb; + char *dirp, *start, *end, *p; +} stack[STACKSIZE], *topp, *curp; /* stack */ + +static regex_t suff_area; +static regex_t *suff = &suff_area; + +static int +getdirs(dir, sb) +char *dir; +STRBUF *sb; +{ + DIR *dirp; + struct dirent *dp; +#ifndef BSD4_4 + struct stat st; +#endif + + if ((dirp = opendir(dir)) == NULL) + return -1; + while ((dp = readdir(dirp)) != NULL) { +#ifdef BSD4_4 + if (dp->d_namlen == 1 && dp->d_name[0] == '.') + continue; + if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') + continue; + if (dp->d_type == DT_DIR) + strputc(sb, 'd'); + else if (dp->d_type == DT_REG) + strputc(sb, 'f'); + else if (dp->d_type == DT_LNK) + strputc(sb, 'l'); + else + strputc(sb, ' '); + strnputs(sb, dp->d_name, (int)dp->d_namlen); +#else + if (stat(path, &st) < 0) { + fprintf(stderr, "cannot stat '%s'. (Ignored)\n", path); + continue; + } + if (S_ISDIR(st.st_mode)) + strputc(sb, 'd'); + else if (S_ISREG(st.st_mode)) + strputc(sb, 'f'); + else if (S_ISLNK(st.st_mode)) + strputc(sb, 'l'); + else + strputc(sb, ' '); + strputs(sb, dp->d_name); +#endif /* BSD4_4 */ + strputc(sb, '\0'); + } + (void)closedir(dirp); + return 0; +} +void +findopen() +{ + STRBUF *sb = stropen(); + char *sufflist = NULL; + char *skiplist = NULL; + + assert(opened == 0); + opened = 1; + + /* + * setup stack. + */ + curp = &stack[0]; + topp = curp + STACKSIZE; + strcpy(dir, "."); + + curp->dirp = dir + strlen(dir); + curp->sb = stropen(); + if (getdirs(dir, curp->sb) < 0) + die("cannot open '.' directory."); + curp->start = curp->p = strvalue(curp->sb); + curp->end = curp->start + strbuflen(curp->sb); + + /* + * preparing regular expression. + */ + strstart(sb); + if (!getconfs("suffixes", sb)) + die("cannot get suffixes data."); + sufflist = strdup(strvalue(sb)); + if (!sufflist) + die("short of memory."); + trim(sufflist); + strstart(sb); + if (getconfs("skip", sb)) { + skiplist = strdup(strvalue(sb)); + if (!skiplist) + die("short of memory."); + trim(skiplist); + } + { + char *p; + + strstart(sb); + strputc(sb, '('); /* ) */ + for (p = sufflist; p; ) { + char *suffp = p; + if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL) + *p++ = 0; + strputs(sb, "\\."); + strputs(sb, suffp); + strputc(sb, '$'); + if (p) + strputc(sb, '|'); + } + strputc(sb, ')'); + /* + * compile regular expression. + */ + if (regcomp(suff, strvalue(sb), REG_EXTENDED) != 0) + die("cannot compile regular expression."); + } + if (skiplist) { + char *p, *q; + /* + * construct regular expression. + */ + strstart(sb); + strputc(sb, '('); /* ) */ + for (p = skiplist; p; ) { + char *skipf = p; + if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL) + *p++ = 0; + strputc(sb, '/'); + for (q = skipf; *q; q++) { + if (*q == '.') + strputc(sb, '\\'); + strputc(sb, *q); + } + if (*(q - 1) != '/') + strputc(sb, '$'); + if (p) + strputc(sb, '|'); + } + strputc(sb, ')'); + /* + * compile regular expression. + */ + if (regcomp(skip, strvalue(sb), REG_EXTENDED) != 0) + die("cannot compile regular expression."); + } else { + skip = (regex_t *)0; + } + strclose(sb); + if (sufflist) + free(sufflist); + if (skiplist) + free(skiplist); +} +char * +findread(length) +int *length; +{ + static char val[MAXPATHLEN+1]; + + for (;;) { + while (curp->p < curp->end) { + char type = *(curp->p); + char *unit = curp->p + 1; + + curp->p += strlen(curp->p) + 1; + if (type == 'f' || type == 'l') { + char *path = makepath(dir, unit); + if (regexec(suff, path, 0, 0, 0) != 0) + continue; + if (skip && regexec(skip, path, 0, 0, 0) == 0) + continue; + strcpy(val, path); + return val; + } + if (type == 'd') { + STRBUF *sb = stropen(); + char *dirp = curp->dirp; + + strcat(dirp, "/"); + strcat(dirp, unit); + if (getdirs(dir, sb) < 0) { + fprintf(stderr, "cannot open directory '%s'. (Ignored)\n", dir); + strclose(sb); + *(curp->dirp) = 0; + continue; + } + /* + * Push stack. + */ + if (++curp >= topp) + die("directory stack over flow."); + curp->dirp = dirp + strlen(dirp); + curp->sb = sb; + curp->start = curp->p = strvalue(sb); + curp->end = curp->start + strbuflen(sb); + } + } + strclose(curp->sb); + curp->sb = NULL; + if (curp == &stack[0]) + break; + /* + * Pop stack. + */ + curp--; + *(curp->dirp) = 0; + } + return NULL; +} +void +findclose(void) +{ + assert(opened == 1); + for (curp = &stack[0]; curp < topp; curp++) + if (curp->sb != NULL) + strclose(curp->sb); + else + break; + opened = 0; +} +#endif /* !USEFIND */ |