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

📄 bsd_glob.c

📁 source of perl for linux application,
💻 C
📖 第 1 页 / 共 3 页
字号:
			;		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;	}	if (pglob->gl_flags & GLOB_ALTDIRFUNC)		(*pglob->gl_closedir)(dirp);	else		PerlDir_close(dirp);	return(err);#ifdef MACOS_TRADITIONAL	}#endif}/* * Extend the gl_pathv member of a glob_t structure to accomodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: *	Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and *	gl_pathv points to (gl_offs + gl_pathc + 1) items. */static intglobextend(const Char *path, glob_t *pglob, size_t *limitp){	register char **pathv;	register int i;	STRLEN newsize, len;	char *copy;	const Char *p;#ifdef GLOB_DEBUG	printf("Adding ");        for (p = path; *p; p++)                (void)printf("%c", CHAR(*p));        printf("\n");#endif /* GLOB_DEBUG */	newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);	if (pglob->gl_pathv)		pathv = Renew(pglob->gl_pathv,newsize,char*);	else		Newx(pathv,newsize,char*);	if (pathv == NULL) {		if (pglob->gl_pathv) {			Safefree(pglob->gl_pathv);			pglob->gl_pathv = NULL;		}		return(GLOB_NOSPACE);	}	if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {		/* first time around -- clear initial gl_offs items */		pathv += pglob->gl_offs;		for (i = pglob->gl_offs; --i >= 0; )			*--pathv = NULL;	}	pglob->gl_pathv = pathv;	for (p = path; *p++;)		;	len = (STRLEN)(p - path);	*limitp += len;	Newx(copy, p-path, char);	if (copy != NULL) {		if (g_Ctoc(path, copy, len)) {			Safefree(copy);			return(GLOB_NOSPACE);		}		pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;	}	pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;	if ((pglob->gl_flags & GLOB_LIMIT) &&	    newsize + *limitp >= ARG_MAX) {		errno = 0;		return(GLOB_NOSPACE);	}	return(copy == NULL ? GLOB_NOSPACE : 0);}/* * pattern matching function for filenames.  Each occurrence of the * * pattern causes a recursion level. */static intmatch(register Char *name, register Char *pat, register Char *patend, int nocase){	int ok, negate_range;	Char c, k;	while (pat < patend) {		c = *pat++;		switch (c & M_MASK) {		case M_ALL:			if (pat == patend)				return(1);			do			    if (match(name, pat, patend, nocase))				    return(1);			while (*name++ != BG_EOS)				;			return(0);		case M_ONE:			if (*name++ == BG_EOS)				return(0);			break;		case M_SET:			ok = 0;			if ((k = *name++) == BG_EOS)				return(0);			if ((negate_range = ((*pat & M_MASK) == M_NOT)) != BG_EOS)				++pat;			while (((c = *pat++) & M_MASK) != M_END)				if ((*pat & M_MASK) == M_RNG) {					if (nocase) {						if (tolower(c) <= tolower(k) && tolower(k) <= tolower(pat[1]))							ok = 1;					} else {						if (c <= k && k <= pat[1])							ok = 1;					}					pat += 2;				} else if (nocase ? (tolower(c) == tolower(k)) : (c == k))					ok = 1;			if (ok == negate_range)				return(0);			break;		default:			k = *name++;			if (nocase ? (tolower(k) != tolower(c)) : (k != c))				return(0);			break;		}	}	return(*name == BG_EOS);}/* Free allocated data belonging to a glob_t structure. */voidbsd_globfree(glob_t *pglob){	register int i;	register char **pp;	if (pglob->gl_pathv != NULL) {		pp = pglob->gl_pathv + pglob->gl_offs;		for (i = pglob->gl_pathc; i--; ++pp)			if (*pp)				Safefree(*pp);		Safefree(pglob->gl_pathv);		pglob->gl_pathv = NULL;	}}static DIR *g_opendir(register Char *str, glob_t *pglob){	char buf[MAXPATHLEN];	if (!*str) {#ifdef MACOS_TRADITIONAL		my_strlcpy(buf, ":", sizeof(buf));#else		my_strlcpy(buf, ".", sizeof(buf));#endif	} else {		if (g_Ctoc(str, buf, sizeof(buf)))			return(NULL);	}	if (pglob->gl_flags & GLOB_ALTDIRFUNC)		return((DIR*)(*pglob->gl_opendir)(buf));	return(PerlDir_open(buf));}static intg_lstat(register Char *fn, Stat_t *sb, glob_t *pglob){	char buf[MAXPATHLEN];	if (g_Ctoc(fn, buf, sizeof(buf)))		return(-1);	if (pglob->gl_flags & GLOB_ALTDIRFUNC)		return((*pglob->gl_lstat)(buf, sb));#ifdef HAS_LSTAT	return(PerlLIO_lstat(buf, sb));#else	return(PerlLIO_stat(buf, sb));#endif /* HAS_LSTAT */}static intg_stat(register Char *fn, Stat_t *sb, glob_t *pglob){	char buf[MAXPATHLEN];	if (g_Ctoc(fn, buf, sizeof(buf)))		return(-1);	if (pglob->gl_flags & GLOB_ALTDIRFUNC)		return((*pglob->gl_stat)(buf, sb));	return(PerlLIO_stat(buf, sb));}static Char *g_strchr(Char *str, int ch){	do {		if (*str == ch)			return (str);	} while (*str++);	return (NULL);}static intg_Ctoc(register const Char *str, char *buf, STRLEN len){	while (len--) {		if ((*buf++ = (char)*str++) == BG_EOS)			return (0);	}	return (1);}#ifdef GLOB_DEBUGstatic voidqprintf(const char *str, register Char *s){	register Char *p;	(void)printf("%s:\n", str);	for (p = s; *p; p++)		(void)printf("%c", CHAR(*p));	(void)printf("\n");	for (p = s; *p; p++)		(void)printf("%c", *p & M_PROTECT ? '"' : ' ');	(void)printf("\n");	for (p = s; *p; p++)		(void)printf("%c", ismeta(*p) ? '_' : ' ');	(void)printf("\n");}#endif /* GLOB_DEBUG */#ifdef MACOS_TRADITIONAL/* Replace the last occurrence of the pattern ":[^:]+::", e.g. ":lib::",   with a single ':', if possible. It is not an error, if the pattern   doesn't match (we return -1), but if there are two consecutive colons   '::', there must be a preceding ':[^:]+'. Hence,  a volume path like   "HD::" is considered to be an error (we return 1), that is, it can't   be resolved. We return 0 on success.*/static shortupdir(char *path){	char *pb, *pe, *lastchar;	char *bgn_mark, *end_mark;	char *f, *m, *b; /* front, middle, back */	size_t len;	len = strlen(path);	lastchar = path + (len-1);	b = lastchar;	m = lastchar-1;	f = lastchar-2;	/* find a '[^:]::' (e.g. b::) pattern ... */	while ( !( (*f != BG_SEP) && (*m == BG_SEP) && (*b == BG_SEP) )	        && (f >= path)) {		f--;		m--;		b--;	}	if (f < path) { /* no (more) match */		return -1;	}	end_mark = b;	/* ... and now find its preceding colon ':' */	while ((*f != BG_SEP) && (f >= path)) {		f--;	}	if (f < path) {		/* No preceding colon found, must be a		   volume path. We can't move up the		   tree and that's an error */		return 1;	}	bgn_mark = f;	/* Shrink path, i.e. exclude all characters between	   bgn_mark and end_mark */	pb = bgn_mark;	pe = end_mark;	while (*pb++ = *pe++) ;	return 0;}/* Resolve all updirs in pattern. */static shortresolve_updirs(char *new_pattern){	short err;	do {		err = updir(new_pattern);	} while (!err);	if (err == 1) {		return NO_UPDIR_ERR;	}	return 0;}/* Remove a trailing colon from the path, but only if it's   not a volume path (e.g. HD:) and not a path consisting   solely of colons. */static voidremove_trColon(char *path){	char *lastchar, *lc;	/* if path matches the pattern /:[^:]+:$/, we can	   remove the trailing ':' */	lc = lastchar = path + (strlen(path) - 1);	if (*lastchar == BG_SEP) {		/* there's a trailing ':', there must be at least		   one preceding char != ':' and a preceding ':' */		lc--;		if ((*lc != BG_SEP) && (lc >= path)) {			lc--;		} else {			return;		}		while ((*lc != BG_SEP) && (lc >= path)) {			lc--;		}		if (lc >= path) {			/* ... there's a preceding ':', we remove			   the trailing colon */			*lastchar = BG_EOS;		}	}}/* With the GLOB_MARK flag on, we append a colon, if pathbuf   is a directory. If the directory name contains no colons,   e.g. 'lib', we can't simply append a ':', since this (e.g.   'lib:') is not a valid (relative) path on Mac OS. Instead,   we add a leading _and_ trailing ':'. */static shortglob_mark_Mac(Char *pathbuf, Char *pathend, Char *pathend_last){	Char *p, *pe;	Boolean is_file = true;	/* check if pathbuf contains a ':',	   i.e. is not a file name */	p = pathbuf;	while (*p != BG_EOS) {		if (*p == BG_SEP) {			is_file = false;			break;		}		p++;	}	if (is_file) {		if (pathend+2 > pathend_last) {			return (1);		}		/* right shift one char */		pe = p = pathend;		p--;		pathend++;		while (p >= pathbuf) {			*pe-- = *p--;		}		/* first char becomes a colon */		*pathbuf = BG_SEP;		/* append a colon */		*pathend++ = BG_SEP;		*pathend = BG_EOS;	} else {		if (pathend+1 > pathend_last) {			return (1);		}		*pathend++ = BG_SEP;		*pathend = BG_EOS;	}	return 0;}/* Return a FSSpec record for the specified volume   (borrowed from MacPerl.xs). */static OSErrGetVolInfo(short volume, Boolean indexed, FSSpec* spec){	OSErr		err; /* OSErr: 16-bit integer */	HParamBlockRec	pb;	pb.volumeParam.ioNamePtr	= spec->name;	pb.volumeParam.ioVRefNum	= indexed ? 0 : volume;	pb.volumeParam.ioVolIndex	= indexed ? volume : 0;	if (err = PBHGetVInfoSync(&pb))		return err;	spec->vRefNum	= pb.volumeParam.ioVRefNum;	spec->parID	= 1;	return noErr; /* 0 */}/* Extract a C name from a FSSpec. Note that there are   no leading or trailing colons. */static voidname_f_FSSpec(StrFileName name, FSSpec *spec){	unsigned char *nc;	const short len = spec->name[0];	short i;	/* FSSpec.name is a Pascal string,	   convert it to C ... */	nc = name;	for (i=1; i<=len; i++) {		*nc++ = spec->name[i];	}	*nc = BG_EOS;}#endif /* MACOS_TRADITIONAL */

⌨️ 快捷键说明

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