98e366c4017feae351d11a0180ae95d98696d03f
[p5sagit/p5-mst-13.2.git] / ext / File / Glob / Glob.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include "bsd_glob.h"
6
7 static int GLOB_ERROR = 0;
8
9 static int
10 not_here(char *s)
11 {
12     croak("%s not implemented on this architecture", s);
13     return -1;
14 }
15
16
17 static double
18 constant(char *name, int arg)
19 {
20     errno = 0;
21     if (strlen(name) <= 5)
22         goto not_there;
23     switch (*(name+5)) {
24     case 'A':
25         if (strEQ(name, "GLOB_ABEND"))
26 #ifdef GLOB_ABEND
27             return GLOB_ABEND;
28 #else
29             goto not_there;
30 #endif
31         if (strEQ(name, "GLOB_ALTDIRFUNC"))
32 #ifdef GLOB_ALTDIRFUNC
33             return GLOB_ALTDIRFUNC;
34 #else
35             goto not_there;
36 #endif
37         break;
38     case 'B':
39         if (strEQ(name, "GLOB_BRACE"))
40 #ifdef GLOB_BRACE
41             return GLOB_BRACE;
42 #else
43             goto not_there;
44 #endif
45         break;
46     case 'C':
47         break;
48     case 'D':
49         break;
50     case 'E':
51         if (strEQ(name, "GLOB_ERR"))
52 #ifdef GLOB_ERR
53             return GLOB_ERR;
54 #else
55             goto not_there;
56 #endif
57         if (strEQ(name, "GLOB_ERROR"))
58             return GLOB_ERROR;
59         break;
60     case 'F':
61         break;
62     case 'G':
63         break;
64     case 'H':
65         break;
66     case 'I':
67         break;
68     case 'J':
69         break;
70     case 'K':
71         break;
72     case 'L':
73         break;
74     case 'M':
75         if (strEQ(name, "GLOB_MARK"))
76 #ifdef GLOB_MARK
77             return GLOB_MARK;
78 #else
79             goto not_there;
80 #endif
81         break;
82     case 'N':
83         if (strEQ(name, "GLOB_NOCHECK"))
84 #ifdef GLOB_NOCHECK
85             return GLOB_NOCHECK;
86 #else
87             goto not_there;
88 #endif
89         if (strEQ(name, "GLOB_NOMAGIC"))
90 #ifdef GLOB_NOMAGIC
91             return GLOB_NOMAGIC;
92 #else
93             goto not_there;
94 #endif
95         if (strEQ(name, "GLOB_NOSORT"))
96 #ifdef GLOB_NOSORT
97             return GLOB_NOSORT;
98 #else
99             goto not_there;
100 #endif
101         if (strEQ(name, "GLOB_NOSPACE"))
102 #ifdef GLOB_NOSPACE
103             return GLOB_NOSPACE;
104 #else
105             goto not_there;
106 #endif
107         break;
108     case 'O':
109         break;
110     case 'P':
111         break;
112     case 'Q':
113         if (strEQ(name, "GLOB_QUOTE"))
114 #ifdef GLOB_QUOTE
115             return GLOB_QUOTE;
116 #else
117             goto not_there;
118 #endif
119         break;
120     case 'R':
121         break;
122     case 'S':
123         break;
124     case 'T':
125         if (strEQ(name, "GLOB_TILDE"))
126 #ifdef GLOB_TILDE
127             return GLOB_TILDE;
128 #else
129             goto not_there;
130 #endif
131         break;
132     case 'U':
133         break;
134     case 'V':
135         break;
136     case 'W':
137         break;
138     case 'X':
139         break;
140     case 'Y':
141         break;
142     case 'Z':
143         break;
144     }
145     errno = EINVAL;
146     return 0;
147
148 not_there:
149     errno = ENOENT;
150     return 0;
151 }
152
153 #ifdef WIN32
154 #define errfunc         NULL
155 #else
156 int
157 errfunc(const char *foo, int bar) {
158   return !(bar == ENOENT || bar == ENOTDIR);
159 }
160 #endif
161
162 MODULE = File::Glob             PACKAGE = File::Glob
163
164 void
165 doglob(pattern,...)
166     char *pattern
167 PROTOTYPE:
168 PREINIT:
169     glob_t pglob;
170     int i;
171     int retval;
172     int flags = 0;
173     SV *tmp;
174 PPCODE:
175     {
176         /* allow for optional flags argument */
177         if (items > 1) {
178             flags = (int) SvIV(ST(1));
179         }
180
181         /* call glob */
182         retval = bsd_glob(pattern, flags, errfunc, &pglob);
183         GLOB_ERROR = retval;
184
185         /* return any matches found */
186         EXTEND(sp, pglob.gl_pathc);
187         for (i = 0; i < pglob.gl_pathc; i++) {
188             /* printf("# bsd_glob: %s\n", pglob.gl_pathv[i]); */
189             tmp = sv_2mortal(newSVpvn(pglob.gl_pathv[i],
190                                       strlen(pglob.gl_pathv[i])));
191             TAINT;
192             SvTAINT(tmp);
193             PUSHs(tmp);
194         }
195
196         bsd_globfree(&pglob);
197     }
198
199 double
200 constant(name,arg)
201     char *name
202     int   arg
203 PROTOTYPE: