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

📄 misc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (p[-1] == (0x80 | '?')			    && do_gmatch(s, se, prest, pe, isfile))				return 1;			for (psub = p; ; psub = pnext) {				pnext = pat_scan(psub, pe, 1);				srest = prest == pe ? se : s;				for (; srest <= se; srest++) {					if (do_gmatch(s, srest,						      psub, pnext - 2, isfile)					    && do_gmatch(srest, se,							 prest, pe, isfile))						return 1;				}				if (pnext == prest)					break;			}			return 0;		  case 0x80|'!': /* matches none of the patterns */			if (!(prest = pat_scan(p, pe, 0)))				return 0;			s--;			for (srest = s; srest <= se; srest++) {				int matched = 0;				for (psub = p; ; psub = pnext) {					pnext = pat_scan(psub, pe, 1);					if (do_gmatch(s, srest,						      psub, pnext - 2, isfile))					{						matched = 1;						break;					}					if (pnext == prest)						break;				}				if (!matched && do_gmatch(srest, se,							  prest, pe, isfile))					return 1;			}			return 0;		  default:			if (sc != p[-1])				return 0;			break;		}	}	return s == se;}static const unsigned char *cclass(p, sub)	const unsigned char *p;	register int sub;{	register int c, d, not, found = 0;	const unsigned char *orig_p = p;	if ((not = (ISMAGIC(*p) && *++p == NOT)))		p++;	do {		c = *p++;		if (ISMAGIC(c)) {			c = *p++;			if ((c & 0x80) && !ISMAGIC(c)) {				c &= 0x7f;/* extended pattern matching: *+?@! */				/* XXX the ( char isn't handled as part of [] */				if (c == ' ') /* simile for @: plain (..) */					c = '(' /*)*/;			}		}		if (c == '\0')			/* No closing ] - act as if the opening [ was quoted */			return sub == '[' ? orig_p : NULL;		if (ISMAGIC(p[0]) && p[1] == '-'		    && (!ISMAGIC(p[2]) || p[3] != ']'))		{			p += 2; /* MAGIC- */			d = *p++;			if (ISMAGIC(d)) {				d = *p++;				if ((d & 0x80) && !ISMAGIC(d))					d &= 0x7f;			}			/* POSIX says this is an invalid expression */			if (c > d)				return NULL;		} else			d = c;		if (c == sub || (c <= sub && sub <= d))			found = 1;	} while (!(ISMAGIC(p[0]) && p[1] == ']'));	return (found != not) ? p+2 : NULL;}/* Look for next ) or | (if match_sep) in *(foo|bar) pattern */const unsigned char *pat_scan(p, pe, match_sep)	const unsigned char *p;	const unsigned char *pe;	int match_sep;{	int nest = 0;	for (; p < pe; p++) {		if (!ISMAGIC(*p))			continue;		if ((*++p == /*(*/ ')' && nest-- == 0)		    || (*p == '|' && match_sep && nest == 0))			return ++p;		if ((*p & 0x80) && strchr("*+?@! ", *p & 0x7f))			nest++;	}	return (const unsigned char *) 0;}/* -------- qsort.c -------- *//* * quick sort of array of generic pointers to objects. */static void qsort1 ARGS((void **base, void **lim, int (*f)(void *, void *)));voidqsortp(base, n, f)	void **base;				/* base address */	size_t n;				/* elements */	int (*f) ARGS((void *, void *));	/* compare function */{	qsort1(base, base + n, f);}#define	swap2(a, b)	{\	register void *t; t = *(a); *(a) = *(b); *(b) = t;\}#define	swap3(a, b, c)	{\	register void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\}static voidqsort1(base, lim, f)	void **base, **lim;	int (*f) ARGS((void *, void *));{	register void **i, **j;	register void **lptr, **hptr;	size_t n;	int c;  top:	n = (lim - base) / 2;	if (n == 0)		return;	hptr = lptr = base+n;	i = base;	j = lim - 1;	for (;;) {		if (i < lptr) {			if ((c = (*f)(*i, *lptr)) == 0) {				lptr --;				swap2(i, lptr);				continue;			}			if (c < 0) {				i += 1;				continue;			}		}	  begin:		if (j > hptr) {			if ((c = (*f)(*hptr, *j)) == 0) {				hptr ++;				swap2(hptr, j);				goto begin;			}			if (c > 0) {				if (i == lptr) {					hptr ++;					swap3(i, hptr, j);					i = lptr += 1;					goto begin;				}				swap2(i, j);				j -= 1;				i += 1;				continue;			}			j -= 1;			goto begin;		}		if (i == lptr) {			if (lptr-base >= lim-hptr) {				qsort1(hptr+1, lim, f);				lim = lptr;			} else {				qsort1(base, lptr, f);				base = hptr+1;			}			goto top;		}		lptr -= 1;		swap3(j, lptr, i);		j = hptr -= 1;	}}intxstrcmp(p1, p2)	void *p1, *p2;{	return (strcmp((char *)p1, (char *)p2));}/* Initialize a Getopt structure */voidksh_getopt_reset(go, flags)	Getopt *go;	int flags;{	go->optind = 1;	go->optarg = (char *) 0;	go->p = 0;	go->flags = flags;	go->info = 0;	go->buf[1] = '\0';}/* getopt() used for shell built-in commands, the getopts command, and * command line options. * A leading ':' in options means don't print errors, instead return '?' * or ':' and set go->optarg to the offending option character. * If GF_ERROR is set (and option doesn't start with :), errors result in * a call to bi_errorf(). * * Non-standard features: *	- ';' is like ':' in options, except the argument is optional *	  (if it isn't present, optarg is set to 0). *	  Used for 'set -o'. *	- ',' is like ':' in options, except the argument always immediately *	  follows the option character (optarg is set to the null string if *	  the option is missing). *	  Used for 'read -u2', 'print -u2' and fc -40. *	- '#' is like ':' in options, expect that the argument is optional *	  and must start with a digit.  If the argument doesn't start with a *	  digit, it is assumed to be missing and normal option processing *	  continues (optarg is set to 0 if the option is missing). *	  Used for 'typeset -LZ4'. *	- accepts +c as well as -c IF the GF_PLUSOPT flag is present.  If an *	  option starting with + is accepted, the GI_PLUS flag will be set *	  in go->info. */intksh_getopt(argv, go, options)	char **argv;	Getopt *go;	const char *options;{	char c;	char *o;	if (go->p == 0 || (c = argv[go->optind - 1][go->p]) == '\0') {		char *arg = argv[go->optind], flag = arg ? *arg : '\0';		go->p = 1;		if (flag == '-' && arg[1] == '-' && arg[2] == '\0') {			go->optind++;			go->p = 0;			go->info |= GI_MINUSMINUS;			return EOF;		}		if (arg == (char *) 0		    || ((flag != '-' ) /* neither a - nor a + (if + allowed) */			&& (!(go->flags & GF_PLUSOPT) || flag != '+'))		    || (c = arg[1]) == '\0')		{			go->p = 0;			return EOF;		}		go->optind++;		go->info &= ~(GI_MINUS|GI_PLUS);		go->info |= flag == '-' ? GI_MINUS : GI_PLUS;	}	go->p++;	if (c == '?' || c == ':' || c == ';' || c == ',' || c == '#'	    || !(o = strchr(options, c)))	{		if (options[0] == ':') {			go->buf[0] = c;			go->optarg = go->buf;		} else {			warningf(TRUE, "%s%s-%c: unknown option",				(go->flags & GF_NONAME) ? "" : argv[0],				(go->flags & GF_NONAME) ? "" : ": ", c);			if (go->flags & GF_ERROR)				bi_errorf(null);		}		return '?';	}	/* : means argument must be present, may be part of option argument	 *   or the next argument	 * ; same as : but argument may be missing	 * , means argument is part of option argument, and may be null.	 */	if (*++o == ':' || *o == ';') {		if (argv[go->optind - 1][go->p])			go->optarg = argv[go->optind - 1] + go->p;		else if (argv[go->optind])			go->optarg = argv[go->optind++];		else if (*o == ';')			go->optarg = (char *) 0;		else {			if (options[0] == ':') {				go->buf[0] = c;				go->optarg = go->buf;				return ':';			}			warningf(TRUE, "%s%s-`%c' requires argument",				(go->flags & GF_NONAME) ? "" : argv[0],				(go->flags & GF_NONAME) ? "" : ": ", c);			if (go->flags & GF_ERROR)				bi_errorf(null);			return '?';		}		go->p = 0;	} else if (*o == ',') {		/* argument is attatched to option character, even if null */		go->optarg = argv[go->optind - 1] + go->p;		go->p = 0;	} else if (*o == '#') {		/* argument is optional and may be attatched or unattatched		 * but must start with a digit.  optarg is set to 0 if the		 * argument is missing.		 */		if (argv[go->optind - 1][go->p]) {			if (digit(argv[go->optind - 1][go->p])) {				go->optarg = argv[go->optind - 1] + go->p;				go->p = 0;			} else				go->optarg = (char *) 0;;		} else {			if (argv[go->optind] && digit(argv[go->optind][0])) {				go->optarg = argv[go->optind++];				go->p = 0;			} else				go->optarg = (char *) 0;;		}	}	return c;}/* print variable/alias value using necessary quotes * (POSIX says they should be suitable for re-entry...) * No trailing newline is printed. */voidprint_value_quoted(s)	const char *s;{	const char *p;	int inquote = 0;	/* Test if any quotes are needed */	for (p = s; *p; p++)		if (ctype(*p, C_QUOTE))			break;	if (!*p) {		shprintf("%s", s);		return;	}	for (p = s; *p; p++) {		if (*p == '\'') {			shprintf("'\\'" + 1 - inquote);			inquote = 0;		} else {			if (!inquote) {				shprintf("'");				inquote = 1;			}			shf_putc(*p, shl_stdout);		}	}	if (inquote)		shprintf("'");}/* Print things in columns and rows - func() is called to format the ith * element */voidprint_columns(shf, n, func, arg, max_width)	struct shf *shf;	int n;	char *(*func) ARGS((void *, int, char *, int));	void *arg;	int max_width;{	char *str = (char *) alloc(max_width + 1, ATEMP);	int i;	int r, c;	int rows, cols;	int nspace;	/* max_width + 1 for the space.  Note that no space	 * is printed after the last column to avoid problems	 * with terminals that have auto-wrap.	 */	cols = x_cols / (max_width + 1);	if (!cols)		cols = 1;	rows = (n + cols - 1) / cols;	if (n && cols > rows) {		int tmp = rows;		rows = cols;		cols = tmp;		if (rows > n)			rows = n;	}	nspace = (x_cols - max_width * cols) / cols;	if (nspace <= 0)		nspace = 1;	for (r = 0; r < rows; r++) {		for (c = 0; c < cols; c++) {			i = c * rows + r;			if (i < n) {				shf_fprintf(shf, "%-*s",					max_width,					(*func)(arg, i, str, max_width + 1));				if (c + 1 < cols)					shf_fprintf(shf, "%*s", nspace, null);			}		}		shf_putchar('\n', shf);	}	afree(str, ATEMP);}/* Strip any nul bytes from buf - returns new length (nbytes - # of nuls) */intstrip_nuls(buf, nbytes)	char *buf;	int nbytes;{	char *dst;	/* nbytes check because some systems (older freebsd's) have a buggy	 * memchr()	 */	if (nbytes && (dst = memchr(buf, '\0', nbytes))) {		char *end = buf + nbytes;		char *p, *q;		for (p = dst; p < end; p = q) {			/* skip a block of nulls */			while (++p < end && *p == '\0')				;			/* find end of non-null block */			if (!(q = memchr(p, '\0', end - p)))				q = end;			memmove(dst, p, q - p);			dst += q - p;		}		*dst = '\0';		return dst - buf;	}	return nbytes;}/* Copy at most dsize-1 bytes from src to dst, ensuring dst is null terminated. * Returns dst. */char *str_zcpy(dst, src, dsize)	char *dst;	const char *src;	int dsize;{	if (dsize > 0) {		int len = strlen(src);		if (len >= dsize)			len = dsize - 1;		memcpy(dst, src, len);		dst[len] = '\0';	}	return dst;}/* Like read(2), but if read fails due to non-blocking flag, resets flag * and restarts read. */intblocking_read(fd, buf, nbytes)	int fd;	char *buf;	int nbytes;{	int ret;	int tried_reset = 0;	while ((ret = read(fd, buf, nbytes)) < 0) {		if (!tried_reset && (errno == EAGAIN#ifdef EWOULDBLOCK				     || errno == EWOULDBLOCK#endif /* EWOULDBLOCK */				    ))		{			int oerrno = errno;			if (reset_nonblock(fd) > 0) {				tried_reset = 1;				continue;			}			errno = oerrno;		}		break;	}	return ret;}/* Reset the non-blocking flag on the specified file descriptor. * Returns -1 if there was an error, 0 if non-blocking wasn't set, * 1 if it was. */intreset_nonblock(fd)	int fd;{	int flags;	int blocking_flags;	if ((flags = fcntl(fd, F_GETFL, 0)) < 0)		return -1;	/* With luck, the C compiler will reduce this to a constant */	blocking_flags = 0;#ifdef O_NONBLOCK	blocking_flags |= O_NONBLOCK;#endif /* O_NONBLOCK */#ifdef O_NDELAY	blocking_flags |= O_NDELAY;#else /* O_NDELAY */# ifndef O_NONBLOCK	blocking_flags |= FNDELAY; /* hope this exists... */# endif /* O_NONBLOCK */#endif /* O_NDELAY */	if (!(flags & blocking_flags))		return 0;	flags &= ~blocking_flags;	if (fcntl(fd, F_SETFL, flags) < 0)		return -1;	return 1;}#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif /* HAVE_SYS_PARAM_H */#ifndef MAXPATHLEN# define MAXPATHLEN PATH#endif /* MAXPATHLEN */#ifdef HPUX_GETWD_BUG# include "ksh_dir.h"/* * Work around bug in hpux 10.x C library - getwd/getcwd dump core * if current directory is not readable.  Done in macro 'cause code * is needed in GETWD and GETCWD cases. */# define HPUX_GETWD_BUG_CODE \	{ \	    DIR *d = ksh_opendir("."); \	    if (!d) \		return (char *) 0; \	    closedir(d); \	}#else /* HPUX_GETWD_BUG */# define HPUX_GETWD_BUG_CODE#endif /* HPUX_GETWD_BUG *//* Like getcwd(), except bsize is ignored if buf is 0 (MAXPATHLEN is used) */char *ksh_get_wd(buf, bsize)	char *buf;	int bsize;{#ifdef HAVE_GETCWD	char *b;	char *ret;	/* Before memory allocated */	HPUX_GETWD_BUG_CODE	/* Assume getcwd() available */	if (!buf) {		bsize = MAXPATHLEN;		b = alloc(MAXPATHLEN + 1, ATEMP);	} else		b = buf;	ret = getcwd(b, bsize);	if (!buf) {		if (ret)			ret = aresize(b, strlen(b) + 1, ATEMP);		else			afree(b, ATEMP);	}	return ret;#else /* HAVE_GETCWD */	extern char *getwd ARGS((char *));	char *b;	int len;	/* Before memory allocated */	HPUX_GETWD_BUG_CODE	if (buf && bsize > MAXPATHLEN)		b = buf;	else		b = alloc(MAXPATHLEN + 1, ATEMP);	if (!getwd(b)) {		errno = EACCES;		if (b != buf)			afree(b, ATEMP);		return (char *) 0;	}	len = strlen(b) + 1;	if (!buf)		b = aresize(b, len, ATEMP);	else if (buf != b) {		if (len > bsize) {			errno = ERANGE;			return (char *) 0;		}		memcpy(buf, b, len);		afree(b, ATEMP);		b = buf;	}	return b;#endif /* HAVE_GETCWD */}

⌨️ 快捷键说明

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