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

📄 macbody

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻
字号:
#define VARMAC 0x80longgetnsn(void){	long n;	int c;	c = getnsc();	if(c < '0' || c > '9')		return -1;	n = 0;	while(c >= '0' && c <= '9') {		n = n*10 + c-'0';		c = getc();	}	unget(c);	return n;}Sym*getsym(void){	int c;	char *cp;	c = getnsc();	if(!isalpha(c) && c != '_') {		unget(c);		return S;	}	for(cp = symb;;) {		if(cp <= symb+NSYMB-4)			*cp++ = c;		c = getc();		if(isalnum(c) || c == '_')			continue;		unget(c);		break;	}	*cp = 0;	if(cp > symb+NSYMB-4)		yyerror("symbol too large: %s", symb);	return lookup();}Sym*getsymdots(int *dots){	int c;	Sym *s;	s = getsym();	if(s != S)		return s;	c = getnsc();	if(c != '.'){		unget(c);		return S;	}	if(getc() != '.' || getc() != '.')		yyerror("bad dots in macro");	*dots = 1;	return slookup("__VA_ARGS__");}intgetcom(void){	int c;	for(;;) {		c = getnsc();		if(c != '/')			break;		c = getc();		if(c == '/') {			while(c != '\n')				c = getc();			break;		}		if(c != '*')			break;		c = getc();		for(;;) {			if(c == '*') {				c = getc();				if(c != '/')					continue;				c = getc();				break;			}			if(c == '\n') {				yyerror("comment across newline");				break;			}			c = getc();		}		if(c == '\n')			break;	}	return c;}voiddodefine(char *cp){	Sym *s;	char *p;	long l;	strcpy(symb, cp);	p = strchr(symb, '=');	if(p) {		*p++ = 0;		s = lookup();		l = strlen(p) + 2;	/* +1 null, +1 nargs */		while(l & 3)			l++;		while(nhunk < l)			gethunk();		*hunk = 0;		strcpy(hunk+1, p);		s->macro = hunk;		hunk += l;		nhunk -= l;	} else {		s = lookup();		s->macro = "\0001";	/* \000 is nargs */	}	if(debug['m'])		print("#define (-D) %s %s\n", s->name, s->macro+1);}struct{	char	*macname;	void	(*macf)(void);} mactab[] ={	"ifdef",	0,	/* macif(0) */	"ifndef",	0,	/* macif(1) */	"else",		0,	/* macif(2) */	"line",		maclin,	"define",	macdef,	"include",	macinc,	"undef",	macund,	"pragma",	macprag,	"endif",	macend,	0};voiddomacro(void){	int i;	Sym *s;	s = getsym();	if(s == S)		s = slookup("endif");	for(i=0; mactab[i].macname; i++)		if(strcmp(s->name, mactab[i].macname) == 0) {			if(mactab[i].macf)				(*mactab[i].macf)();			else				macif(i);			return;		}	yyerror("unknown #: %s", s->name);	macend();}voidmacund(void){	Sym *s;	s = getsym();	macend();	if(s == S) {		yyerror("syntax in #undef");		return;	}	s->macro = 0;}#define	NARG	25voidmacdef(void){	Sym *s, *a;	char *args[NARG], *np, *base;	int n, i, c, len, dots;	int ischr;	s = getsym();	if(s == S)		goto bad;	if(s->macro)		yyerror("macro redefined: %s", s->name);	c = getc();	n = -1;	dots = 0;	if(c == '(') {		n++;		c = getnsc();		if(c != ')') {			unget(c);			for(;;) {				a = getsymdots(&dots);				if(a == S)					goto bad;				if(n >= NARG) {					yyerror("too many arguments in #define: %s", s->name);					goto bad;				}				args[n++] = a->name;				c = getnsc();				if(c == ')')					break;				if(c != ',' || dots)					goto bad;			}		}		c = getc();	}	if(isspace(c))		if(c != '\n')			c = getnsc();	base = hunk;	len = 1;	ischr = 0;	for(;;) {		if(isalpha(c) || c == '_') {			np = symb;			*np++ = c;			c = getc();			while(isalnum(c) || c == '_') {				*np++ = c;				c = getc();			}			*np = 0;			for(i=0; i<n; i++)				if(strcmp(symb, args[i]) == 0)					break;			if(i >= n) {				i = strlen(symb);				base = allocn(base, len, i);				memcpy(base+len, symb, i);				len += i;				continue;			}			base = allocn(base, len, 2);			base[len++] = '#';			base[len++] = 'a' + i;			continue;		}		if(ischr){			if(c == '\\'){ 				base = allocn(base, len, 1);				base[len++] = c;				c = getc();			}else if(c == ischr)				ischr = 0;		}else{			if(c == '"' || c == '\''){				base = allocn(base, len, 1);				base[len++] = c;				ischr = c;				c = getc();				continue;			}			if(c == '/') {				c = getc();				if(c == '/'){					c = getc();					for(;;) {						if(c == '\n')							break;						c = getc();					}					continue;				}				if(c == '*'){					c = getc();					for(;;) {						if(c == '*') {							c = getc();							if(c != '/')								continue;							c = getc();							break;						}						if(c == '\n') {							yyerror("comment and newline in define: %s", s->name);							break;						}						c = getc();					}					continue;				}				base = allocn(base, len, 1);				base[len++] = '/';				continue;			}		}		if(c == '\\') {			c = getc();			if(c == '\n') {				c = getc();				continue;			}			else if(c == '\r') {				c = getc();				if(c == '\n') {					c = getc();					continue;				}			}			base = allocn(base, len, 1);			base[len++] = '\\';			continue;		}		if(c == '\n')			break;		if(c == '#')		if(n > 0) {			base = allocn(base, len, 1);			base[len++] = c;		}		base = allocn(base, len, 1);		base[len++] = c;		c = ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff));		if(c == '\n')			lineno++;		if(c == -1) {			yyerror("eof in a macro: %s", s->name);			break;		}	}	do {		base = allocn(base, len, 1);		base[len++] = 0;	} while(len & 3);	*base = n+1;	if(dots)		*base |= VARMAC;	s->macro = base;	if(debug['m'])		print("#define %s %s\n", s->name, s->macro+1);	return;bad:	if(s == S)		yyerror("syntax in #define");	else		yyerror("syntax in #define: %s", s->name);	macend();}voidmacexpand(Sym *s, char *b){	char buf[2000];	int n, l, c, nargs;	char *arg[NARG], *cp, *ob, *ecp, dots;	ob = b;	if(*s->macro == 0) {		strcpy(b, s->macro+1);		if(debug['m'])			print("#expand %s %s\n", s->name, ob);		return;	}		nargs = (char)(*s->macro & ~VARMAC) - 1;	dots = *s->macro & VARMAC;	c = getnsc();	if(c != '(')		goto bad;	n = 0;	c = getc();	if(c != ')') {		unget(c);		l = 0;		cp = buf;		ecp = cp + sizeof(buf)-4;		arg[n++] = cp;		for(;;) {			if(cp >= ecp)				goto toobig;			c = getc();			if(c == '"')				for(;;) {					if(cp >= ecp)						goto toobig;					*cp++ = c;					c = getc();					if(c == '\\') {						*cp++ = c;						c = getc();						continue;					}					if(c == '\n')						goto bad;					if(c == '"')						break;				}			if(c == '\'')				for(;;) {					if(cp >= ecp)						goto toobig;					*cp++ = c;					c = getc();					if(c == '\\') {						*cp++ = c;						c = getc();						continue;					}					if(c == '\n')						goto bad;					if(c == '\'')						break;				}			if(c == '/') {				c = getc();				switch(c) {				case '*':					for(;;) {						c = getc();						if(c == '*') {							c = getc();							if(c == '/')								break;						}					}					*cp++ = ' ';					continue;				case '/':					while((c = getc()) != '\n')						;					break;				default:					unget(c);					c = '/';				}			}			if(l == 0) {				if(c == ',') {					if(n == nargs && dots) {						*cp++ = ',';						continue;					}					*cp++ = 0;					arg[n++] = cp;					if(n > nargs)						break;					continue;				}				if(c == ')')					break;			}			if(c == '\n')				c = ' ';			*cp++ = c;			if(c == '(')				l++;			if(c == ')')				l--;		}		*cp = 0;	}	if(n != nargs) {		yyerror("argument mismatch expanding: %s", s->name);		*b = 0;		return;	}	cp = s->macro+1;	for(;;) {		c = *cp++;		if(c == '\n')			c = ' ';		if(c != '#') {			*b++ = c;			if(c == 0)				break;			continue;		}		c = *cp++;		if(c == 0)			goto bad;		if(c == '#') {			*b++ = c;			continue;		}		c -= 'a';		if(c < 0 || c >= n)			continue;		strcpy(b, arg[c]);		b += strlen(arg[c]);	}	*b = 0;	if(debug['m'])		print("#expand %s %s\n", s->name, ob);	return;bad:	yyerror("syntax in macro expansion: %s", s->name);	*b = 0;	return;toobig:	yyerror("too much text in macro expansion: %s", s->name);	*b = 0;}voidmacinc(void){	int c0, c, i, f;	char str[STRINGSZ], *hp;	c0 = getnsc();	if(c0 != '"') {		c = c0;		if(c0 != '<')			goto bad;		c0 = '>';	}	for(hp = str;;) {		c = getc();		if(c == c0)			break;		if(c == '\n')			goto bad;		*hp++ = c;	}	*hp = 0;	c = getcom();	if(c != '\n')		goto bad;	f = -1;	for(i=0; i<ninclude; i++) {		if(i == 0 && c0 == '>')			continue;		strcpy(symb, include[i]);		strcat(symb, "/");		if(strcmp(symb, "./") == 0)			symb[0] = 0;		strcat(symb, str);		f = open(symb, 0);		if(f >= 0)			break;	}	if(f < 0)		strcpy(symb, str);	c = strlen(symb) + 1;	while(c & 3)		c++;	while(nhunk < c)		gethunk();	hp = hunk;	memcpy(hunk, symb, c);	nhunk -= c;	hunk += c;	newio();	pushio();	newfile(hp, f);	return;bad:	unget(c);	yyerror("syntax in #include");	macend();}voidmaclin(void){	char *cp;	int c;	long n;	n = getnsn();	c = getc();	if(n < 0)		goto bad;	for(;;) {		if(c == ' ' || c == '\t') {			c = getc();			continue;		}		if(c == '"')			break;		if(c == '\n') {			strcpy(symb, "<noname>");			goto nn;		}		goto bad;	}	cp = symb;	for(;;) {		c = getc();		if(c == '"')			break;		*cp++ = c;	}	*cp = 0;	c = getcom();	if(c != '\n')		goto bad;nn:	c = strlen(symb) + 1;	while(c & 3)		c++;	while(nhunk < c)		gethunk();	cp = hunk;	memcpy(hunk, symb, c);	nhunk -= c;	hunk += c;	linehist(cp, n);	return;bad:	unget(c);	yyerror("syntax in #line");	macend();}voidmacif(int f){	int c, l, bol;	Sym *s;	if(f == 2)		goto skip;	s = getsym();	if(s == S)		goto bad;	if(getcom() != '\n')		goto bad;	if((s->macro != 0) ^ f)		return;skip:	bol = 1;	l = 0;	for(;;) {		c = getc();		if(c != '#') {			if(!isspace(c))				bol = 0;			if(c == '\n')				bol = 1;			continue;		}		if(!bol)			continue;		s = getsym();		if(s == S)			continue;		if(strcmp(s->name, "endif") == 0) {			if(l) {				l--;				continue;			}			macend();			return;		}		if(strcmp(s->name, "ifdef") == 0 || strcmp(s->name, "ifndef") == 0) {			l++;			continue;		}		if(l == 0 && f != 2 && strcmp(s->name, "else") == 0) {			macend();			return;		}	}bad:	yyerror("syntax in #if(n)def");	macend();}voidmacprag(void){	Sym *s;	int c0, c;	char *hp;	Hist *h;	s = getsym();	if(s && strcmp(s->name, "lib") == 0)		goto praglib;	if(s && strcmp(s->name, "pack") == 0) {		pragpack();		return;	}	if(s && strcmp(s->name, "fpround") == 0) {		pragfpround();		return;	}	if(s && strcmp(s->name, "profile") == 0) {		pragprofile();		return;	}	if(s && strcmp(s->name, "varargck") == 0) {		pragvararg();		return;	}	if(s && strcmp(s->name, "incomplete") == 0) {		pragincomplete();		return;	}	while(getnsc() != '\n')		;	return;praglib:	c0 = getnsc();	if(c0 != '"') {		c = c0;		if(c0 != '<')			goto bad;		c0 = '>';	}	for(hp = symb;;) {		c = getc();		if(c == c0)			break;		if(c == '\n')			goto bad;		*hp++ = c;	}	*hp = 0;	c = getcom();	if(c != '\n')		goto bad;	/*	 * put pragma-line in as a funny history 	 */	c = strlen(symb) + 1;	while(c & 3)		c++;	while(nhunk < c)		gethunk();	hp = hunk;	memcpy(hunk, symb, c);	nhunk -= c;	hunk += c;	h = alloc(sizeof(Hist));	h->name = hp;	h->line = lineno;	h->offset = -1;	h->link = H;	if(ehist == H) {		hist = h;		ehist = h;		return;	}	ehist->link = h;	ehist = h;	return;bad:	unget(c);	yyerror("syntax in #pragma lib");	macend();}voidmacend(void){	int c;	for(;;) {		c = getnsc();		if(c < 0 || c == '\n')			return;	}}voidlinehist(char *f, int offset){	Hist *h;	/*	 * overwrite the last #line directive if	 * no alloc has happened since the last one	 */	if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0)		if(f && ehist->name && strcmp(f, ehist->name) == 0) {			ehist->line = lineno;			ehist->offset = offset;			return;		}	if(debug['f'])		if(f) {			if(offset)				print("%4ld: %s (#line %d)\n", lineno, f, offset);			else				print("%4ld: %s\n", lineno, f);		} else			print("%4ld: <pop>\n", lineno);	newflag = 0;	h = alloc(sizeof(Hist));	h->name = f;	h->line = lineno;	h->offset = offset;	h->link = H;	if(ehist == H) {		hist = h;		ehist = h;		return;	}	ehist->link = h;	ehist = h;}voidgethunk(void){	char *h;	long nh;	nh = NHUNK;	if(thunk >= 10L*NHUNK)		nh = 10L*NHUNK;	h = (char*)mysbrk(nh);	if(h == (char*)-1) {		yyerror("out of memory");		errorexit();	}	hunk = h;	nhunk = nh;	thunk += nh;}

⌨️ 快捷键说明

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