/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* file name expansion - posix.2 glob with gnu and ast extensions
*
* David Korn
* Glenn Fowler
* AT&T Research
*/
#include <ast.h>
#include <ls.h>
#include <stak.h>
#include <ast_dir.h>
#include <error.h>
#include <ctype.h>
#include <regex.h>
typedef int (*GL_error_f)(const char*, int);
typedef void* (*GL_opendir_f)(const char*);
typedef void (*GL_closedir_f)(void*);
#define _GLOB_PRIVATE_ \
int gl_error; \
char* gl_nextpath; \
globlist_t* gl_rescan; \
globlist_t* gl_match; \
int re_flags; \
int re_first; \
regex_t* gl_ignorei; \
unsigned long gl_starstar; \
char* gl_opt; \
char* gl_pat; \
char* gl_pad[4];
#include <glob.h>
/*
* default gl_diropen
*/
static void*
{
}
/*
* default gl_dirnext
*/
static char*
{
{
#ifdef D_TYPE
#endif
}
return 0;
}
/*
* default gl_dirclose
*/
static void
{
}
/*
* default gl_type
*/
static int
{
register int type;
type = 0;
else
return type;
}
/*
* default gl_attr
*/
static int
{
}
/*
* default gl_nextdir
*/
static char*
{
switch (*gp->gl_nextpath)
{
case 0:
dir = 0;
break;
case ':':
gp->gl_nextpath++;
dir = ".";
break;
default:
while (*gp->gl_nextpath)
{
break;
}
break;
}
return dir;
}
/*
* error intercept
*/
static int
{
int r = 1;
r = 0;
if (!r)
return r;
}
/*
* remove backslashes
*/
static void
{
register int c;
if (p1)
*n1 = 0;
if (p2)
*n2 = 0;
do
{
if ((c = *sp++) == '\\')
c = *sp++;
{
p1 = 0;
}
{
p2 = 0;
}
} while (*dp++ = c);
}
static void
addmatch(register glob_t* gp, const char* dir, const char* pat, register const char* rescan, char* endslash, int meta)
{
int offset;
int type;
if (dir)
{
}
if (endslash)
*endslash = 0;
if (rescan)
{
return;
/* if null, reserve room for . */
if (*rescan)
else
stakputc(0);
stakputc(0);
}
else
{
if (!endslash && (gp->gl_flags & GLOB_MARK) && (type = (*gp->gl_type)(gp, stakptr(MATCHPATH(gp)), 0)))
{
{
stakseek(0);
return;
}
}
}
}
/*
* this routine builds a list of files that match a given pathname
* uses REG_SHELL of <regex> to match each component
* a leading . must match explicitly
*/
static void
{
register char* rescan;
register char* prefix;
register char* pat;
register char* name;
register int c;
char* dirname;
void* dirf;
char first;
int notdir;
int t1;
int t2;
int bracket;
int complete = 0;
int err = 0;
int quote = 0;
int savequote = 0;
char* restore1 = 0;
char* restore2 = 0;
char* matchdir = 0;
int starstar = 0;
{
return;
}
bracket = 0;
for (;;)
{
switch (c = *rescan++)
{
case 0:
if (meta)
{
rescan = 0;
break;
}
if (quote)
{
}
{
*(rescan - 2) = 0;
if (c == GLOB_DIR)
}
return;
case '[':
if (!bracket)
{
rescan++;
if (*rescan == ']')
rescan++;
}
continue;
case ']':
continue;
case '(':
continue;
case '*':
case '?':
meta = MATCH_META;
continue;
case '\\':
{
quote = 1;
if (*rescan)
rescan++;
}
continue;
default:
{
if (meta)
break;
bracket = 0;
}
continue;
}
break;
}
if (matchdir)
goto skip;
{
prefix = 0;
{
complete = 1;
dirname = 0;
}
else
dirname = ".";
}
else
{
dirname = "/";
if (savequote)
{
quote = 0;
if (rescan)
}
}
{
if (pat[2])
{
pat += 3;
while (*pat=='/')
pat++;
if (*pat)
continue;
}
pat = "*";
goto skip;
}
if (matchdir)
{
goto again;
}
skip:
if (rescan)
{
register char* p = rescan;
while (p[0] == '*' && p[1] == '*' && (p[2] == '/' || p[2]==0))
{
rescan = p;
if (starstar = (p[2]==0))
break;
p += 3;
while (*p=='/')
p++;
if (*p==0)
{
starstar = 2;
break;
}
}
}
if (matchdir)
gp->gl_starstar++;
for (;;)
{
if (complete)
{
break;
}
if ((!starstar && !gp->gl_starstar || (*gp->gl_type)(gp, dirname, GLOB_STARSTAR) == GLOB_DIR) && (dirf = (*gp->gl_diropen)(gp, dirname)))
{
{
if (!prei)
{
break;
{
}
}
}
else
{
if (!prec)
{
break;
{
}
}
}
{
if (!gp->gl_ignorei)
{
{
break;
}
}
}
if (restore2)
{
continue;
{
}
errno = 0;
}
break;
}
break;
if (!complete)
break;
{
break;
}
}
if (restore1)
if (restore2)
if (prec)
if (prei)
if (err == REG_ESPACE)
}
int
{
register char* pat;
char** argv;
char** av;
unsigned long f;
int n;
int x;
int re_flags;
int optlen = 0;
int suflen = 0;
unsigned char intr = 0;
if (flags & GLOB_APPEND)
{
return GLOB_APPERR;
return GLOB_APPERR;
else
gp->gl_starstar = 0;
}
else
{
gp->gl_ignorei = 0;
gp->gl_starstar = 0;
{
gp->gl_fignore = 0;
gp->gl_diropen = 0;
gp->gl_dirnext = 0;
gp->gl_dirclose = 0;
gp->gl_nextdir = 0;
}
if (!(flags & GLOB_ALTDIRFUNC))
{
}
if (!gp->gl_diropen)
if (!gp->gl_dirnext)
if (!gp->gl_dirclose)
if (flags & GLOB_GROUP)
if (flags & GLOB_ICASE)
if (!gp->gl_fignore)
else if (*gp->gl_fignore)
{
return GLOB_APPERR;
}
return GLOB_NOSPACE;
}
if (flags & GLOB_DOOFFS)
{
n = 1;
x = 1;
pat += 2;
for (;;)
{
switch (*pat++)
{
case 0:
case ':':
break;
case '-':
n = 0;
continue;
case '+':
n = 1;
continue;
case 'i':
if (n)
f |= GLOB_ICASE;
else
f &= ~GLOB_ICASE;
continue;
case 'M':
if (n)
f |= GLOB_BRACE;
else
f &= ~GLOB_BRACE;
continue;
case 'N':
if (n)
f &= ~GLOB_NOCHECK;
else
f |= GLOB_NOCHECK;
continue;
case 'O':
if (n)
f |= GLOB_STARSTAR;
else
f &= ~GLOB_STARSTAR;
continue;
case ')':
if (f & GLOB_ICASE)
else
if (x)
break;
default:
x = 0;
continue;
}
break;
}
}
top = ap = (globlist_t*)stakalloc((optlen ? 2 : 1) * strlen(pattern) + sizeof(globlist_t) + suflen + gp->gl_extra);
if (suflen)
if (optlen)
else
suflen = 0;
do
{
{
if (flags & GLOB_NOCHECK)
{
}
else
}
else
{
{
}
else
{
while (--extra > 0)
*av++ = 0;
}
while (ap)
{
}
*argv = 0;
{
gp->gl_starstar = 0;
}
}
stakinstall(oldstak, 0);
}
void
{
{
if (gp->gl_ignorei)
}
}