diff options
Diffstat (limited to 'ext/File/Glob/Glob.xs')
-rw-r--r-- | ext/File/Glob/Glob.xs | 203 |
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: |