perl
view release on metacpan or search on metacpan
ext/File-Glob/bsd_glob.c view on Meta::CPAN
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
/* most changes between the version above and the one below have been ported:
static char sscsid[]= "$OpenBSD: glob.c,v 1.8.10.1 2001/04/10 jason Exp $";
*/
#endif /* LIBC_SCCS and not lint */
/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
* GLOB_ALPHASORT:
* sort alphabetically like csh (case doesn't matter) instead of in ASCII
* order
*/
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include "bsd_glob.h"
#ifdef I_PWD
# include <pwd.h>
#else
#if defined(HAS_PASSWD) && !defined(VMS)
struct passwd *getpwnam(char *);
struct passwd *getpwuid(Uid_t);
#endif
#endif
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# else
# define MAXPATHLEN 1024
# endif
#endif
#include <limits.h>
#ifndef ARG_MAX
# ifdef _SC_ARG_MAX
# define ARG_MAX (sysconf(_SC_ARG_MAX))
# else
# ifdef _POSIX_ARG_MAX
# define ARG_MAX _POSIX_ARG_MAX
# else
# ifdef WIN32
# define ARG_MAX 14500 /* from VC's limits.h */
# else
# define ARG_MAX 4096 /* from POSIX, be conservative */
# endif
# endif
# endif
#endif
#define BG_DOLLAR '$'
#define BG_DOT '.'
#define BG_EOS '\0'
#define BG_LBRACKET '['
#define BG_NOT '!'
#define BG_QUESTION '?'
#define BG_QUOTE '\\'
#define BG_RANGE '-'
#define BG_RBRACKET ']'
#define BG_SEP '/'
#ifdef DOSISH
#define BG_SEP2 '\\'
#endif
#define BG_STAR '*'
#define BG_TILDE '~'
#define BG_UNDERSCORE '_'
#define BG_LBRACE '{'
#define BG_RBRACE '}'
#define BG_SLASH '/'
#define BG_COMMA ','
#ifndef GLOB_DEBUG
#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff
typedef U16 Char;
#else
ext/File-Glob/bsd_glob.c view on Meta::CPAN
*/
for (pl = pe + 1; (*lm++ = *pl++) != BG_EOS; )
;
/* Expand the current pattern */
#ifdef GLOB_DEBUG
qprintf("globexp2:", patbuf);
#endif /* GLOB_DEBUG */
*rv = globexp1(patbuf, pglob);
/* move after the comma, to the next string */
pl = pm + 1;
}
break;
default:
break;
}
}
*rv = 0;
return 0;
}
/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
{
char *h;
const Char *p;
Char *b, *eb;
if (*pattern != BG_TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
eb = &patbuf[patbuf_len - 1];
for (p = pattern + 1, h = (char *) patbuf;
h < (char*)eb && *p && *p != BG_SLASH; *h++ = (char)*p++)
;
*h = BG_EOS;
#if 0
if (h == (char *)eb)
return what;
#endif
if (((char *) patbuf)[0] == BG_EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
* or $USERPROFILE on DOSISH systems
*/
if ((h = PerlEnv_getenv("HOME")) == NULL) {
#ifdef HAS_PASSWD
struct passwd *pwd;
if ((pwd = getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
#elif DOSISH
/*
* When no passwd file, fallback to the USERPROFILE
* environment variable on DOSish systems.
*/
if ((h = PerlEnv_getenv("USERPROFILE")) == NULL) {
return pattern;
}
#else
return pattern;
#endif
}
} else {
/*
* Expand a ~user
*/
#ifdef HAS_PASSWD
struct passwd *pwd;
if ((pwd = getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
#else
return pattern;
#endif
}
/* Copy the home directory */
for (b = patbuf; b < eb && *h; *b++ = *h++)
;
/* Append the rest of the pattern */
while (b < eb && (*b++ = *p++) != BG_EOS)
;
*b = BG_EOS;
return patbuf;
}
/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(const Char *pattern, glob_t *pglob)
{
const Char *qpat, *qpatnext;
int c, err, oldflags, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN];
size_t limit = 0;
qpat = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
qpatnext = qpat;
( run in 1.477 second using v1.01-cache-2.11-cpan-140bd7fdf52 )