str * next() { switch(__last_yield) { case 0: goto __after_yield_0; case 1: goto __after_yield_1; case 2: goto __after_yield_2; case 3: goto __after_yield_3; default: break; } if ((!has_magic(pathname))) { if (__os__::__path__::lexists(pathname)) { __last_yield = 0; return pathname; __after_yield_0:; } throw new StopIteration(); } __0 = __os__::__path__::split(pathname); dirname = __0->__getfirst__(); basename = __0->__getsecond__(); if ((!___bool(dirname))) { FOR_IN_SEQ(name,glob1(__os__::curdir, basename),1,3) __last_yield = 1; return name; __after_yield_1:; END_FOR throw new StopIteration(); } if (has_magic(dirname)) { dirs = iglob(dirname); } else { dirs = (new list<str *>(1, dirname)); } if (has_magic(basename)) { FOR_IN(dirname,dirs,5) FOR_IN_SEQ(name,glob1(dirname, basename),7,9) __last_yield = 2; return __os__::__path__::join(2, dirname, name); __after_yield_2:; END_FOR END_FOR } else {
/* * 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(GDir *dir, const gchar *pattern, wapi_glob_t *pglob, gboolean ignorecase, gboolean unique) { const gchar *qpatnext; int c, err, oldpathc; gchar *bufnext, patbuf[PATH_MAX]; size_t limit = 0; qpatnext = pattern; oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case QUESTION: pglob->gl_flags |= WAPI_GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= WAPI_GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG_ENABLED qprintf("glob0:", patbuf); #endif if ((err = glob1(dir, patbuf, patbuf+PATH_MAX-1, pglob, &limit, ignorecase, unique)) != 0) return(err); if (pglob->gl_pathc == oldpathc) { return(WAPI_GLOB_NOMATCH); } return(0); }
/* glob0 -- glob a list, (destructively) passing through entries we don't care about */ static List *glob0(List *list, StrList *quote) { List *result, **prevp, *expand1; for (result = NULL, prevp = &result; list != NULL; list = list->next, quote = quote->next) { char *str; if ( quote->str == QUOTED || !haswild(str = getstr(list->term), quote->str) || (expand1 = glob1(str, quote->str)) == NULL ) { *prevp = list; prevp = &list->next; } else { *prevp = sortlist(expand1); while (*prevp != NULL) prevp = &(*prevp)->next; } } return result; }
int main() { try { init(); SDL_Surface *screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, SDL_DOUBLEBUF); if (screen == NULL) { throw std::string("Unable to set video mode: ")+SDL_GetError(); } Sprite background("images/falsemirror.bmp", 0.0, 0.0, false); Sprite trees("images/ringotrees.bmp", 1.0, 0.0, true); Sprite flowers("images/ringoflowers.bmp", 1.0, 0.0, true); Sprite cells("images/lastring.bmp", 1.0, 0.0, true); Sprite glob1("images/oil.bmp", 430.0, 315.0, true); Sprite glob2("images/oil.bmp", 430.0, 315.0, true); Sprite glob3("images/oil.bmp", 430.0, 315.0, true); Manager manager(START_X, START_Y, INCR_X, X_VELOCITY, Y_VELOCITY, DISC_VELOCITY, DT); manager.animate(screen, background, trees, flowers, cells, glob1, glob2, glob3); SDL_FreeSurface(screen); } catch(const std::string& msg) { std::cout << msg << std::endl; } catch(...) { std::cout << "oops" << std::endl; } }
/* * 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. */ int glob(const char *pattern, int flags, int (*errfunc) (const char *, int), glob_t *pglob) { int err, oldpathc; Char *bufnext, m_not; const unsigned char *patnext; int c, not; Char *qpatnext, *patbuf; int no_match; patnext = (const unsigned char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; oldpathc = pglob->gl_pathc; pglob->gl_matchc = 0; if (pglob->gl_flags & GLOB_ALTNOT) { not = ALTNOT; m_not = M_ALTNOT; } else { not = NOT; m_not = M_NOT; } patbuf = xmalloc((strlen(pattern) + 1) * sizeof(*patbuf)); bufnext = patbuf; no_match = *patnext == not; if (no_match) patnext++; if (flags & GLOB_QUOTE) { /* Protect the quoted characters */ while ((c = *patnext++) != EOS) { #ifdef WIDE_STRINGS int len; len = mblen((const char *)(patnext - 1), MB_LEN_MAX); if (len == -1) TCSH_IGNORE(mblen(NULL, 0)); else if (len > 1) { *bufnext++ = (Char) c; while (--len != 0) *bufnext++ = (Char) (*patnext++ | M_PROTECT); } else #endif /* WIDE_STRINGS */ if (c == QUOTE) { if ((c = *patnext++) == EOS) { c = QUOTE; --patnext; } *bufnext++ = (Char) (c | M_PROTECT); } else *bufnext++ = (Char) c; } } else while ((c = *patnext++) != EOS) *bufnext++ = (Char) c; *bufnext = EOS; bufnext = patbuf; qpatnext = patbuf; while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == not) ++qpatnext; if (*qpatnext == EOS || Strchr(qpatnext + 1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == not) --qpatnext; break; } pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_SET; if (c == not) *bufnext++ = m_not; c = *qpatnext++; do { *bufnext++ = LCHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = LCHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one [or three if globstar], * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL || ((flags & GLOB_STAR) != 0 && (bufnext - 1 == patbuf || bufnext[-2] != M_ALL || bufnext - 2 == patbuf || bufnext[-3] != M_ALL))) *bufnext++ = M_ALL; break; default: *bufnext++ = LCHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf(patbuf); #endif if ((err = glob1(patbuf, pglob, no_match)) != 0) { xfree(patbuf); return (err); } /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc && ((flags & GLOB_NOCHECK) || ((flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) { if (!(flags & GLOB_QUOTE)) globextend(pattern, pglob); else { char *copy, *dest; const char *src; /* copy pattern, interpreting quotes */ copy = xmalloc(strlen(pattern) + 1); dest = copy; src = pattern; while (*src != EOS) { /* Don't interpret quotes. The spec does not say we should do */ if (*src == QUOTE) { if (*++src == EOS) --src; } *dest++ = *src++; } *dest = EOS; globextend(copy, pglob); xfree(copy); } xfree(patbuf); return 0; } else if (!(flags & GLOB_NOSORT) && (pglob->gl_pathc != oldpathc)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); xfree(patbuf); return (0); }
/* * 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, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[PATH_MAX]; qpatnext = pattern; oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) { ++qpatnext; } if (*qpatnext == EOS || g_strchr(qpatnext + 1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) { --qpatnext; } break; } *bufnext++ = M_SET; if (c == NOT) { *bufnext++ = M_NOT; } c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) { *bufnext++ = M_ALL; } break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; if ((err = glob1(patbuf, patbuf+PATH_MAX - 1, pglob, limitp, 1)) != 0) { return err; } /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) { return globextend(pattern, pglob, limitp, NULL); } else { return GLOB_NOMATCH; } } if (!(pglob->gl_flags & GLOB_NOSORT)) { if ((pglob->gl_flags & GLOB_KEEPSTAT)) { /* Keep the paths and stat info synced during sort */ struct glob_path_stat *path_stat; int i; int n = pglob->gl_pathc - oldpathc; int o = pglob->gl_offs + oldpathc; if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) { return GLOB_NOSPACE; } for (i = 0; i < n; i++) { path_stat[i].gps_path = pglob->gl_pathv[o + i]; path_stat[i].gps_stat = pglob->gl_statv[o + i]; } qsort(path_stat, n, sizeof(*path_stat), compare_gps); for (i = 0; i < n; i++) { pglob->gl_pathv[o + i] = path_stat[i].gps_path; pglob->gl_statv[o + i] = path_stat[i].gps_stat; } free(path_stat); } else { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } } return 0; }
/* * 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. */ static int glob0(const Char *pattern, glob_t *pglob, size_t *limit) { const Char *qpatnext; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, pglob, limit)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if (((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) return(globextend(pattern, pglob, limit)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); }
/* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h; const Char *p; Char *b, *eb; if (*pattern != 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 != SLASH; *h++ = *p++) ; *h = EOS; #if 0 if (h == (char *)eb) return what; #endif if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ #if 0 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { #endif if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; b < eb && *h; *b++ = *h++) ; /* Append the rest of the pattern */ while (b < eb && (*b++ = *p++) != EOS) ; *b = 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 *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; size_t limit = 0; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return(globextend(pattern, pglob, &limit)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); } static int compare(const void *p, const void *q) { return(strcmp(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, pattern, pattern_last, pglob, limitp)); }
/* * 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; oldflags = pglob->gl_flags; oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != BG_EOS) { switch (c) { case BG_LBRACKET: c = *qpatnext; if (c == BG_NOT) ++qpatnext; if (*qpatnext == BG_EOS || g_strchr((Char *) qpatnext+1, BG_RBRACKET) == NULL) { *bufnext++ = BG_LBRACKET; if (c == BG_NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == BG_NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == BG_RANGE && (c = qpatnext[1]) != BG_RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != BG_RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case BG_QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case BG_STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = BG_EOS; #ifdef GLOB_DEBUG qprintf("glob0:", patbuf); #endif /* GLOB_DEBUG */ if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) { pglob->gl_flags = oldflags; return(err); } /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc && ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) { #ifdef GLOB_DEBUG printf("calling globextend from glob0\n"); #endif /* GLOB_DEBUG */ pglob->gl_flags = oldflags; return(globextend(qpat, pglob, &limit)); } else if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), (pglob->gl_flags & (GLOB_ALPHASORT|GLOB_NOCASE)) ? ci_compare : compare); pglob->gl_flags = oldflags; return(0); }
/* * 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, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[PATH_MAX]; qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { if (c == LBRACKET && *qpatnext == ':') { do { err = g_charclass(&qpatnext, &bufnext); if (err) break; c = *qpatnext++; } while (c == LBRACKET && *qpatnext == ':'); if (err == -1 && !(pglob->gl_flags & GLOB_NOCHECK)) return GLOB_NOMATCH; if (c == RBRACKET) break; } *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob, limitp)) != 0) return err; /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK)) return globextend(pattern, pglob, limitp, NULL); else return GLOB_NOMATCH; } if (!(pglob->gl_flags & GLOB_NOSORT)) { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } return 0; }
/* * NAME * glob - global command (file name generation) * * SYNOPSIS * glob command [arg ...] * * DESCRIPTION * See glob(1) the manual page for full details. */ int main(int argc, char **argv) { const char **gav; /* points to generated argument vector */ int pmc = 0; /* pattern-match count */ int i; const char **tav; const char *cmd; setmyerrexit(&ut_errexit); setmyname(argv[0]); setmypid(getpid()); /* * Set-ID execution is not supported. */ if (geteuid() != getuid() || getegid() != getgid()) err(SH_ERR, FMT1S, ERR_SETID); if (argc < 2) err(SH_ERR, FMT1S, ERR_GARGCOUNT); if ((gav = malloc(GAVNEW * sizeof(char *))) == NULL) { err(SH_ERR, FMT1S, ERR_NOMEM); /*NOTREACHED*/ } *gav = NULL; gavp = gav; gave = &gav[GAVNEW - 1]; while (*++argv != NULL) gav = glob1(gav, *argv, &pmc); gavp = NULL; if (pmc == 0) { err(SH_ERR, FMT1S, ERR_NOMATCH); /*NOTREACHED*/ } cmd = gav[0]; if (IS_LIBEXEC(EQUAL)) { for (i = 0; gav[i] != NULL; i++) ; /* nothing */ if ((tav = malloc((i + 1) * sizeof(char *))) == NULL) { err(SH_ERR, FMT1S, ERR_NOMEM); /*NOTREACHED*/ } if (EQUAL(cmd, "fd2")) tav[0] = FD2_PATH; else if (EQUAL(cmd, "goto")) tav[0] = GOTO_PATH; else tav[0] = IF_PATH; cmd = tav[0]; (void)memcpy(&tav[1], &gav[1], i * sizeof(char *)); (void)err_pexec(cmd, (char *const *)tav); } else (void)err_pexec(cmd, (char *const *)gav); /*NOTREACHED*/ return SH_ERR; }