⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glob.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * 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 + -