/* * expansion of lharc's filename handling * Robert Stabl April 1990 * * see copyright notice below * * Wild card expansion * * $Id: wild.c,v 1.3 1991/06/05 13:55:14 bammi Exp $ * * $Log: wild.c,v $ * Revision 1.3 1991/06/05 13:55:14 bammi * minor patches * * Revision 1.2 1990/12/16 14:02:16 bammi * cleanup * * Revision 1.1 90/08/30 16:52:57 bammi * after asm * * Revision 1.4 89/02/20 20:03:40 dclemans * Add RCS identifiers * */ #include #ifdef atarist #include #endif #include #ifndef USG #include #else #include #endif /* USG */ #define ESCAPE_CHAR '\\' #define DIR_SEPARATOR '/' #define WILDCARDS "*?[" #define new_string(a) (char *)malloc((size_t)(a)) /**** Start of "glob" package ****/ /* This software is copyright (c) 1986 by Stichting Mathematisch Centrum. * You may use, modify and copy it, provided this notice is present in all * copies, modified or unmodified, and provided you don't make money for it. * * Written 86-jun-28 by Guido van Rossum, CWI, Amsterdam * Stripped down for local use, more portability by Dave Clemans */ /* Pattern matching function for filenames */ /* Each occurrence of the * pattern causes a recursion level */ #define EOS '\0' #define BOOL int #define NO 0 #define YES 1 #define M_ALL '\001' /* * */ #define M_ONE '\002' /* ? */ #define M_SET '\003' /* [ */ #define M_CMP '\004' /* ^ */ #define M_RNG '\005' /* - */ #define M_END '\006' /* ] */ static BOOL match(name, pat) char *name; char *pat; { register char c, k; BOOL ok,cmp; for (c = *pat++; c != EOS; c = *pat++) { switch (c) { case M_ONE: if (*name++ == EOS) return NO; break; case M_ALL: if (*pat == EOS) return YES; for (; *name != EOS; ++name) { if (match(name, pat)) return YES; } return NO; case M_SET: cmp= NO; ok= NO; k= *name++; while ((c= *pat++) != M_END) { if (c == M_CMP) cmp= YES; else if (*pat == M_RNG) { if (c <= k && k <= pat[1]) ok= YES; pat += 2; } else if (c == k) ok= YES; } if (!cmp && !ok) return NO; if (cmp && ok) return NO; break; default: if (*name++ != c) return NO; break; } } return *name == EOS; } /**** End of "glob" package ****/ char *wild_compile(pattern,upcase) char *pattern; int upcase; { register char *compiled; register char *in,*out; compiled = (char *)malloc((size_t)(strlen(pattern)+1)); if (compiled == (char *)NULL) { /* enough memory? */ fprintf(stderr,"Not enough memory\n"); return (char *)NULL; } out = compiled; for (in = pattern; *in; in++) { /* copy, "compiling" the pattern */ switch (*in) { /* a "special" character? */ case '\'': in++; while (*in && *in != '\'') *out++ = *in++; if (*in != '\'') break; break; case '"': in++; while (*in && *in != '"') { /* scan the string */ if (*in == ESCAPE_CHAR) { /* embedded escape char? */ in++; if (*in == '\0') break; } *out++ = *in++; } if (*in != '"') break; break; case ESCAPE_CHAR: in++; if (*in == '\0') break; *out++ = *in; break; case '*': *out++ = M_ALL; break; case '?': *out++ = M_ONE; break; case '[': *out++ = M_SET; in++; while (*in && *in != ']') { /* scan the set */ if (*in == '-' && (in[-1] == '[' || (in[-1] == '^' && in[-2] == '['))) *out++ = '-'; else if (*in == '-') *out++ = M_RNG; else if (*in == '^' && in[-1] == '[') *out++ = M_CMP; else if (*in == '^') *out++ = '^'; else if (*in == ESCAPE_CHAR && in[1] != '\0') *out++ = *++in; else if (*in == ESCAPE_CHAR) *out++ = ESCAPE_CHAR; else *out++ = *in; in++; } if (*in != ']') { /* if error found */ fprintf(stderr,"incomplete character class: missing ']'\n"); free(compiled); return (char *)NULL; } *out++ = M_END; break; default: *out++ = *in; break; } if (*in == '\0') break; } #ifdef GEMDOS *out = '\0'; for (out = compiled; *out; out++) { /* fixups for mono-case matching */ if (!upcase) continue; if (islower(*out)) *out = _toupper(*out); } #endif /* GEMDOS */ *out = '\0'; /* finally done, return compiled string */ return compiled; } /* end of wild_compile */ int wild_match(string,pattern) char *string; char *pattern; { register char *compiled; int rc; if (string == NULL || pattern == NULL) { return 0; } compiled = wild_compile(pattern,0); if (compiled == (char *)NULL) { /* any errors? message already printed */ return 0; } rc = match(string,compiled); free(compiled); return rc; } /* end of wild_match */ #ifdef TEST int main(void) { char string[100]; char pattern[100]; printf("pattern> "); fflush(stdout); gets(pattern); printf("string> "); fflush(stdout); gets(string); printf("wild_match(%s, %s) = %d\n",string, pattern, wild_match(string, pattern)); return(0); } #endif