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