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

📄 glob.c

📁 早期freebsd实现
💻 C
字号:
/* $Header: glob.c,v 2.0 85/11/21 07:22:47 jqj Exp $ *//* * $Log:	glob.c,v $ * Revision 2.0  85/11/21  07:22:47  jqj * 4.3BSD standard release *  * Revision 1.2  85/11/21  07:04:29  jqj * added RCS header line *  */#ifndef lintstatic char sccsid[] = "@(#)glob.c	4.2 3/1/83";#endif/* * C-shell glob for random programs. */#include <sys/param.h>#include <sys/stat.h>#include <sys/dir.h>#include <stdio.h>#include <errno.h>#include <pwd.h>#define	QUOTE 0200#define	TRIM 0177#define	eq(a,b)		(strcmp(a, b)==0)#define	GAVSIZ		(NCARGS/6)#define	isdir(d)	((d.st_mode & S_IFMT) == S_IFDIR)static	char **gargv;		/* Pointer to the (stack) arglist */static	short gargc;		/* Number args in gargv */static	short gnleft;static	short gflag;static	int tglob();char	**glob();char	*globerr;char	*home;struct	passwd *getpwnam();extern	int errno;static	char *strspl(), **copyblk(), *strend();char	*malloc(), *strcpy(), *strcat();static	int globcnt;char	*globchars = "`{[*?";static	char *gpath, *gpathp, *lastgpathp;static	int globbed;static	char *entp;static	char **sortbas;char **glob(v)	register char *v;{	char agpath[BUFSIZ];	char *agargv[GAVSIZ];	char *vv[2];	vv[0] = v;	vv[1] = 0;	gflag = 0;	rscan(vv, tglob);	if (gflag == 0)		return (copyblk(vv));	globerr = 0;	gpath = agpath; gpathp = gpath; *gpathp = 0;	lastgpathp = &gpath[sizeof agpath - 2];	ginit(agargv); globcnt = 0;	collect(v);	if (globcnt == 0 && (gflag&1)) {		blkfree(gargv), gargv = 0;		return (0);	} else		return (gargv = copyblk(gargv));}staticginit(agargv)	char **agargv;{	agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;	gnleft = NCARGS - 4;}staticcollect(as)	register char *as;{	if (eq(as, "{") || eq(as, "{}")) {		Gcat(as, "");		sort();	} else		acollect(as);}staticacollect(as)	register char *as;{	register int ogargc = gargc;	gpathp = gpath; *gpathp = 0; globbed = 0;	expand(as);	if (gargc != ogargc)		sort();}staticsort(){	register char **p1, **p2, *c;	char **Gvp = &gargv[gargc];	p1 = sortbas;	while (p1 < Gvp-1) {		p2 = p1;		while (++p2 < Gvp)			if (strcmp(*p1, *p2) > 0)				c = *p1, *p1 = *p2, *p2 = c;		p1++;	}	sortbas = Gvp;}staticexpand(as)	char *as;{	register char *cs;	register char *sgpathp, *oldcs;	struct stat stb;	sgpathp = gpathp;	cs = as;	if (*cs == '~' && gpathp == gpath) {		addpath('~');		for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)			addpath(*cs++);		if (!*cs || *cs == '/') {			if (gpathp != gpath + 1) {				*gpathp = 0;				if (gethdir(gpath + 1))					globerr = "Unknown user name after ~";				strcpy(gpath, gpath + 1);			} else				strcpy(gpath, home);			gpathp = strend(gpath);		}	}	while (!any(*cs, globchars)) {		if (*cs == 0) {			if (!globbed)				Gcat(gpath, "");			else if (stat(gpath, &stb) >= 0) {				Gcat(gpath, "");				globcnt++;			}			goto endit;		}		addpath(*cs++);	}	oldcs = cs;	while (cs > as && *cs != '/')		cs--, gpathp--;	if (*cs == '/')		cs++, gpathp++;	*gpathp = 0;	if (*oldcs == '{') {		execbrc(cs, ((char *)0));		return;	}	matchdir(cs);endit:	gpathp = sgpathp;	*gpathp = 0;}staticmatchdir(pattern)	char *pattern;{	struct stat stb;	register struct direct *dp;	DIR *dirp;	register int cnt;	dirp = opendir(gpath);	if (dirp == NULL) {		if (globbed)			return;		goto patherr2;	}	if (fstat(dirp->dd_fd, &stb) < 0)		goto patherr1;	if (!isdir(stb)) {		errno = ENOTDIR;		goto patherr1;	}	while ((dp = readdir(dirp)) != NULL) {		if (dp->d_ino == 0)			continue;		if (match(dp->d_name, pattern)) {			Gcat(gpath, dp->d_name);			globcnt++;		}	}	closedir(dirp);	return;patherr1:	closedir(dirp);patherr2:	globerr = "Bad directory components";}staticexecbrc(p, s)	char *p, *s;{	char restbuf[BUFSIZ + 2];	register char *pe, *pm, *pl;	int brclev = 0;	char *lm, savec, *sgpathp;	for (lm = restbuf; *p != '{'; *lm++ = *p++)		continue;	for (pe = ++p; *pe; pe++)	switch (*pe) {	case '{':		brclev++;		continue;	case '}':		if (brclev == 0)			goto pend;		brclev--;		continue;	case '[':		for (pe++; *pe && *pe != ']'; pe++)			continue;		continue;	}pend:	brclev = 0;	for (pl = pm = p; pm <= pe; pm++)	switch (*pm & (QUOTE|TRIM)) {	case '{':		brclev++;		continue;	case '}':		if (brclev) {			brclev--;			continue;		}		goto doit;	case ','|QUOTE:	case ',':		if (brclev)			continue;doit:		savec = *pm;		*pm = 0;		strcpy(lm, pl);		strcat(restbuf, pe + 1);		*pm = savec;		if (s == 0) {			sgpathp = gpathp;			expand(restbuf);			gpathp = sgpathp;			*gpathp = 0;		} else if (amatch(s, restbuf))			return (1);		sort();		pl = pm + 1;		if (brclev)			return (0);		continue;	case '[':		for (pm++; *pm && *pm != ']'; pm++)			continue;		if (!*pm)			pm--;		continue;	}	if (brclev)		goto doit;	return (0);}staticmatch(s, p)	char *s, *p;{	register int c;	register char *sentp;	char sglobbed = globbed;	if (*s == '.' && *p != '.')		return (0);	sentp = entp;	entp = s;	c = amatch(s, p);	entp = sentp;	globbed = sglobbed;	return (c);}staticamatch(s, p)	register char *s, *p;{	register int scc;	int ok, lc;	char *sgpathp;	struct stat stb;	int c, cc;	globbed = 1;	for (;;) {		scc = *s++ & TRIM;		switch (c = *p++) {		case '{':			return (execbrc(p - 1, s - 1));		case '[':			ok = 0;			lc = 077777;			while (cc = *p++) {				if (cc == ']') {					if (ok)						break;					return (0);				}				if (cc == '-') {					if (lc <= scc && scc <= *p++)						ok++;				} else					if (scc == (lc = cc))						ok++;			}			if (cc == 0)				if (ok)					p--;				else					return 0;			continue;		case '*':			if (!*p)				return (1);			if (*p == '/') {				p++;				goto slash;			}			s--;			do {				if (amatch(s, p))					return (1);			} while (*s++);			return (0);		case 0:			return (scc == 0);		default:			if (c != scc)				return (0);			continue;		case '?':			if (scc == 0)				return (0);			continue;		case '/':			if (scc)				return (0);slash:			s = entp;			sgpathp = gpathp;			while (*s)				addpath(*s++);			addpath('/');			if (stat(gpath, &stb) == 0 && isdir(stb))				if (*p == 0) {					Gcat(gpath, "");					globcnt++;				} else					expand(p);			gpathp = sgpathp;			*gpathp = 0;			return (0);		}	}}staticGmatch(s, p)	register char *s, *p;{	register int scc;	int ok, lc;	int c, cc;	for (;;) {		scc = *s++ & TRIM;		switch (c = *p++) {		case '[':			ok = 0;			lc = 077777;			while (cc = *p++) {				if (cc == ']') {					if (ok)						break;					return (0);				}				if (cc == '-') {					if (lc <= scc && scc <= *p++)						ok++;				} else					if (scc == (lc = cc))						ok++;			}			if (cc == 0)				if (ok)					p--;				else					return 0;			continue;		case '*':			if (!*p)				return (1);			for (s--; *s; s++)				if (Gmatch(s, p))					return (1);			return (0);		case 0:			return (scc == 0);		default:			if ((c & TRIM) != scc)				return (0);			continue;		case '?':			if (scc == 0)				return (0);			continue;		}	}}staticGcat(s1, s2)	register char *s1, *s2;{	register int len = strlen(s1) + strlen(s2) + 1;	if (len >= gnleft || gargc >= GAVSIZ - 1)		globerr = "Arguments too long";	else {		gargc++;		gnleft -= len;		gargv[gargc] = 0;		gargv[gargc - 1] = strspl(s1, s2);	}}staticaddpath(c)	char c;{	if (gpathp >= lastgpathp)		globerr = "Pathname too long";	else {		*gpathp++ = c;		*gpathp = 0;	}}staticrscan(t, f)	register char **t;	int (*f)();{	register char *p, c;	while (p = *t++) {		if (f == tglob)			if (*p == '~')				gflag |= 2;			else if (eq(p, "{") || eq(p, "{}"))				continue;		while (c = *p++)			(*f)(c);	}}staticscan(t, f)	register char **t;	int (*f)();{	register char *p, c;	while (p = *t++)		while (c = *p)			*p++ = (*f)(c);}statictglob(c)	register char c;{	if (any(c, globchars))		gflag |= c == '{' ? 2 : 1;	return (c);}statictrim(c)	char c;{	return (c & TRIM);}letter(c)	register char c;{	return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');}digit(c)	register char c;{	return (c >= '0' && c <= '9');}any(c, s)	register int c;	register char *s;{	while (*s)		if (*s++ == c)			return(1);	return(0);}blklen(av)	register char **av;{	register int i = 0;	while (*av++)		i++;	return (i);}char **blkcpy(oav, bv)	char **oav;	register char **bv;{	register char **av = oav;	while (*av++ = *bv++)		continue;	return (oav);}blkfree(av0)	char **av0;{	register char **av = av0;	while (*av)		free(*av++);	free((char *)av0);}staticchar *strspl(cp, dp)	register char *cp, *dp;{	register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));	if (ep == (char *)0)		fatal("Out of memory");	strcpy(ep, cp);	strcat(ep, dp);	return (ep);}staticchar **copyblk(v)	register char **v;{	register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *						sizeof(char **)));	if (nv == (char **)0)		fatal("Out of memory");	return (blkcpy(nv, v));}staticchar *strend(cp)	register char *cp;{	while (*cp)		cp++;	return (cp);}/* * Extract a home directory from the password file * The argument points to a buffer where the name of the * user whose home directory is sought is currently. * We write the home directory of the user back there. */gethdir(home)	char *home;{	register struct passwd *pp = getpwnam(home);	if (pp == 0)		return (1);	strcpy(home, pp->pw_dir);	return (0);}

⌨️ 快捷键说明

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