| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- * Copyright (c) 1983-2023 Martin Atkins and Composers Desktop Project Ltd
- * http://people.bath.ac.uk/masrwd
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The CDP System is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- /*
- * Sound Filing System - Library
- *
- * wildcard - sound file wildcards
- *
- * Copyright M. C. Atkins, April 1987
- * All Rights Reserved.
- */
- //static char *rcsid = "$Id: wildcard.c%v 1.1 1994/10/31 16:49:56 martin Exp $";
- /*
- * $Log: wildcard.c%v $
- * Revision 1.1 1994/10/31 16:49:56 martin
- * Initial revision
- *
- */
- #include <stdlib.h>
- #include <string.h>
- #include <sfsys.h>
- #include "sffuncs.h"
- #include "wildcard.h"
- //static char *wildcard_h_rcsid = WILDCARD_H_RCSID;
- struct wildcard {
- int code;
- struct wildcard *next;
- int arglen;
- char arg[1];
- };
- int
- iswildcard(char *filename)
- {
- while(*filename != '\0') {
- switch(*filename++) {
- case '?':
- case '*':
- case '[':
- case '\\':
- return 1;
- }
- }
- return 0;
- }
- void
- freeargv(char **a)
- {
- char **ap = a;
- while(*ap != 0)
- free(*ap++);
- free(a);
- }
- struct wildcard *
- mkwildcard(int code, char *str)
- {
- int len = (str != 0) ? strlen(str) : 0;
- struct wildcard *res = (struct wildcard *)
- malloc(sizeof(struct wildcard) + len);
- if(res == 0)
- return 0;
- res->code = code;
- res->next = 0;
- res->arglen = len;
- if(str != 0)
- strcpy(res->arg, str);
- return res;
- }
- void
- wildfree(struct wildcard *wld)
- {
- struct wildcard *next;
- while(wld != 0) {
- next = wld->next;
- free(wld);
- wld = next;
- }
- }
- struct wildcard *
- wildcomp(char *str)
- {
- struct wildcard *res = 0;
- struct wildcard **thisp = &res;
- char buf[400];
- char *bp = buf;
- while(str[0] != '\0') {
- switch(str[0]) {
- case '?':
- case '*':
- if(bp != buf) {
- *bp++ = '\0';
- if((*thisp = mkwildcard('A', buf)) == 0)
- return 0;
- thisp = &(*thisp)->next;
- bp = buf;
- }
- if((*thisp = mkwildcard(*str, 0)) == 0)
- return 0;
- thisp = &(*thisp)->next;
- break;
- case '\\':
- if(str[1] == '\0')
- *bp++ = '\\';
- else
- *bp++ = *++str;
- break;
- case '[':
- if(bp != buf) {
- *bp++ = '\0';
- if((*thisp = mkwildcard('A', buf)) == 0)
- return 0;
- thisp = &(*thisp)->next;
- bp = buf;
- }
- while(*++str != ']') {
- switch(str[0]) {
- case '\0':
- wildfree(res);
- return 0;
- case '-':
- if(bp == buf || str[1] == ']' || str[1] == '\0')
- *bp++ = '-';
- else {
- int from = bp[-1] + 1;
- int to = str[1];
- while(from <= to)
- *bp++ = (char) from++;
- str++;
- }
- break;
- case '\\':
- if(str[1] == '\0')
- *bp++ = '\\';
- else
- *bp++ = *++str;
- break;
- default:
- *bp++ = *str;
- break;
- }
- }
- *bp++ = '\0';
- if((*thisp = mkwildcard('[', buf)) == 0)
- return 0;
- thisp = &(*thisp)->next;
- bp = buf;
- break;
- default:
- *bp++ = *str;
- break;
- }
- str++;
- }
- if(bp != buf) {
- *bp++ = '\0';
- if((*thisp = mkwildcard('A', buf)) == 0)
- return 0;
- }
- return res;
- }
- static int SFCALLS dofile(struct sf_direct *p);
- static char **matcharr;
- static char **nxtmatch;
- static struct wildcard *pat;
- char **
- wildmatchall(struct wildcard *wild)
- {
- if((matcharr = (char **)malloc(MAXMATCH * sizeof(char *))) == 0)
- return 0;
- nxtmatch = &matcharr[0];
- pat = wild;
- if(sfdir(dofile, SFDIR_USED) != SFDIR_NOTFOUND) {/* an error occured */
- char **t = matcharr;
- while(t < nxtmatch)
- free(*t++);
- free(matcharr);
- return 0;
- }
- *nxtmatch++ = 0;
- if((matcharr = (char **)realloc(matcharr, (nxtmatch-matcharr)*sizeof(char *))) == 0)
- return 0;
- return matcharr;
- }
- static int SFCALLS
- dofile(struct sf_direct *p)
- {
- char *res;
- if(wildmatch(p->name, pat)) {
- if((res = malloc(strlen(p->name) + 1)) == 0
- ||nxtmatch >= &matcharr[MAXMATCH])
- return 1;
- strcpy(res, p->name);
- *nxtmatch++ = res;
- }
- return 0;
- }
- char **
- wildexpand(char *filename)
- {
- struct wildcard *wld;
- char **res;
- char prefix[MAXPREFIX];
- char buf[MAXPREFIX + 100];
- if(filename[0] != '\\') {
- sfgetprefix(prefix);
- if(prefix[0] != '\0') { /* prefix is set */
- char *fp = prefix;
- char *tp = buf;
- do {
- *tp++ = *fp;
- if(*fp == '\\')
- *tp++ = '\\';
- } while(*fp++ != 0);
-
- strcat(buf, "\\\\");
- strcat(buf, filename);
- filename = buf;
- }
- }
- if((wld = wildcomp(filename)) == 0)
- return 0;
- res = wildmatchall(wld);
- wildfree(wld);
- return res;
- }
- int SFCALLS
- wildmatch(char *filename, struct wildcard *wild)
- {
- char *cp = filename;
- int len;
- while(*cp != '\0' && wild != 0) {
- switch(wild->code) {
- case 'A':
- if(strncmp(cp, wild->arg, wild->arglen) != 0)
- return 0;
- cp += wild->arglen;
- break;
- case '?':
- cp++;
- break;
- case '[':
- if(strchr(wild->arg, *cp) == 0)
- return 0;
- cp++;
- break;
- case '*':
- len = 0;
- do {
- if(wildmatch(&cp[len], wild->next))
- return 1;
- } while(cp[len++] != 0);
- return 0;
- }
- wild = wild->next;
- }
- return wild == 0 && *cp == 0;
- }
|