This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add File::BSDGlob as File::Glob and load it at compile-time
[perl5.git] / ext / File / Glob / Glob.xs
CommitLineData
72b16652
GS
1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4
5#include "bsd_glob.h"
6
7static int GLOB_ERROR = 0;
8
9static int
10not_here(char *s)
11{
12 croak("%s not implemented on this architecture", s);
13 return -1;
14}
15
16
17static double
18constant(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
148not_there:
149 errno = ENOENT;
150 return 0;
151}
152
153#ifdef WIN32
154#define errfunc NULL
155#else
156int
157errfunc(const char *foo, int bar) {
158 return !(bar == ENOENT || bar == ENOTDIR);
159}
160#endif
161
162MODULE = File::Glob PACKAGE = File::Glob
163
164void
165doglob(pattern,...)
166 char *pattern
167PROTOTYPE:
168PREINIT:
169 glob_t pglob;
170 int i;
171 int retval;
172 int flags = 0;
173 SV *tmp;
174PPCODE:
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
199double
200constant(name,arg)
201 char *name
202 int arg
203PROTOTYPE: