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

📄 bsd_glob.c

📁 source of perl for linux application,
💻 C
📖 第 1 页 / 共 3 页
字号:
				;			if (*pm == BG_EOS) {				/*				 * We could not find a matching BG_RBRACKET.				 * Ignore and just look for BG_RBRACE				 */				pm = pm1;			}			break;		case BG_LBRACE:			i++;			break;		case BG_RBRACE:			if (i) {				i--;				break;			}			/* FALLTHROUGH */		case BG_COMMA:			if (i && *pm == BG_COMMA)				break;			else {				/* Append the current string */				for (lm = ls; (pl < pm); *lm++ = *pl++)					;				/*				 * Append the rest of the pattern after the				 * closing brace				 */				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		 */		if ((h = getenv("HOME")) == NULL) {#ifdef HAS_PASSWD			struct passwd *pwd;			if ((pwd = getpwuid(getuid())) == NULL)				return pattern;			else				h = pwd->pw_dir;#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 intglob0(const Char *pattern, glob_t *pglob){	const Char *qpat, *qpatnext;	int c, err, oldflags, oldpathc;	Char *bufnext, patbuf[MAXPATHLEN];	size_t limit = 0;#ifdef MACOS_TRADITIONAL	if ( (*pattern == BG_TILDE) && (pglob->gl_flags & GLOB_TILDE) ) {		return(globextend(pattern, pglob, &limit));	}#endif	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);}static intci_compare(const void *p, const void *q){	const char *pp = *(const char **)p;	const char *qq = *(const char **)q;	int ci;	while (*pp && *qq) {		if (toLOWER(*pp) != toLOWER(*qq))			break;		++pp;		++qq;	}	ci = toLOWER(*pp) - toLOWER(*qq);	if (ci == 0)		return compare(p, q);	return ci;}static intcompare(const void *p, const void *q){	return(strcmp(*(char **)p, *(char **)q));}static intglob1(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 == BG_EOS)		return(0);	return(glob2(pathbuf, pathbuf+MAXPATHLEN-1,		     pathbuf, pathbuf+MAXPATHLEN-1,		     pattern, pattern_last, pglob, limitp));}/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */static intglob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,      Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp){	Stat_t sb;	Char *p, *q;	int anymeta;	/*	 * Loop over pattern segments until end of pattern or until	 * segment with meta character found.	 */	for (anymeta = 0;;) {		if (*pattern == BG_EOS) {		/* End of pattern? */			*pathend = BG_EOS;			if (g_lstat(pathbuf, &sb, pglob))				return(0);			if (((pglob->gl_flags & GLOB_MARK) &&			    pathend[-1] != BG_SEP#ifdef DOSISH			    && pathend[-1] != BG_SEP2#endif			    ) && (S_ISDIR(sb.st_mode) ||				  (S_ISLNK(sb.st_mode) &&			    (g_stat(pathbuf, &sb, pglob) == 0) &&			    S_ISDIR(sb.st_mode)))) {#ifdef MACOS_TRADITIONAL				short err;				err = glob_mark_Mac(pathbuf, pathend, pathend_last);				if (err)					return (err);#else				if (pathend+1 > pathend_last)					return (1);				*pathend++ = BG_SEP;				*pathend = BG_EOS;#endif			}			++pglob->gl_matchc;#ifdef GLOB_DEBUG                        printf("calling globextend from glob2\n");#endif /* GLOB_DEBUG */			return(globextend(pathbuf, pglob, limitp));		}		/* Find end of next segment, copy tentatively to pathend. */		q = pathend;		p = pattern;		while (*p != BG_EOS && *p != BG_SEP#ifdef DOSISH		       && *p != BG_SEP2#endif		       ) {			if (ismeta(*p))				anymeta = 1;			if (q+1 > pathend_last)				return (1);			*q++ = *p++;		}		if (!anymeta) {		/* No expansion, do next segment. */			pathend = q;			pattern = p;			while (*pattern == BG_SEP#ifdef DOSISH			       || *pattern == BG_SEP2#endif			       ) {				if (pathend+1 > pathend_last)					return (1);				*pathend++ = *pattern++;			}		} else			/* Need expansion, recurse. */			return(glob3(pathbuf, pathbuf_last, pathend,				     pathend_last, pattern, pattern_last,				     p, pattern_last, pglob, limitp));	}	/* NOTREACHED */}static intglob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,      Char *pattern, Char *pattern_last,      Char *restpattern, Char *restpattern_last, glob_t *pglob, size_t *limitp){	register Direntry_t *dp;	DIR *dirp;	int err;	int nocase;	char buf[MAXPATHLEN];	/*	 * The readdirfunc declaration can't be prototyped, because it is	 * assigned, below, to two functions which are prototyped in glob.h	 * and dirent.h as taking pointers to differently typed opaque	 * structures.	 */	Direntry_t *(*readdirfunc)(DIR*);	if (pathend > pathend_last)		return (1);	*pathend = BG_EOS;	errno = 0;#ifdef VMS        {		Char *q = pathend;		if (q - pathbuf > 5) {			q -= 5;			if (q[0] == '.' &&			    tolower(q[1]) == 'd' && tolower(q[2]) == 'i' &&			    tolower(q[3]) == 'r' && q[4] == '/')			{				q[0] = '/';				q[1] = BG_EOS;				pathend = q+1;			}		}        }#endif#ifdef MACOS_TRADITIONAL	if ((!*pathbuf) && (g_matchVol)) {	    FSSpec spec;	    short index;	    StrFileName vol_name; /* unsigned char[64] on MacOS */	    err = 0;	    nocase = ((pglob->gl_flags & GLOB_NOCASE) != 0);	    /* Get and match a list of volume names */	    for (index = 0; !GetVolInfo(index+1, true, &spec); ++index) {		register U8 *sc;		register Char *dc;		name_f_FSSpec(vol_name, &spec);		/* Initial BG_DOT must be matched literally. */		if (*vol_name == BG_DOT && *pattern != BG_DOT)		    continue;		dc = pathend;		sc = (U8 *) vol_name;		while (dc < pathend_last && (*dc++ = *sc++) != BG_EOS)		    ;		if (dc >= pathend_last) {		    *dc = BG_EOS;		    err = 1;		    break;		}		if (!match(pathend, pattern, restpattern, nocase)) {		    *pathend = BG_EOS;		    continue;		}		err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,		    restpattern, restpattern_last, pglob, limitp);		if (err)		    break;	    }	    return(err);	} else { /* open dir */#endif /* MACOS_TRADITIONAL */	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {		/* TODO: don't call for ENOENT or ENOTDIR? */		if (pglob->gl_errfunc) {			if (g_Ctoc(pathbuf, buf, sizeof(buf)))				return (GLOB_ABEND);			if (pglob->gl_errfunc(buf, errno) ||			    (pglob->gl_flags & GLOB_ERR))				return (GLOB_ABEND);		}		return(0);	}	err = 0;	nocase = ((pglob->gl_flags & GLOB_NOCASE) != 0);	/* Search directory for matching names. */	if (pglob->gl_flags & GLOB_ALTDIRFUNC)		readdirfunc = (Direntry_t *(*)(DIR *))pglob->gl_readdir;	else		readdirfunc = (Direntry_t *(*)(DIR *))my_readdir;	while ((dp = (*readdirfunc)(dirp))) {		register U8 *sc;		register Char *dc;		/* Initial BG_DOT must be matched literally. */		if (dp->d_name[0] == BG_DOT && *pattern != BG_DOT)			continue;		dc = pathend;		sc = (U8 *) dp->d_name;		while (dc < pathend_last && (*dc++ = *sc++) != BG_EOS)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -