wildcard.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Copyright (c) 1983-2023 Martin Atkins and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /*
  22. * Sound Filing System - Library
  23. *
  24. * wildcard - sound file wildcards
  25. *
  26. * Copyright M. C. Atkins, April 1987
  27. * All Rights Reserved.
  28. */
  29. //static char *rcsid = "$Id: wildcard.c%v 1.1 1994/10/31 16:49:56 martin Exp $";
  30. /*
  31. * $Log: wildcard.c%v $
  32. * Revision 1.1 1994/10/31 16:49:56 martin
  33. * Initial revision
  34. *
  35. */
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <sfsys.h>
  39. #include "sffuncs.h"
  40. #include "wildcard.h"
  41. //static char *wildcard_h_rcsid = WILDCARD_H_RCSID;
  42. struct wildcard {
  43. int code;
  44. struct wildcard *next;
  45. int arglen;
  46. char arg[1];
  47. };
  48. int
  49. iswildcard(char *filename)
  50. {
  51. while(*filename != '\0') {
  52. switch(*filename++) {
  53. case '?':
  54. case '*':
  55. case '[':
  56. case '\\':
  57. return 1;
  58. }
  59. }
  60. return 0;
  61. }
  62. void
  63. freeargv(char **a)
  64. {
  65. char **ap = a;
  66. while(*ap != 0)
  67. free(*ap++);
  68. free(a);
  69. }
  70. struct wildcard *
  71. mkwildcard(int code, char *str)
  72. {
  73. int len = (str != 0) ? strlen(str) : 0;
  74. struct wildcard *res = (struct wildcard *)
  75. malloc(sizeof(struct wildcard) + len);
  76. if(res == 0)
  77. return 0;
  78. res->code = code;
  79. res->next = 0;
  80. res->arglen = len;
  81. if(str != 0)
  82. strcpy(res->arg, str);
  83. return res;
  84. }
  85. void
  86. wildfree(struct wildcard *wld)
  87. {
  88. struct wildcard *next;
  89. while(wld != 0) {
  90. next = wld->next;
  91. free(wld);
  92. wld = next;
  93. }
  94. }
  95. struct wildcard *
  96. wildcomp(char *str)
  97. {
  98. struct wildcard *res = 0;
  99. struct wildcard **thisp = &res;
  100. char buf[400];
  101. char *bp = buf;
  102. while(str[0] != '\0') {
  103. switch(str[0]) {
  104. case '?':
  105. case '*':
  106. if(bp != buf) {
  107. *bp++ = '\0';
  108. if((*thisp = mkwildcard('A', buf)) == 0)
  109. return 0;
  110. thisp = &(*thisp)->next;
  111. bp = buf;
  112. }
  113. if((*thisp = mkwildcard(*str, 0)) == 0)
  114. return 0;
  115. thisp = &(*thisp)->next;
  116. break;
  117. case '\\':
  118. if(str[1] == '\0')
  119. *bp++ = '\\';
  120. else
  121. *bp++ = *++str;
  122. break;
  123. case '[':
  124. if(bp != buf) {
  125. *bp++ = '\0';
  126. if((*thisp = mkwildcard('A', buf)) == 0)
  127. return 0;
  128. thisp = &(*thisp)->next;
  129. bp = buf;
  130. }
  131. while(*++str != ']') {
  132. switch(str[0]) {
  133. case '\0':
  134. wildfree(res);
  135. return 0;
  136. case '-':
  137. if(bp == buf || str[1] == ']' || str[1] == '\0')
  138. *bp++ = '-';
  139. else {
  140. int from = bp[-1] + 1;
  141. int to = str[1];
  142. while(from <= to)
  143. *bp++ = (char) from++;
  144. str++;
  145. }
  146. break;
  147. case '\\':
  148. if(str[1] == '\0')
  149. *bp++ = '\\';
  150. else
  151. *bp++ = *++str;
  152. break;
  153. default:
  154. *bp++ = *str;
  155. break;
  156. }
  157. }
  158. *bp++ = '\0';
  159. if((*thisp = mkwildcard('[', buf)) == 0)
  160. return 0;
  161. thisp = &(*thisp)->next;
  162. bp = buf;
  163. break;
  164. default:
  165. *bp++ = *str;
  166. break;
  167. }
  168. str++;
  169. }
  170. if(bp != buf) {
  171. *bp++ = '\0';
  172. if((*thisp = mkwildcard('A', buf)) == 0)
  173. return 0;
  174. }
  175. return res;
  176. }
  177. static int SFCALLS dofile(struct sf_direct *p);
  178. static char **matcharr;
  179. static char **nxtmatch;
  180. static struct wildcard *pat;
  181. char **
  182. wildmatchall(struct wildcard *wild)
  183. {
  184. if((matcharr = (char **)malloc(MAXMATCH * sizeof(char *))) == 0)
  185. return 0;
  186. nxtmatch = &matcharr[0];
  187. pat = wild;
  188. if(sfdir(dofile, SFDIR_USED) != SFDIR_NOTFOUND) {/* an error occured */
  189. char **t = matcharr;
  190. while(t < nxtmatch)
  191. free(*t++);
  192. free(matcharr);
  193. return 0;
  194. }
  195. *nxtmatch++ = 0;
  196. if((matcharr = (char **)realloc(matcharr, (nxtmatch-matcharr)*sizeof(char *))) == 0)
  197. return 0;
  198. return matcharr;
  199. }
  200. static int SFCALLS
  201. dofile(struct sf_direct *p)
  202. {
  203. char *res;
  204. if(wildmatch(p->name, pat)) {
  205. if((res = malloc(strlen(p->name) + 1)) == 0
  206. ||nxtmatch >= &matcharr[MAXMATCH])
  207. return 1;
  208. strcpy(res, p->name);
  209. *nxtmatch++ = res;
  210. }
  211. return 0;
  212. }
  213. char **
  214. wildexpand(char *filename)
  215. {
  216. struct wildcard *wld;
  217. char **res;
  218. char prefix[MAXPREFIX];
  219. char buf[MAXPREFIX + 100];
  220. if(filename[0] != '\\') {
  221. sfgetprefix(prefix);
  222. if(prefix[0] != '\0') { /* prefix is set */
  223. char *fp = prefix;
  224. char *tp = buf;
  225. do {
  226. *tp++ = *fp;
  227. if(*fp == '\\')
  228. *tp++ = '\\';
  229. } while(*fp++ != 0);
  230. strcat(buf, "\\\\");
  231. strcat(buf, filename);
  232. filename = buf;
  233. }
  234. }
  235. if((wld = wildcomp(filename)) == 0)
  236. return 0;
  237. res = wildmatchall(wld);
  238. wildfree(wld);
  239. return res;
  240. }
  241. int SFCALLS
  242. wildmatch(char *filename, struct wildcard *wild)
  243. {
  244. char *cp = filename;
  245. int len;
  246. while(*cp != '\0' && wild != 0) {
  247. switch(wild->code) {
  248. case 'A':
  249. if(strncmp(cp, wild->arg, wild->arglen) != 0)
  250. return 0;
  251. cp += wild->arglen;
  252. break;
  253. case '?':
  254. cp++;
  255. break;
  256. case '[':
  257. if(strchr(wild->arg, *cp) == 0)
  258. return 0;
  259. cp++;
  260. break;
  261. case '*':
  262. len = 0;
  263. do {
  264. if(wildmatch(&cp[len], wild->next))
  265. return 1;
  266. } while(cp[len++] != 0);
  267. return 0;
  268. }
  269. wild = wild->next;
  270. }
  271. return wild == 0 && *cp == 0;
  272. }