From b514a325b560d0f36451050e15dd7ff985171d7b Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Tue, 7 Dec 1999 16:47:21 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'v1_4_3'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_4_3@582 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- dir.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 6 deletions(-) (limited to 'dir.c') diff --git a/dir.c b/dir.c index 31116a9fff..a771534155 100644 --- a/dir.c +++ b/dir.c @@ -47,12 +47,6 @@ # endif #endif -#ifdef HAVE_FNMATCH_H -#include -#else -#include "missing/fnmatch.h" -#endif - #include #ifdef USE_CWGUSI # include @@ -66,6 +60,167 @@ char *getenv(); char *strchr _((char*,char)); #endif +#include + +#define FNM_NOESCAPE 0x01 +#define FNM_PATHNAME 0x02 +#define FNM_PERIOD 0x04 +#define FNM_NOCASE 0x08 + +#define FNM_NOMATCH 1 +#define FNM_ERROR 2 + +#define downcase(c) (nocase && isupper(c) ? tolower(c) : (c)) + +#if defined DOSISH +#define isdirsep(c) ((c) == '/' || (c) == '\\') +static char * +find_dirsep(s) + char *s; +{ + while (*s) { + if (isdirsep(*s)) + return s; + s++; + } + return 0; +} +#else +#define isdirsep(c) ((c) == '/') +#define find_dirsep(s) strchr(s, '/') +#endif + +static char * +range(pat, test, flags) + char *pat; + char test; + int flags; +{ + int not, ok = 0; + int nocase = flags & FNM_NOCASE; + int escape = !(flags & FNM_NOESCAPE); + + not = *pat == '!' || *pat == '^'; + if (not) + pat++; + + test = downcase(test); + + while (*pat) { + int cstart, cend; + cstart = cend = *pat++; + if (cstart == ']') + return ok == not ? 0 : pat; + else if (escape && cstart == '\\') + cstart = cend = *pat++; + if (*pat == '-' && pat[1] != ']') { + if (escape && pat[1] == '\\') + pat++; + cend = pat[1]; + if (!cend) + return 0; + pat += 2; + } + if (downcase(cstart) <= test && test <= downcase(cend)) + ok = 1; + } + return 0; +} + +#define PERIOD(s) (period && *(s) == '.' && \ + ((s) == string || pathname && isdirsep(*(s)))) +static int +fnmatch(pat, string, flags) + char *pat; + char *string; + int flags; +{ + int c; + int test; + char *s = string; + int escape = !(flags & FNM_NOESCAPE); + int pathname = flags & FNM_PATHNAME; + int period = flags & FNM_PERIOD; + int nocase = flags & FNM_NOCASE; + + while (c = *pat++) { + switch (c) { + case '?': + if (!*s || pathname && isdirsep(*s) || PERIOD(s)) + return FNM_NOMATCH; + s++; + break; + case '*': + while ((c = *pat++) == '*') + ; + + if (PERIOD(s)) + return FNM_NOMATCH; + + if (!c) { + if (pathname && find_dirsep(s)) + return FNM_NOMATCH; + else + return 0; + } + else if (pathname && isdirsep(c)) { + s = find_dirsep(s); + if (s) + break; + return FNM_NOMATCH; + } + + test = escape && c == '\\' ? *pat : c; + test = downcase(test); + pat--; + while (*s) { + if ((c == '[' || downcase(*s) == test) && + !fnmatch(pat, s, flags & ~FNM_PERIOD)) + return 0; + else if (pathname && isdirsep(*s)) + break; + s++; + } + return FNM_NOMATCH; + + case '[': + if (!*s || pathname && isdirsep(*s) || PERIOD(s)) + return FNM_NOMATCH; + pat = range(pat, *s, flags); + if (!pat) + return FNM_NOMATCH; + s++; + break; + + case '\\': + if (escape +#if defined DOSISH + && *pat && strchr("*?[\\", *pat) +#endif + ) { + c = *pat; + if (!c) + c = '\\'; + else + pat++; + } + /* FALLTHROUGH */ + + default: +#if defined DOSISH + if (pathname && isdirsep(c) && isdirsep(*s)) + ; + else +#endif + if(downcase(c) != downcase(*s)) + return FNM_NOMATCH; + s++; + break; + } + } + return !*s ? 0 : FNM_NOMATCH; +} + VALUE rb_cDir; static void -- cgit v1.2.3