summaryrefslogtreecommitdiff
path: root/ext/File/Glob/Glob.xs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/File/Glob/Glob.xs')
-rw-r--r--ext/File/Glob/Glob.xs203
1 files changed, 203 insertions, 0 deletions
diff --git a/ext/File/Glob/Glob.xs b/ext/File/Glob/Glob.xs
new file mode 100644
index 0000000000..98e366c401
--- /dev/null
+++ b/ext/File/Glob/Glob.xs
@@ -0,0 +1,203 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "bsd_glob.h"
+
+static int GLOB_ERROR = 0;
+
+static int
+not_here(char *s)
+{
+ croak("%s not implemented on this architecture", s);
+ return -1;
+}
+
+
+static double
+constant(char *name, int arg)
+{
+ errno = 0;
+ if (strlen(name) <= 5)
+ goto not_there;
+ switch (*(name+5)) {
+ case 'A':
+ if (strEQ(name, "GLOB_ABEND"))
+#ifdef GLOB_ABEND
+ return GLOB_ABEND;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "GLOB_ALTDIRFUNC"))
+#ifdef GLOB_ALTDIRFUNC
+ return GLOB_ALTDIRFUNC;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'B':
+ if (strEQ(name, "GLOB_BRACE"))
+#ifdef GLOB_BRACE
+ return GLOB_BRACE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'C':
+ break;
+ case 'D':
+ break;
+ case 'E':
+ if (strEQ(name, "GLOB_ERR"))
+#ifdef GLOB_ERR
+ return GLOB_ERR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "GLOB_ERROR"))
+ return GLOB_ERROR;
+ break;
+ case 'F':
+ break;
+ case 'G':
+ break;
+ case 'H':
+ break;
+ case 'I':
+ break;
+ case 'J':
+ break;
+ case 'K':
+ break;
+ case 'L':
+ break;
+ case 'M':
+ if (strEQ(name, "GLOB_MARK"))
+#ifdef GLOB_MARK
+ return GLOB_MARK;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'N':
+ if (strEQ(name, "GLOB_NOCHECK"))
+#ifdef GLOB_NOCHECK
+ return GLOB_NOCHECK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "GLOB_NOMAGIC"))
+#ifdef GLOB_NOMAGIC
+ return GLOB_NOMAGIC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "GLOB_NOSORT"))
+#ifdef GLOB_NOSORT
+ return GLOB_NOSORT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "GLOB_NOSPACE"))
+#ifdef GLOB_NOSPACE
+ return GLOB_NOSPACE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'O':
+ break;
+ case 'P':
+ break;
+ case 'Q':
+ if (strEQ(name, "GLOB_QUOTE"))
+#ifdef GLOB_QUOTE
+ return GLOB_QUOTE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'R':
+ break;
+ case 'S':
+ break;
+ case 'T':
+ if (strEQ(name, "GLOB_TILDE"))
+#ifdef GLOB_TILDE
+ return GLOB_TILDE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'U':
+ break;
+ case 'V':
+ break;
+ case 'W':
+ break;
+ case 'X':
+ break;
+ case 'Y':
+ break;
+ case 'Z':
+ break;
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+#ifdef WIN32
+#define errfunc NULL
+#else
+int
+errfunc(const char *foo, int bar) {
+ return !(bar == ENOENT || bar == ENOTDIR);
+}
+#endif
+
+MODULE = File::Glob PACKAGE = File::Glob
+
+void
+doglob(pattern,...)
+ char *pattern
+PROTOTYPE:
+PREINIT:
+ glob_t pglob;
+ int i;
+ int retval;
+ int flags = 0;
+ SV *tmp;
+PPCODE:
+ {
+ /* allow for optional flags argument */
+ if (items > 1) {
+ flags = (int) SvIV(ST(1));
+ }
+
+ /* call glob */
+ retval = bsd_glob(pattern, flags, errfunc, &pglob);
+ GLOB_ERROR = retval;
+
+ /* return any matches found */
+ EXTEND(sp, pglob.gl_pathc);
+ for (i = 0; i < pglob.gl_pathc; i++) {
+ /* printf("# bsd_glob: %s\n", pglob.gl_pathv[i]); */
+ tmp = sv_2mortal(newSVpvn(pglob.gl_pathv[i],
+ strlen(pglob.gl_pathv[i])));
+ TAINT;
+ SvTAINT(tmp);
+ PUSHs(tmp);
+ }
+
+ bsd_globfree(&pglob);
+ }
+
+double
+constant(name,arg)
+ char *name
+ int arg
+PROTOTYPE: