This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
s/use vars/our/g modules that aren't independently maintained on CPAN
[perl5.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_NOCASE"))
84 #ifdef GLOB_NOCASE
85             return GLOB_NOCASE;
86 #else
87             goto not_there;
88 #endif
89         if (strEQ(name, "GLOB_NOCHECK"))
90 #ifdef GLOB_NOCHECK
91             return GLOB_NOCHECK;
92 #else
93             goto not_there;
94 #endif
95         if (strEQ(name, "GLOB_NOMAGIC"))
96 #ifdef GLOB_NOMAGIC
97             return GLOB_NOMAGIC;
98 #else
99             goto not_there;
100 #endif
101         if (strEQ(name, "GLOB_NOSORT"))
102 #ifdef GLOB_NOSORT
103             return GLOB_NOSORT;
104 #else
105             goto not_there;
106 #endif
107         if (strEQ(name, "GLOB_NOSPACE"))
108 #ifdef GLOB_NOSPACE
109             return GLOB_NOSPACE;
110 #else
111             goto not_there;
112 #endif
113         break;
114     case 'O':
115         break;
116     case 'P':
117         break;
118     case 'Q':
119         if (strEQ(name, "GLOB_QUOTE"))
120 #ifdef GLOB_QUOTE
121             return GLOB_QUOTE;
122 #else
123             goto not_there;
124 #endif
125         break;
126     case 'R':
127         break;
128     case 'S':
129         break;
130     case 'T':
131         if (strEQ(name, "GLOB_TILDE"))
132 #ifdef GLOB_TILDE
133             return GLOB_TILDE;
134 #else
135             goto not_there;
136 #endif
137         break;
138     case 'U':
139         break;
140     case 'V':
141         break;
142     case 'W':
143         break;
144     case 'X':
145         break;
146     case 'Y':
147         break;
148     case 'Z':
149         break;
150     }
151     errno = EINVAL;
152     return 0;
153
154 not_there:
155     errno = ENOENT;
156     return 0;
157 }
158
159 #ifdef WIN32
160 #define errfunc         NULL
161 #else
162 int
163 errfunc(const char *foo, int bar) {
164   return !(bar == ENOENT || bar == ENOTDIR);
165 }
166 #endif
167
168 MODULE = File::Glob             PACKAGE = File::Glob
169
170 void
171 doglob(pattern,...)
172     char *pattern
173 PROTOTYPE:
174 PREINIT:
175     glob_t pglob;
176     int i;
177     int retval;
178     int flags = 0;
179     SV *tmp;
180 PPCODE:
181     {
182         /* allow for optional flags argument */
183         if (items > 1) {
184             flags = (int) SvIV(ST(1));
185         }
186
187         /* call glob */
188         retval = bsd_glob(pattern, flags, errfunc, &pglob);
189         GLOB_ERROR = retval;
190
191         /* return any matches found */
192         EXTEND(sp, pglob.gl_pathc);
193         for (i = 0; i < pglob.gl_pathc; i++) {
194             /* printf("# bsd_glob: %s\n", pglob.gl_pathv[i]); */
195             tmp = sv_2mortal(newSVpvn(pglob.gl_pathv[i],
196                                       strlen(pglob.gl_pathv[i])));
197             TAINT;
198             SvTAINT(tmp);
199             PUSHs(tmp);
200         }
201
202         bsd_globfree(&pglob);
203     }
204
205 double
206 constant(name,arg)
207     char *name
208     int   arg
209 PROTOTYPE: