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

📄 builtin.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			s = strnodlen(0, n);			Bread(bp, s->string, n);		}		else			s = strnodlen(p, n-1);		new = al(TSTRING);		new->string = s;		new->fmt = 's';		*l = new;		l = &new->next;	}	Bterm(bp);}voidcvtatof(Node *r, Node *args){	Node res;	if(args == 0)		error("atof(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("atof(string): arg type");	r->op = OCONST;	r->type = TFLOAT;	r->fval = atof(res.string->string);	r->fmt = 'f';}voidcvtatoi(Node *r, Node *args){	Node res;	if(args == 0)		error("atoi(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("atoi(string): arg type");	r->op = OCONST;	r->type = TINT;	r->ival = strtoull(res.string->string, 0, 0);	r->fmt = 'V';}static char *fmtflags = "-0123456789. #,u";static char *fmtverbs = "bdox";static intacidfmt(char *fmt, char *buf, int blen){	char *r, *w, *e;		w = buf;	e = buf+blen;	for(r=fmt; *r; r++){		if(w >= e)			return -1;		if(*r != '%'){			*w++ = *r;			continue;		}		if(*r == '%'){			*w++ = *r++;			if(*r == '%'){				if(w >= e)					return -1;				*w++ = *r;				continue;			}			while(*r && strchr(fmtflags, *r)){				if(w >= e)					return -1;				*w++ = *r++;			}			if(*r == 0 || strchr(fmtverbs, *r) == nil)				return -1;			if(w+3 > e)				return -1;			*w++ = 'l';			*w++ = 'l';			*w++ = *r;		}	}	if(w >= e)		return -1;	*w = 0;	return 0;}voidcvtitoa(Node *r, Node *args){	Node res;	Node *av[Maxarg];	vlong ival;	char buf[128], fmt[32];	if(args == 0)err:		error("itoa(number [, fmt]): arg count");	na = 0;	flatten(av, args);	if(na == 0 || na > 2)		goto err;	expr(av[0], &res);	if(res.type != TINT)		error("itoa(number [, fmt]): arg type");	ival = res.ival;	strncpy(fmt, "%lld", sizeof(fmt));	if(na == 2){		expr(av[1], &res);		if(res.type != TSTRING)			error("itoa(number [, fmt]): fmt type");		if(acidfmt(res.string->string, fmt, sizeof(buf)))			error("itoa(number [, fmt]): malformed fmt");	}	snprint(buf, sizeof(buf), fmt, ival);	r->op = OCONST;	r->type = TSTRING;	r->string = strnode(buf);	r->fmt = 's';}List*mapent(Map *m){	int i;	List *l, *n, **t, *h;	h = 0;	t = &h;	for(i = 0; i < m->nsegs; i++) {		if(m->seg[i].inuse == 0)			continue;		l = al(TSTRING);		n = al(TLIST);		n->l = l;		*t = n;		t = &n->next;		l->string = strnode(m->seg[i].name);		l->fmt = 's';		l->next = al(TINT);		l = l->next;		l->ival = m->seg[i].b;		l->fmt = 'W';		l->next = al(TINT);		l = l->next;		l->ival = m->seg[i].e;		l->fmt = 'W';		l->next = al(TINT);		l = l->next;		l->ival = m->seg[i].f;		l->fmt = 'W';	}	return h;}voidmap(Node *r, Node *args){	int i;	Map *m;	List *l;	char *ent;	Node *av[Maxarg], res;	na = 0;	flatten(av, args);	if(na != 0) {		expr(av[0], &res);		if(res.type != TLIST)			error("map(list): map needs a list");		if(listlen(res.l) != 4)			error("map(list): list must have 4 entries");		l = res.l;		if(l->type != TSTRING)			error("map name must be a string");		ent = l->string->string;		m = symmap;		i = findseg(m, ent);		if(i < 0) {			m = cormap;			i = findseg(m, ent);		}		if(i < 0)			error("%s is not a map entry", ent);			l = l->next;		if(l->type != TINT)			error("map entry not int");		m->seg[i].b = l->ival;		if (strcmp(ent, "text") == 0)			textseg(l->ival, &fhdr);		l = l->next;		if(l->type != TINT)			error("map entry not int");		m->seg[i].e = l->ival;		l = l->next;		if(l->type != TINT)			error("map entry not int");		m->seg[i].f = l->ival;	}	r->type = TLIST;	r->l = 0;	if(symmap)		r->l = mapent(symmap);	if(cormap) {		if(r->l == 0)			r->l = mapent(cormap);		else {			for(l = r->l; l->next; l = l->next)				;			l->next = mapent(cormap);		}	}}void flatten(Node **av, Node *n){	if(n == 0)		return;	switch(n->op) {	case OLIST:		flatten(av, n->left);		flatten(av, n->right);		break;	default:		av[na++] = n;		if(na >= Maxarg)			error("too many function arguments");		break;	}}voidstrace(Node *r, Node *args){	Node *av[Maxarg], *n, res;	uvlong pc, sp;	na = 0;	flatten(av, args);	if(na != 3)		error("strace(pc, sp, link): arg count");	n = av[0];	expr(n, &res);	if(res.type != TINT)		error("strace(pc, sp, link): pc bad type");	pc = res.ival;	n = av[1];	expr(n, &res);	if(res.type != TINT)		error("strace(pc, sp, link): sp bad type");	sp = res.ival;	n = av[2];	expr(n, &res);	if(res.type != TINT)		error("strace(pc, sp, link): link bad type");	tracelist = 0;	if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0)		error("no stack frame: %r");	r->type = TLIST;	r->l = tracelist;}voidregerror(char *msg){	error(msg);}voidregexp(Node *r, Node *args){	Node res;	Reprog *rp;	Node *av[Maxarg];	na = 0;	flatten(av, args);	if(na != 2)		error("regexp(pattern, string): arg count");	expr(av[0], &res);	if(res.type != TSTRING)		error("regexp(pattern, string): pattern must be string");	rp = regcomp(res.string->string);	if(rp == 0)		return;	expr(av[1], &res);	if(res.type != TSTRING)		error("regexp(pattern, string): bad string");	r->fmt = 'D';	r->type = TINT;	r->ival = regexec(rp, res.string->string, 0, 0);	free(rp);}voidfmt(Node *r, Node *args){	Node res;	Node *av[Maxarg];	na = 0;	flatten(av, args);	if(na != 2)		error("fmt(obj, fmt): arg count");	expr(av[1], &res);	if(res.type != TINT || strchr(vfmt, res.ival) == 0)		error("fmt(obj, fmt): bad format '%c'", (char)res.ival);	expr(av[0], r);	r->fmt = res.ival;}voidpatom(char type, Store *res){	int i;	char buf[512];	extern char *typenames[];	switch(res->fmt) {	case 'c':		Bprint(bout, "%c", (int)res->ival);		break;	case 'C':		if(res->ival < ' ' || res->ival >= 0x7f)			Bprint(bout, "%3d", (int)res->ival&0xff);		else			Bprint(bout, "%3c", (int)res->ival);		break;	case 'r':		Bprint(bout, "%C", (int)res->ival);		break;	case 'B':		memset(buf, '0', 34);		buf[1] = 'b';		for(i = 0; i < 32; i++) {			if(res->ival & (1<<i))				buf[33-i] = '1';		}		buf[35] = '\0';		Bprint(bout, "%s", buf);		break;	case 'b':		Bprint(bout, "%.2x", (int)res->ival&0xff);		break;	case 'X':		Bprint(bout, "%.8lux", (ulong)res->ival);		break;	case 'x':		Bprint(bout, "%.4lux", (ulong)res->ival&0xffff);		break;	case 'D':		Bprint(bout, "%d", (int)res->ival);		break;	case 'd':		Bprint(bout, "%d", (ushort)res->ival);		break;	case 'u':		Bprint(bout, "%d", (int)res->ival&0xffff);		break;	case 'U':		Bprint(bout, "%lud", (ulong)res->ival);		break;	case 'Z':		Bprint(bout, "%llud", res->ival);		break;	case 'V':		Bprint(bout, "%lld", res->ival);		break;	case 'W':		Bprint(bout, "%.8llux", res->ival);		break;	case 'Y':		Bprint(bout, "%.16llux", res->ival);		break;	case 'o':		Bprint(bout, "0%.11uo", (int)res->ival&0xffff);		break;	case 'O':		Bprint(bout, "0%.6uo", (int)res->ival);		break;	case 'q':		Bprint(bout, "0%.11o", (short)(res->ival&0xffff));		break;	case 'Q':		Bprint(bout, "0%.6o", (int)res->ival);		break;	case 'f':	case 'F':		if(type != TFLOAT)			Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);		else			Bprint(bout, "%g", res->fval);		break;	case 's':	case 'g':	case 'G':		if(type != TSTRING)			Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);		else			Bwrite(bout, res->string->string, res->string->len);		break;	case 'R':		if(type != TSTRING)			Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);		else			Bprint(bout, "%S", (Rune*)res->string->string);		break;	case 'a':	case 'A':		symoff(buf, sizeof(buf), res->ival, CANY);		Bprint(bout, "%s", buf);		break;	case 'I':	case 'i':		if(type != TINT)			Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);		else {			if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0)				Bprint(bout, "no instruction");			else				Bprint(bout, "%s", buf);		}		break;	}}voidblprint(List *l){	Bprint(bout, "{");	while(l) {		switch(l->type) {		default:			patom(l->type, &l->Store);			break;		case TSTRING:			Bputc(bout, '"');			patom(l->type, &l->Store);			Bputc(bout, '"');			break;		case TLIST:			blprint(l->l);			break;		case TCODE:			pcode(l->cc, 0);			break;		}		l = l->next;		if(l)			Bprint(bout, ", ");	}	Bprint(bout, "}");}intcomx(Node res){	Lsym *sl;	Node *n, xx;	if(res.fmt != 'a' && res.fmt != 'A')		return 0;	if(res.comt == 0 || res.comt->base == 0)		return 0;	sl = res.comt->base;	if(sl->proc) {		res.left = ZN;		res.right = ZN;		n = an(ONAME, ZN, ZN);		n->sym = sl;		n = an(OCALL, n, &res);			n->left->sym = sl;		expr(n, &xx);		return 1;	}	print("(%s)", sl->name);	return 0;}voidbprint(Node *r, Node *args){	int i, nas;	Node res, *av[Maxarg];	USED(r);	na = 0;	flatten(av, args);	nas = na;	for(i = 0; i < nas; i++) {		expr(av[i], &res);		switch(res.type) {		default:			if(comx(res))				break;			patom(res.type, &res.Store);			break;		case TCODE:			pcode(res.cc, 0);			break;		case TLIST:			blprint(res.l);			break;		}	}	if(ret == 0)		Bputc(bout, '\n');}voidprintto(Node *r, Node *args){	int fd;	Biobuf *b;	int i, nas;	Node res, *av[Maxarg];	USED(r);	na = 0;	flatten(av, args);	nas = na;	expr(av[0], &res);	if(res.type != TSTRING)		error("printto(string, ...): need string");	fd = create(res.string->string, OWRITE, 0666);	if(fd < 0)		fd = open(res.string->string, OWRITE);	if(fd < 0)		error("printto: open %s: %r", res.string->string);	b = gmalloc(sizeof(Biobuf));	Binit(b, fd, OWRITE);	Bflush(bout);	io[iop++] = bout;	bout = b;	for(i = 1; i < nas; i++) {		expr(av[i], &res);		switch(res.type) {		default:			if(comx(res))				break;			patom(res.type, &res.Store);			break;		case TLIST:			blprint(res.l);			break;		}	}	if(ret == 0)		Bputc(bout, '\n');	Bterm(b);	close(fd);	free(b);	bout = io[--iop];}voidpcfile(Node *r, Node *args){	Node res;	char *p, buf[128];	if(args == 0)		error("pcfile(addr): arg count");	expr(args, &res);	if(res.type != TINT)		error("pcfile(addr): arg type");	r->type = TSTRING;	r->fmt = 's';	if(fileline(buf, sizeof(buf), res.ival) == 0) {		r->string = strnode("?file?");		return;	}	p = strrchr(buf, ':');	if(p == 0)		error("pcfile(addr): funny file %s", buf);	*p = '\0';	r->string = strnode(buf);	}voidpcline(Node *r, Node *args){	Node res;	char *p, buf[128];	if(args == 0)		error("pcline(addr): arg count");	expr(args, &res);	if(res.type != TINT)		error("pcline(addr): arg type");	r->type = TINT;	r->fmt = 'D';	if(fileline(buf, sizeof(buf), res.ival) == 0) {		r->ival = 0;		return;	}	p = strrchr(buf, ':');	if(p == 0)		error("pcline(addr): funny file %s", buf);	r->ival = strtol(p+1, 0, 0);	}

⌨️ 快捷键说明

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