diff options
author | mp <mp@FreeBSD.org> | 2007-03-11 22:33:41 +0000 |
---|---|---|
committer | mp <mp@FreeBSD.org> | 2007-03-11 22:33:41 +0000 |
commit | a40980339b13e3b506c2317b5b4864127039eb2c (patch) | |
tree | 34aefea92d30b614247ef1f2671f2362f4761785 /contrib/tcsh/glob.c | |
parent | 32837fb336d4709f0a121130a3a78f29be0db5ed (diff) | |
download | FreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.zip FreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.tar.gz |
Import of tcsh-6.15.00
Diffstat (limited to 'contrib/tcsh/glob.c')
-rw-r--r-- | contrib/tcsh/glob.c | 360 |
1 files changed, 140 insertions, 220 deletions
diff --git a/contrib/tcsh/glob.c b/contrib/tcsh/glob.c index b56e220..844ee36 100644 --- a/contrib/tcsh/glob.c +++ b/contrib/tcsh/glob.c @@ -63,7 +63,6 @@ static char sccsid[] = "@(#)glob.c 5.12 (Berkeley) 6/24/91"; #undef QUOTE #undef TILDE #undef META -#undef CHAR #undef ismeta #undef Strchr @@ -81,23 +80,22 @@ static char sccsid[] = "@(#)glob.c 5.12 (Berkeley) 6/24/91"; typedef unsigned short Char; -static int glob1 __P((Char *, glob_t *, int)); -static int glob2 __P((Char *, Char *, Char *, glob_t *, int)); -static int glob3 __P((Char *, Char *, Char *, Char *, - glob_t *, int)); -static int globextend __P((Char *, glob_t *)); -static int match __P((Char *, Char *, Char *, int)); -#ifndef __clipper__ -static int compare __P((const ptr_t, const ptr_t)); -#endif -static DIR *Opendir __P((Char *)); +static int glob1 (Char *, glob_t *, int); +static int glob2 (struct strbuf *, const Char *, glob_t *, int); +static int glob3 (struct strbuf *, const Char *, const Char *, + glob_t *, int); +static void globextend (const char *, glob_t *); +static int match (const char *, const Char *, const Char *, + int); +static int compare (const void *, const void *); +static DIR *Opendir (const char *); #ifdef S_IFLNK -static int Lstat __P((Char *, struct stat *)); +static int Lstat (const char *, struct stat *); #endif -static int Stat __P((Char *, struct stat *sb)); -static Char *Strchr __P((Char *, int)); +static int Stat (const char *, struct stat *sb); +static Char *Strchr (Char *, int); #ifdef DEBUG -static void qprintf __P((Char *)); +static void qprintf (const Char *); #endif #define DOLLAR '$' @@ -120,7 +118,7 @@ static void qprintf __P((Char *)); #define M_MASK 0xffff #define M_ASCII 0x00ff -#define CHAR(c) ((c)&M_ASCII) +#define LCHAR(c) ((c)&M_ASCII) #define META(c) ((c)|M_META) #define M_ALL META('*') #define M_END META(']') @@ -131,19 +129,11 @@ static void qprintf __P((Char *)); #define M_SET META('[') #define ismeta(c) (((c)&M_META) != 0) -#ifndef BUFSIZE -#define GLOBBUFLEN MAXPATHLEN -#else -#define GLOBBUFLEN BUFSIZE -#endif - int -globcharcoll(c1, c2, cs) - NLSChar c1, c2; - int cs; +globcharcoll(__Char c1, __Char c2, int cs) { -#if defined(NLS) && defined(LC_COLLATE) && !defined(NOSTRCOLL) -# if defined(SHORT_STRINGS) +#if defined(NLS) && defined(LC_COLLATE) && defined(HAVE_STRCOLL) +# if defined(WIDE_STRINGS) wchar_t s1[2], s2[2]; if (c1 == c2) @@ -163,7 +153,7 @@ globcharcoll(c1, c2, cs) s2[0] = c2; s1[1] = s2[1] = '\0'; return wcscoll(s1, s2); -# else /* not SHORT_STRINGS */ +# else /* not WIDE_STRINGS */ char s1[2], s2[2]; if (c1 == c2) @@ -199,85 +189,56 @@ globcharcoll(c1, c2, cs) */ static DIR * -Opendir(str) - Char *str; +Opendir(const char *str) { - char buf[GLOBBUFLEN]; - char *dc = buf; #if defined(hpux) || defined(__hpux) struct stat st; #endif if (!*str) return (opendir(".")); - while ((*dc++ = *str++) != '\0') - continue; #if defined(hpux) || defined(__hpux) /* * Opendir on some device files hangs, so avoid it */ - if (stat(buf, &st) == -1 || !S_ISDIR(st.st_mode)) + if (stat(str, &st) == -1 || !S_ISDIR(st.st_mode)) return NULL; #endif - return (opendir(buf)); + return opendir(str); } #ifdef S_IFLNK static int -Lstat(fn, sb) - Char *fn; - struct stat *sb; +Lstat(const char *fn, struct stat *sb) { - char buf[GLOBBUFLEN]; - char *dc = buf; + int st; - while ((*dc++ = *fn++) != '\0') - continue; + st = lstat(fn, sb); # ifdef NAMEI_BUG - { - int st; - - st = lstat(buf, sb); - if (*buf) - dc--; - return (*--dc == '/' && !S_ISDIR(sb->st_mode) ? -1 : st); - } -# else - return (lstat(buf, sb)); + if (*fn != 0 && strend(fn)[-1] == '/' && !S_ISDIR(sb->st_mode)) + st = -1; # endif /* NAMEI_BUG */ + return st; } #else #define Lstat Stat #endif /* S_IFLNK */ static int -Stat(fn, sb) - Char *fn; - struct stat *sb; +Stat(const char *fn, struct stat *sb) { - char buf[GLOBBUFLEN]; - char *dc = buf; + int st; - while ((*dc++ = *fn++) != '\0') - continue; + st = stat(fn, sb); #ifdef NAMEI_BUG - { - int st; - - st = stat(buf, sb); - if (*buf) - dc--; - return (*--dc == '/' && !S_ISDIR(sb->st_mode) ? -1 : st); - } -#else - return (stat(buf, sb)); + if (*fn != 0 && strend(fn)[-1] == '/' && !S_ISDIR(sb->st_mode)) + st = -1; #endif /* NAMEI_BUG */ + return st; } static Char * -Strchr(str, ch) - Char *str; - int ch; +Strchr(Char *str, int ch) { do if (*str == ch) @@ -288,10 +249,9 @@ Strchr(str, ch) #ifdef DEBUG static void -qprintf(s) -Char *s; +qprintf(const Char *s) { - Char *p; + const Char *p; for (p = s; *p; p++) printf("%c", *p & 0xff); @@ -306,16 +266,13 @@ Char *s; #endif /* DEBUG */ static int -compare(p, q) - const ptr_t p, q; +compare(const void *p, const void *q) { -#if defined(NLS) && !defined(NOSTRCOLL) - errno = 0; /* strcoll sets errno, another brain-damage */ - - return (strcoll(*(char **) p, *(char **) q)); +#if defined(NLS) && defined(HAVE_STRCOLL) + return (strcoll(*(char *const *) p, *(char *const *) q)); #else - return (strcmp(*(char **) p, *(char **) q)); -#endif /* NLS && !NOSTRCOLL */ + return (strcmp(*(char *const *) p, *(char *const *) q)); +#endif /* NLS && HAVE_STRCOLL */ } /* @@ -326,22 +283,14 @@ compare(p, q) * to find no matches. */ int -glob(pattern, flags, errfunc, pglob) - const char *pattern; - int flags; - int (*errfunc) __P((const char *, int)); - glob_t *pglob; +glob(const char *pattern, int flags, int (*errfunc) (const char *, int), + glob_t *pglob) { int err, oldpathc; - Char *bufnext, *bufend, *compilebuf, m_not; - const unsigned char *compilepat, *patnext; + Char *bufnext, m_not; + const unsigned char *patnext; int c, not; - Char *qpatnext; -#ifdef WIDE_STRINGS - Char patbuf[GLOBBUFLEN + MB_LEN_MAX + 1]; -#else - Char patbuf[GLOBBUFLEN + 1]; -#endif + Char *qpatnext, *patbuf; int no_match; patnext = (const unsigned char *) pattern; @@ -365,10 +314,8 @@ glob(pattern, flags, errfunc, pglob) m_not = M_NOT; } + patbuf = xmalloc((strlen(pattern) + 1) * sizeof(*patbuf)); bufnext = patbuf; - bufend = bufnext + GLOBBUFLEN; - compilebuf = bufnext; - compilepat = patnext; no_match = *patnext == not; if (no_match) @@ -376,7 +323,7 @@ glob(pattern, flags, errfunc, pglob) if (flags & GLOB_QUOTE) { /* Protect the quoted characters */ - while (bufnext < bufend && (c = *patnext++) != EOS) { + while ((c = *patnext++) != EOS) { #ifdef WIDE_STRINGS int len; @@ -400,14 +347,13 @@ glob(pattern, flags, errfunc, pglob) *bufnext++ = (Char) c; } } - else - while (bufnext < bufend && (c = *patnext++) != EOS) + else + while ((c = *patnext++) != EOS) *bufnext++ = (Char) c; *bufnext = EOS; bufnext = patbuf; qpatnext = patbuf; - /* we don't need to check for buffer overflow any more */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: @@ -427,11 +373,11 @@ glob(pattern, flags, errfunc, pglob) *bufnext++ = m_not; c = *qpatnext++; do { - *bufnext++ = CHAR(c); + *bufnext++ = LCHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; - *bufnext++ = CHAR(c); + *bufnext++ = LCHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); @@ -450,7 +396,7 @@ glob(pattern, flags, errfunc, pglob) *bufnext++ = M_ALL; break; default: - *bufnext++ = CHAR(c); + *bufnext++ = LCHAR(c); break; } } @@ -459,8 +405,10 @@ glob(pattern, flags, errfunc, pglob) qprintf(patbuf); #endif - if ((err = glob1(patbuf, pglob, no_match)) != 0) + if ((err = glob1(patbuf, pglob, no_match)) != 0) { + xfree(patbuf); return (err); + } /* * If there was no match we are going to append the pattern @@ -471,50 +419,51 @@ glob(pattern, flags, errfunc, pglob) if (pglob->gl_pathc == oldpathc && ((flags & GLOB_NOCHECK) || ((flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) { - if (!(flags & GLOB_QUOTE)) { - Char *dp = compilebuf; - const unsigned char *sp = compilepat; - - while ((*dp++ = *sp++) != '\0') - continue; - } + if (!(flags & GLOB_QUOTE)) + globextend(pattern, pglob); else { - /* - * copy pattern, interpreting quotes; this is slightly different - * than the interpretation of quotes above -- which should prevail? - */ - while (*compilepat != EOS) { - if (*compilepat == QUOTE) { - if (*++compilepat == EOS) - --compilepat; + char *copy, *dest; + const char *src; + + /* copy pattern, interpreting quotes */ + copy = xmalloc(strlen(pattern) + 1); + dest = copy; + src = pattern; + while (*src != EOS) { + if (*src == QUOTE) { + if (*++src == EOS) + --src; } - *compilebuf++ = (unsigned char) *compilepat++; + *dest++ = *src++; } - *compilebuf = EOS; + *dest = EOS; + globextend(copy, pglob); + xfree(copy); } - return (globextend(patbuf, pglob)); + xfree(patbuf); + return 0; } else if (!(flags & GLOB_NOSORT) && (pglob->gl_pathc != oldpathc)) - qsort((char *) (pglob->gl_pathv + pglob->gl_offs + oldpathc), - pglob->gl_pathc - oldpathc, sizeof(char *), - (int (*) __P((const void *, const void *))) compare); + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + xfree(patbuf); return (0); } static int -glob1(pattern, pglob, no_match) - Char *pattern; - glob_t *pglob; - int no_match; +glob1(Char *pattern, glob_t *pglob, int no_match) { - Char pathbuf[GLOBBUFLEN + 1]; + struct strbuf pathbuf = strbuf_INIT; + int err; /* * a null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return (0); - return (glob2(pathbuf, pathbuf, pattern, pglob, no_match)); + err = glob2(&pathbuf, pattern, pglob, no_match); + xfree(pathbuf.s); + return err; } /* @@ -523,14 +472,12 @@ glob1(pattern, pglob, no_match) * more meta characters. */ static int -glob2(pathbuf, pathend, pattern, pglob, no_match) - Char *pathbuf, *pathend, *pattern; - glob_t *pglob; - int no_match; +glob2(struct strbuf *pathbuf, const Char *pattern, glob_t *pglob, int no_match) { struct stat sbuf; int anymeta; - Char *p, *q; + const Char *p; + size_t orig_len; /* * loop over pattern segments until end of pattern or until segment with @@ -539,69 +486,67 @@ glob2(pathbuf, pathend, pattern, pglob, no_match) anymeta = 0; for (;;) { if (*pattern == EOS) { /* end of pattern? */ - *pathend = EOS; + strbuf_terminate(pathbuf); - if (Lstat(pathbuf, &sbuf)) + if (Lstat(pathbuf->s, &sbuf)) return (0); if (((pglob->gl_flags & GLOB_MARK) && - pathend[-1] != SEP) && + pathbuf->s[pathbuf->len - 1] != SEP) && (S_ISDIR(sbuf.st_mode) #ifdef S_IFLNK || (S_ISLNK(sbuf.st_mode) && - (Stat(pathbuf, &sbuf) == 0) && + (Stat(pathbuf->s, &sbuf) == 0) && S_ISDIR(sbuf.st_mode)) #endif )) { - *pathend++ = SEP; - *pathend = EOS; + strbuf_append1(pathbuf, SEP); + strbuf_terminate(pathbuf); } ++pglob->gl_matchc; - return (globextend(pathbuf, pglob)); + globextend(pathbuf->s, pglob); + return 0; } - /* find end of next segment, copy tentatively to pathend */ - q = pathend; + /* find end of next segment, tentatively copy to pathbuf */ p = pattern; + orig_len = pathbuf->len; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; - *q++ = *p++; + strbuf_append1(pathbuf, *p++); } if (!anymeta) { /* no expansion, do next segment */ - pathend = q; pattern = p; while (*pattern == SEP) - *pathend++ = *pattern++; + strbuf_append1(pathbuf, *pattern++); + } + else { /* need expansion, recurse */ + pathbuf->len = orig_len; + return (glob3(pathbuf, pattern, p, pglob, no_match)); } - else /* need expansion, recurse */ - return (glob3(pathbuf, pathend, pattern, p, pglob, no_match)); } /* NOTREACHED */ } static int -glob3(pathbuf, pathend, pattern, restpattern, pglob, no_match) - Char *pathbuf, *pathend, *pattern, *restpattern; - glob_t *pglob; - int no_match; +glob3(struct strbuf *pathbuf, const Char *pattern, const Char *restpattern, + glob_t *pglob, int no_match) { DIR *dirp; struct dirent *dp; int err; Char m_not = (pglob->gl_flags & GLOB_ALTNOT) ? M_ALTNOT : M_NOT; - char cpathbuf[GLOBBUFLEN], *ptr;; + size_t orig_len; - *pathend = EOS; + strbuf_terminate(pathbuf); errno = 0; - if (!(dirp = Opendir(pathbuf))) { + if (!(dirp = Opendir(pathbuf->s))) { /* todo: don't call for ENOENT or ENOTDIR? */ - for (ptr = cpathbuf; (*ptr++ = (char) *pathbuf++) != EOS;) - continue; - if ((pglob->gl_errfunc && (*pglob->gl_errfunc) (cpathbuf, errno)) || + if ((pglob->gl_errfunc && (*pglob->gl_errfunc) (pathbuf->s, errno)) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABEND); else @@ -610,27 +555,24 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob, no_match) err = 0; + orig_len = pathbuf->len; /* search directory for matching names */ while ((dp = readdir(dirp)) != NULL) { - unsigned char *sc; - Char *dc; - /* initial DOT must be matched literally */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; - for (sc = (unsigned char *) dp->d_name, dc = pathend; - (*dc++ = *sc++) != '\0';) + pathbuf->len = orig_len; + strbuf_append(pathbuf, dp->d_name); + strbuf_terminate(pathbuf); + if (match(pathbuf->s + orig_len, pattern, restpattern, (int) m_not) + == no_match) continue; - if (match(pathend, pattern, restpattern, (int) m_not) == no_match) { - *pathend = EOS; - continue; - } - err = glob2(pathbuf, --dc, restpattern, pglob, no_match); + err = glob2(pathbuf, restpattern, pglob, no_match); if (err) break; } /* todo: check error from readdir? */ - (void) closedir(dirp); + closedir(dirp); return (err); } @@ -649,23 +591,15 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob, no_match) * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ -static int -globextend(path, pglob) - Char *path; - glob_t *pglob; +static void +globextend(const char *path, glob_t *pglob) { char **pathv; int i; - unsigned int newsize; - char *copy; - Char *p; + size_t newsize; newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = (char **) (pglob->gl_pathv ? - xrealloc((ptr_t) pglob->gl_pathv, (size_t) newsize) : - xmalloc((size_t) newsize)); - if (pathv == NULL) - return (GLOB_NOSPACE); + pathv = xrealloc(pglob->gl_pathv, newsize); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ @@ -675,23 +609,12 @@ globextend(path, pglob) } pglob->gl_pathv = pathv; - for (p = path; *p++;) - continue; - if ((copy = (char *) xmalloc((size_t) (p - path))) != NULL) { - char *dc = copy; - Char *sc = path; - - while ((*dc++ = *sc++) != '\0') - continue; - pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; - } + pathv[pglob->gl_offs + pglob->gl_pathc++] = strsave(path); pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; - return ((copy == NULL) ? GLOB_NOSPACE : 0); } - static size_t -One_mbtowc(NLSChar *pwc, const Char *s, size_t n) +One_Char_mbtowc(__Char *pwc, const Char *s, size_t n) { #ifdef WIDE_STRINGS char buf[MB_LEN_MAX], *p; @@ -699,11 +622,12 @@ One_mbtowc(NLSChar *pwc, const Char *s, size_t n) if (n > MB_LEN_MAX) n = MB_LEN_MAX; p = buf; - while (p < buf + n && (*p++ = CHAR(*s++)) != 0) + while (p < buf + n && (*p++ = LCHAR(*s++)) != 0) ; return one_mbtowc(pwc, buf, n); #else - return NLSFrom(s, n, pwc); + *pwc = *s & CHAR; + return 1; #endif } @@ -712,21 +636,18 @@ One_mbtowc(NLSChar *pwc, const Char *s, size_t n) * pattern causes a recursion level. */ static int -match(name, pat, patend, m_not) - Char *name, *pat, *patend; - int m_not; +match(const char *name, const Char *pat, const Char *patend, int m_not) { int ok, negate_range; - Char c, k; + Char c; while (pat < patend) { size_t lwk; - NLSChar wc, wk; + __Char wc, wk; - USE(k); c = *pat; /* Only for M_MASK bits */ - pat += One_mbtowc(&wc, pat, MB_LEN_MAX); - lwk = One_mbtowc(&wk, name, MB_LEN_MAX); + pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX); + lwk = one_mbtowc(&wk, name, MB_LEN_MAX); switch (c & M_MASK) { case M_ALL: if (pat == patend) @@ -737,7 +658,7 @@ match(name, pat, patend, m_not) if (*name == EOS) break; name += lwk; - lwk = One_mbtowc(&wk, name, MB_LEN_MAX); + lwk = one_mbtowc(&wk, name, MB_LEN_MAX); } return (0); case M_ONE: @@ -753,19 +674,19 @@ match(name, pat, patend, m_not) if ((negate_range = ((*pat & M_MASK) == m_not)) != 0) ++pat; while ((*pat & M_MASK) != M_END) { - pat += One_mbtowc(&wc, pat, MB_LEN_MAX); + pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX); if ((*pat & M_MASK) == M_RNG) { - NLSChar wc2; - + __Char wc2; + pat++; - pat += One_mbtowc(&wc2, pat, MB_LEN_MAX); + pat += One_Char_mbtowc(&wc2, pat, MB_LEN_MAX); if (globcharcoll(wc, wk, 0) <= 0 && globcharcoll(wk, wc2, 0) <= 0) ok = 1; } else if (wc == wk) ok = 1; } - pat += One_mbtowc(&wc, pat, MB_LEN_MAX); + pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX); if (ok == negate_range) return (0); break; @@ -781,8 +702,7 @@ match(name, pat, patend, m_not) /* free allocated data belonging to a glob_t structure */ void -globfree(pglob) - glob_t *pglob; +globfree(glob_t *pglob) { int i; char **pp; @@ -791,7 +711,7 @@ globfree(pglob) pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) - xfree((ptr_t) *pp), *pp = NULL; - xfree((ptr_t) pglob->gl_pathv), pglob->gl_pathv = NULL; + xfree(*pp), *pp = NULL; + xfree(pglob->gl_pathv), pglob->gl_pathv = NULL; } } |