📄 glob.c
字号:
/*- * Copyright (c) 1980, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * 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. */#ifndef lintstatic char sccsid[] = "@(#)glob.c 8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/param.h>#include <glob.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#if __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include "csh.h"#include "extern.h"static int noglob;static int pargsiz, gargsiz;/* * Values for gflag */#define G_NONE 0 /* No globbing needed */#define G_GLOB 1 /* string contains *?[] characters */#define G_CSH 2 /* string contains ~`{ characters */#define GLOBSPACE 100 /* Alloc increment */#define LBRC '{'#define RBRC '}'#define LBRK '['#define RBRK ']'#define EOS '\0'Char **gargv = NULL;long gargc = 0;Char **pargv = NULL;long pargc = 0;/* * globbing is now done in two stages. In the first pass we expand * csh globbing idioms ~`{ and then we proceed doing the normal * globbing if needed ?*[ * * Csh type globbing is handled in globexpand() and the rest is * handled in glob() which is part of the 4.4BSD libc. * */static Char *globtilde __P((Char **, Char *));static Char **libglob __P((Char **));static Char **globexpand __P((Char **));static int globbrace __P((Char *, Char *, Char ***));static void expbrace __P((Char ***, Char ***, int));static int pmatch __P((Char *, Char *));static void pword __P((void));static void psave __P((int));static void backeval __P((Char *, bool));static Char *globtilde(nv, s) Char **nv, *s;{ Char gbuf[MAXPATHLEN], *gstart, *b, *u, *e; gstart = gbuf; *gstart++ = *s++; u = s; for (b = gstart, e = &gbuf[MAXPATHLEN - 1]; *s && *s != '/' && *s != ':' && b < e; *b++ = *s++) continue; *b = EOS; if (gethdir(gstart)) { blkfree(nv); if (*gstart) stderror(ERR_UNKUSER, vis_str(gstart)); else stderror(ERR_NOHOME); } b = &gstart[Strlen(gstart)]; while (*s) *b++ = *s++; *b = EOS; --u; xfree((ptr_t) u); return (Strsave(gstart));}static intglobbrace(s, p, bl) Char *s, *p, ***bl;{ int i, len; Char *pm, *pe, *lm, *pl; Char **nv, **vl; Char gbuf[MAXPATHLEN]; int size = GLOBSPACE; nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size); *vl = NULL; len = 0; /* copy part up to the brace */ for (lm = gbuf, p = s; *p != LBRC; *lm++ = *p++) continue; /* check for balanced braces */ for (i = 0, pe = ++p; *pe; pe++) if (*pe == LBRK) { /* Ignore everything between [] */ for (++pe; *pe != RBRK && *pe != EOS; pe++) continue; if (*pe == EOS) { blkfree(nv); return (-RBRK); } } else if (*pe == LBRC) i++; else if (*pe == RBRC) { if (i == 0) break; i--; } if (i != 0 || *pe == '\0') { blkfree(nv); return (-RBRC); } for (i = 0, pl = pm = p; pm <= pe; pm++) switch (*pm) { case LBRK: for (++pm; *pm != RBRK && *pm != EOS; pm++) continue; if (*pm == EOS) { *vl = NULL; blkfree(nv); return (-RBRK); } break; case LBRC: i++; break; case RBRC: if (i) { i--; break; } /* FALLTHROUGH */ case ',': if (i && *pm == ',') break; else { Char savec = *pm; *pm = EOS; (void) Strcpy(lm, pl); (void) Strcat(gbuf, pe + 1); *pm = savec; *vl++ = Strsave(gbuf); len++; pl = pm + 1; if (vl == &nv[size]) { size += GLOBSPACE; nv = (Char **) xrealloc((ptr_t) nv, (size_t) size * sizeof(Char *)); vl = &nv[size - GLOBSPACE]; } } break; default: break; } *vl = NULL; *bl = nv; return (len);}static voidexpbrace(nvp, elp, size) Char ***nvp, ***elp; int size;{ Char **vl, **el, **nv, *s; vl = nv = *nvp; if (elp != NULL) el = *elp; else for (el = vl; *el; el++) continue; for (s = *vl; s; s = *++vl) { Char *b; Char **vp, **bp; /* leave {} untouched for find */ if (s[0] == '{' && (s[1] == '\0' || (s[1] == '}' && s[2] == '\0'))) continue; if ((b = Strchr(s, '{')) != NULL) { Char **bl; int len; if ((len = globbrace(s, b, &bl)) < 0) { xfree((ptr_t) nv); stderror(ERR_MISSING, -len); } xfree((ptr_t) s); if (len == 1) { *vl-- = *bl; xfree((ptr_t) bl); continue; } len = blklen(bl); if (&el[len] >= &nv[size]) { int l, e; l = &el[len] - &nv[size]; size += GLOBSPACE > l ? GLOBSPACE : l; l = vl - nv; e = el - nv; nv = (Char **) xrealloc((ptr_t) nv, (size_t) size * sizeof(Char *)); vl = nv + l; el = nv + e; } vp = vl--; *vp = *bl; len--; for (bp = el; bp != vp; bp--) bp[len] = *bp; el += len; vp++; for (bp = bl + 1; *bp; *vp++ = *bp++) continue; xfree((ptr_t) bl); } } if (elp != NULL) *elp = el; *nvp = nv;}static Char **globexpand(v) Char **v;{ Char *s; Char **nv, **vl, **el; int size = GLOBSPACE; nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size); *vl = NULL; /* * Step 1: expand backquotes. */ while ((s = *v++) != NULL) { if (Strchr(s, '`')) { int i; (void) dobackp(s, 0); for (i = 0; i < pargc; i++) { *vl++ = pargv[i]; if (vl == &nv[size]) { size += GLOBSPACE; nv = (Char **) xrealloc((ptr_t) nv, (size_t) size * sizeof(Char *)); vl = &nv[size - GLOBSPACE]; } } xfree((ptr_t) pargv); pargv = NULL; } else { *vl++ = Strsave(s); if (vl == &nv[size]) { size += GLOBSPACE; nv = (Char **) xrealloc((ptr_t) nv, (size_t) size * sizeof(Char *)); vl = &nv[size - GLOBSPACE]; } } } *vl = NULL; if (noglob) return (nv); /* * Step 2: expand braces */ el = vl; expbrace(&nv, &el, size); /* * Step 3: expand ~ */ vl = nv; for (s = *vl; s; s = *++vl) if (*s == '~') *vl = globtilde(nv, s); vl = nv; return (vl);}static Char *handleone(str, vl, action) Char *str, **vl; int action;{ Char *cp, **vlp = vl; switch (action) { case G_ERROR: setname(vis_str(str)); blkfree(vl); stderror(ERR_NAME | ERR_AMBIG); break; case G_APPEND: trim(vlp); str = Strsave(*vlp++); do { cp = Strspl(str, STRspace); xfree((ptr_t) str); str = Strspl(cp, *vlp); xfree((ptr_t) cp); } while (*++vlp); blkfree(vl); break; case G_IGNORE: str = Strsave(strip(*vlp)); blkfree(vl); break; default: break; } return (str);}static Char **libglob(vl) Char **vl;{ int gflgs = GLOB_QUOTE | GLOB_NOMAGIC; glob_t globv; char *ptr; int nonomatch = adrof(STRnonomatch) != 0, magic = 0, match = 0; if (!vl || !vl[0]) return (vl); globv.gl_offs = 0; globv.gl_pathv = 0; globv.gl_pathc = 0; if (nonomatch) gflgs |= GLOB_NOCHECK; do { ptr = short2qstr(*vl); switch (glob(ptr, gflgs, 0, &globv)) { case GLOB_ABEND: setname(vis_str(*vl)); stderror(ERR_NAME | ERR_GLOB); /* NOTREACHED */ case GLOB_NOSPACE: stderror(ERR_NOMEM); /* NOTREACHED */ default: break; } if (globv.gl_flags & GLOB_MAGCHAR) { match |= (globv.gl_matchc != 0); magic = 1; } gflgs |= GLOB_APPEND; } while (*++vl); vl = (globv.gl_pathc == 0 || (magic && !match && !nonomatch)) ? NULL : blk2short(globv.gl_pathv); globfree(&globv); return (vl);}Char *globone(str, action) Char *str; int action;{ Char *v[2], **vl, **vo; int gflg; noglob = adrof(STRnoglob) != 0; gflag = 0; v[0] = str; v[1] = 0; tglob(v); gflg = gflag; if (gflg == G_NONE) return (strip(Strsave(str))); if (gflg & G_CSH) { /* * Expand back-quote, tilde and brace */ vo = globexpand(v); if (noglob || (gflg & G_GLOB) == 0) { if (vo[0] == NULL) { xfree((ptr_t) vo); return (Strsave(STRNULL)); } if (vo[1] != NULL) return (handleone(str, vo, action)); else { str = strip(vo[0]); xfree((ptr_t) vo); return (str); } } } else if (noglob || (gflg & G_GLOB) == 0) return (strip(Strsave(str))); else vo = v; vl = libglob(vo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -