1 /*
2 * Copyright 2014-2016, Björn Ståhl
3 * License: 3-Clause BSD, see COPYING file in arcan source repository.
4 * Reference: http://arcan-fe.com
5 */
6
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <glob.h>
13 #include <math.h>
14
15 #include <stdbool.h>
16 #include <sys/types.h>
17 #include <arcan_math.h>
18 #include <arcan_general.h>
19
arcan_glob(char * basename,enum arcan_namespaces space,void (* cb)(char *,void *),void * tag)20 unsigned arcan_glob(char* basename, enum arcan_namespaces space,
21 void (*cb)(char*, void*), void* tag)
22 {
23 unsigned count = 0;
24
25 if (!basename || verify_traverse(basename) == NULL)
26 return 0;
27
28 /* need to track so that we don't glob namespaces that
29 * happen to collide */
30 size_t nspaces = (size_t) log2(RESOURCE_SYS_ENDM);
31
32 char* globslots[ nspaces ];
33 memset(globslots, '\0', sizeof(globslots));
34 size_t ofs = 0;
35
36 for (size_t i = 1; i <= RESOURCE_SYS_ENDM; i <<= 1){
37 if ( (space & i) == 0 )
38 continue;
39
40 glob_t res = {0};
41 char* path = arcan_expand_resource(basename, i);
42 bool match = false;
43
44 for (size_t j = 0; j < ofs; j++){
45 if (globslots[ j ] == NULL)
46 break;
47
48 if (strcmp(path, globslots[j]) == 0){
49 arcan_mem_free(path);
50 match = true;
51 break;
52 }
53 }
54
55 if (match)
56 continue;
57
58 globslots[ofs++] = path;
59
60 if ( glob(path, 0, NULL, &res) == 0 ){
61 char** beg = res.gl_pathv;
62
63 while(*beg){
64 cb(strrchr(*beg, '/') ? strrchr(*beg, '/')+1 : *beg, tag);
65 beg++;
66 count++;
67 }
68
69 globfree(&res);
70 }
71 }
72
73 for (size_t i = 0; i < nspaces && globslots[i] != NULL; i++)
74 arcan_mem_free(globslots[i]);
75
76 return count;
77 }
78
79