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