home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 <stdio.h>
- #ifdef atarist
- #include <stdlib.h>
- #endif
- #include <sys/types.h>
- #ifndef USG
- #include <sys/dir.h>
- #else
- #include <dirent.h>
- #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 <guido@mcvax.uucp>
- * 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
-