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

📄 dpchk.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"cc.h"#include	"y.tab.h"enum{	Fnone	= 0,	Fl,	Fvl,	Fignor,	Fstar,	Fadj,	Fverb	= 10,};typedef	struct	Tprot	Tprot;struct	Tprot{	Type*	type;	Bits	flag;	Tprot*	link;};typedef	struct	Tname	Tname;struct	Tname{	char*	name;	int	param;	Tname*	link;};static	Type*	indchar;static	uchar	flagbits[512];static	char	fmtbuf[100];static	int	lastadj;static	int	lastverb;static	int	nstar;static	Tprot*	tprot;static	Tname*	tname;voidargflag(int c, int v){	switch(v) {	case Fignor:	case Fstar:	case Fl:	case Fvl:		flagbits[c] = v;		break;	case Fverb:		flagbits[c] = lastverb;/*print("flag-v %c %d\n", c, lastadj);*/		lastverb++;		break;	case Fadj:		flagbits[c] = lastadj;/*print("flag-l %c %d\n", c, lastadj);*/		lastadj++;		break;	}}Bitsgetflag(char *s){	Bits flag;	int f;	char *fmt;	Rune c;	fmt = fmtbuf;	flag = zbits;	nstar = 0;	for(;;) {		s += chartorune(&c, s);		if(c == 0 || c >= nelem(flagbits))			break;		fmt += runetochar(fmt, &c);		f = flagbits[c];		switch(f) {		case Fnone:			argflag(c, Fverb);			f = flagbits[c];			break;		case Fstar:			nstar++;		case Fignor:			continue;		case Fl:			if(bset(flag, Fl))				flag = bor(flag, blsh(Fvl));		}		flag = bor(flag, blsh(f));		if(f >= Fverb)			break;	}	*fmt = 0;	return flag;}voidnewprot(Sym *m, Type *t, char *s){	Bits flag;	Tprot *l;	if(t == T) {		warn(Z, "%s: newprot: type not defined", m->name);		return;	}	flag = getflag(s);	for(l=tprot; l; l=l->link)		if(beq(flag, l->flag) && sametype(t, l->type))			return;	l = alloc(sizeof(*l));	l->type = t;	l->flag = flag;	l->link = tprot;	tprot = l;}voidnewname(char *s, int p){	Tname *l;	for(l=tname; l; l=l->link)		if(strcmp(l->name, s) == 0) {			if(l->param != p)				yyerror("vargck %s already defined\n", s);			return;		}	l = alloc(sizeof(*l));	l->name = s;	l->param = p;	l->link = tname;	tname = l;}voidarginit(void){	int i;/* debug['F'] = 1;*//* debug['w'] = 1;*/	lastadj = Fadj;	lastverb = Fverb;	indchar = typ(TIND, types[TCHAR]);	memset(flagbits, Fnone, sizeof(flagbits));	for(i='0'; i<='9'; i++)		argflag(i, Fignor);	argflag('.', Fignor);	argflag('#', Fignor);	argflag('u', Fignor);	argflag('+', Fignor);	argflag('-', Fignor);	argflag('*', Fstar);	argflag('l', Fl);	argflag('o', Fverb);	flagbits['x'] = flagbits['o'];	flagbits['X'] = flagbits['o'];}voidpragvararg(void){	Sym *s;	int n, c;	char *t;	Rune r;	Type *ty;	if(!debug['F'])		goto out;	s = getsym();	if(s && strcmp(s->name, "argpos") == 0)		goto ckpos;	if(s && strcmp(s->name, "type") == 0)		goto cktype;	if(s && strcmp(s->name, "flag") == 0)		goto ckflag;	yyerror("syntax in #pragma varargck");	goto out;ckpos:/*#pragma	varargck	argpos	warn	2*/	s = getsym();	if(s == S)		goto bad;	n = getnsn();	if(n < 0)		goto bad;	newname(s->name, n);	goto out;ckflag:/*#pragma	varargck	flag	'c'*/	c = getnsc();	if(c != '\'')		goto bad;	c = getr();	if(c == '\\')		c = getr();	else if(c == '\'')		goto bad;	if(c == '\n')		goto bad;	if(getc() != '\'')		goto bad;	argflag(c, Fignor);	goto out;cktype:/*#pragma	varargck	type	O	int*/	c = getnsc();	if(c != '"')		goto bad;	t = fmtbuf;	for(;;) {		r = getr();		if(r == ' ' || r == '\n')			goto bad;		if(r == '"')			break;		t += runetochar(t, &r);	}	*t = 0;	t = strdup(fmtbuf);	s = getsym();	if(s == S)		goto bad;	ty = s->type;	while((c = getnsc()) == '*')		ty = typ(TIND, ty);	unget(c);	newprot(s, ty, t);	goto out;bad:	yyerror("syntax in #pragma varargck");out:	while(getnsc() != '\n')		;}Node*nextarg(Node *n, Node **a){	if(n == Z) {		*a = Z;		return Z;	}	if(n->op == OLIST) {		*a = n->left;		return n->right;	}	*a = n;	return Z;}voidcheckargs(Node *nn, char *s, int pos){	Node *a, *n;	Bits flag;	Tprot *l;	if(!debug['F'])		return;	n = nn;	for(;;) {		s = strchr(s, '%');		if(s == 0) {			nextarg(n, &a);			if(a != Z)				warn(nn, "more arguments than format %T",					a->type);			return;		}		s++;		flag = getflag(s);		while(nstar > 0) {			n = nextarg(n, &a);			pos++;			nstar--;			if(a == Z) {				warn(nn, "more format than arguments %s",					fmtbuf);				return;			}			if(a->type == T)				continue;			if(!sametype(types[TINT], a->type) &&			   !sametype(types[TUINT], a->type))				warn(nn, "format mismatch '*' in %s %T, arg %d",					fmtbuf, a->type, pos);		}		for(l=tprot; l; l=l->link)			if(sametype(types[TVOID], l->type)) {				if(beq(flag, l->flag)) {					s++;					goto loop;				}			}		n = nextarg(n, &a);		pos++;		if(a == Z) {			warn(nn, "more format than arguments %s",				fmtbuf);			return;		}		if(a->type == 0)			continue;		for(l=tprot; l; l=l->link)			if(sametype(a->type, l->type)) {/*print("checking %T/%ulx %T/%ulx\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/				if(beq(flag, l->flag))					goto loop;			}		warn(nn, "format mismatch %s %T, arg %d", fmtbuf, a->type, pos);	loop:;	}}voiddpcheck(Node *n){	char *s;	Node *a, *b;	Tname *l;	int i;	if(n == Z)		return;	b = n->left;	if(b == Z || b->op != ONAME)		return;	s = b->sym->name;	for(l=tname; l; l=l->link)		if(strcmp(s, l->name) == 0)			break;	if(l == 0)		return;	i = l->param;	b = n->right;	while(i > 0) {		b = nextarg(b, &a);		i--;	}	if(a == Z) {		warn(n, "cant find format arg");		return;	}	if(!sametype(indchar, a->type)) {		warn(n, "format arg type %T", a->type);		return;	}	if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {/*		warn(n, "format arg not constant string");*/		return;	}	s = a->left->cstring;	checkargs(b, s, l->param);}voidpragpack(void){	Sym *s;	packflg = 0;	s = getsym();	if(s) {		packflg = atoi(s->name+1);		if(strcmp(s->name, "on") == 0 ||		   strcmp(s->name, "yes") == 0)			packflg = 1;	}	while(getnsc() != '\n')		;	if(debug['f'])		if(packflg)			print("%4ld: pack %d\n", lineno, packflg);		else			print("%4ld: pack off\n", lineno);}voidpragfpround(void){	Sym *s;	fproundflg = 0;	s = getsym();	if(s) {		fproundflg = atoi(s->name+1);		if(strcmp(s->name, "on") == 0 ||		   strcmp(s->name, "yes") == 0)			fproundflg = 1;	}	while(getnsc() != '\n')		;	if(debug['f'])		if(fproundflg)			print("%4ld: fproundflg %d\n", lineno, fproundflg);		else			print("%4ld: fproundflg off\n", lineno);}voidpragprofile(void){	Sym *s;	profileflg = 0;	s = getsym();	if(s) {		profileflg = atoi(s->name+1);		if(strcmp(s->name, "on") == 0 ||		   strcmp(s->name, "yes") == 0)			profileflg = 1;	}	while(getnsc() != '\n')		;	if(debug['f'])		if(profileflg)			print("%4ld: profileflg %d\n", lineno, profileflg);		else			print("%4ld: profileflg off\n", lineno);}voidpragincomplete(void){	Sym *s;	s = getsym();	if(s){		if(strcmp(s->name, "_off_") == 0)			debug['T'] = 0;		else if(strcmp(s->name, "_on_") == 0)			debug['T'] = 1;		else if(s->type == T)			diag(Z, "unknown type %s in pragma incomplete", s->name);		else			s->type->garb |= GINCOMPLETE;	}	while(getnsc() != '\n')		;	if(debug['f'])		print("%s incomplete\n", s->name);}

⌨️ 快捷键说明

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