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