[comp.lang.c] Re^2: Wildcard Expansion

chris@wacsvax.OZ (chris mcdonald) (02/04/90)

karl@haddock.ima.isc.com (Karl Heuer) writes:

>In article <9460@ttidca.TTI.COM> paulb@ttidca.TTI.COM (Paul Blumstein) writes:
>>In article <8466@pogo.WV.TEK.COM> bluneski@pogo.WV.TEK.COM (Bob Luneski) writes:
>>>Does anyone have a general wildcard expansion code...
>>See if your system has re_comp & re_exec...

>Wildcard globbing is not the same thing as regexp matching.  You could do it
>that way, but you'd have to translate the wildcard pattern to a regexp first.

No, they are not the same, but you can easily convert a filename wildcard
into a regexp if you do not have true globbing code.

Just to show its easy, here's some code that runs under BSD but can be
easily modified for other Unix flavours. Note that this code does not
descend into directories. I can send you some other code if that's what
you want.

Good luck,

Chris McDonald.

Department of Computer Science,   ACSnet:   chris@wacsvax.oz
University of Western Australia,  ARPA:     chris%wacsvax.oz@uunet.uu.net
Mounts Bay Road,                  UUCP:     ..!uunet!murtoa!wacsvax!chris
Crawley, Western Australia, 6009. SDI:      (31.97 +/-10% S, 115.81 +/-10% E)
PHONE:  ((+61) 09) 380 2533       FAX:      ((+61) 09) 382 1688
--------------------------------------------------------------------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>

main(argc,argv) int argc; char *argv[];
{
    DIR *opendir(), *dir;
    struct direct *readdir(), *dp;
    char *getenv(), *re_comp(), *s, *t, buf[BUFSIZ];
    int dot = 0, nfound = 0;

    if(argc == 2)
	argv[2] = getenv("HOME");
    else if(argc != 3) {
	(void) fprintf(stderr,"Usage : %s pattern [directory]\n",argv[0]);
	exit(1);
    }

    if((dir = opendir(argv[2])) == NULL) {
	(void) fprintf(stderr,"%s : cannot open '%s'\n",argv[0],argv[2]);
	exit(1);
    }
    if(*argv[1] == '.') dot++;

    s = argv[1];
    t = buf;
    *t++ = '^';
    while(*s)
        switch (*s) {
        case '.' :
        case '\\':
        case '$' : *t++ = '\\'; *t++ = *s++; break;
        case '*' : *t++ = '.';  *t++ = *s++; break;
        case '?' : *t++ = '.'; s++; break;
        default  : *t++ = *s++;
        }
    *t++ = '$';
    *t   = '\0';
    (void) printf("%s -> %s\n",argv[1],buf);

    if((s = re_comp(buf)) != NULL) {
	(void) fprintf(stderr,"%s : %s\n",argv[0],s);
	exit(2);
    }
    while((dp = readdir(dir)) != NULL)
	if(dp->d_namlen != 0)
	    if((dot && *dp->d_name == '.') || *dp->d_name != '.')
	    {
	        if(re_exec(dp->d_name) == 1) {
	            (void) printf("%s\n",dp->d_name);
	            ++nfound;
	        }
	    }
    (void) printf("\n%d files\n",nfound);
    (void) closedir(dir);
    exit(0);
}