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

📄 sym.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/***** spin: sym.c *****//* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories.     *//* All Rights Reserved.  This software is for educational purposes only.  *//* No guarantee whatsoever is expressed or implied by the distribution of *//* this code.  Permission is given to distribute this code provided that  *//* this introductory message is not removed and no monies are exchanged.  *//* Software written by Gerard J. Holzmann.  For tool documentation see:   *//*             http://spinroot.com/                                       *//* Send all bug-reports and/or questions to: bugs@spinroot.com            */#include "spin.h"#ifdef PC#include "y_tab.h"#else#include "y.tab.h"#endifextern Symbol	*Fname, *owner;extern int	lineno, depth, verbose, NamesNotAdded, deadvar;extern short	has_xu;Symbol	*context = ZS;Ordered	*all_names = (Ordered *)0;int	Nid = 0;static Ordered	*last_name = (Ordered *)0;static Symbol	*symtab[Nhash+1];static intsamename(Symbol *a, Symbol *b){	if (!a && !b) return 1;	if (!a || !b) return 0;	return !strcmp(a->name, b->name);}inthash(char *s){	int h=0;	while (*s)	{	h += *s++;		h <<= 1;		if (h&(Nhash+1))			h |= 1;	}	return h&Nhash;}Symbol *lookup(char *s){	Symbol *sp; Ordered *no;	int h = hash(s);	for (sp = symtab[h]; sp; sp = sp->next)		if (strcmp(sp->name, s) == 0		&&  samename(sp->context, context)		&&  samename(sp->owner, owner))			return sp;		/* found */	if (context)				/* in proctype */	for (sp = symtab[h]; sp; sp = sp->next)		if (strcmp(sp->name, s) == 0		&& !sp->context		&&  samename(sp->owner, owner))			return sp;		/* global */	sp = (Symbol *) emalloc(sizeof(Symbol));	sp->name = (char *) emalloc((int) strlen(s) + 1);	strcpy(sp->name, s);	sp->nel = 1;	sp->setat = depth;	sp->context = context;	sp->owner = owner;			/* if fld in struct */	if (NamesNotAdded == 0)	{	sp->next = symtab[h];		symtab[h] = sp;		no = (Ordered *) emalloc(sizeof(Ordered));		no->entry = sp;		if (!last_name)			last_name = all_names = no;		else		{	last_name->next = no;			last_name = no;	}	}	return sp;}voidtrackvar(Lextok *n, Lextok *m){	Symbol *sp = n->sym;	if (!sp) return;	/* a structure list */	switch (m->ntyp) {	case NAME:		if (m->sym->type != BIT)		{	sp->hidden |= 4;			if (m->sym->type != BYTE)				sp->hidden |= 8;		}		break;	case CONST:		if (m->val != 0 && m->val != 1)			sp->hidden |= 4;		if (m->val < 0 || m->val > 256)			sp->hidden |= 8; /* ditto byte-equiv */		break;	default:	/* unknown */		sp->hidden |= (4|8); /* not known bit-equiv */	}}Lextok *runstmnts = ZN;voidtrackrun(Lextok *n){	runstmnts = nn(ZN, 0, n, runstmnts);}voidcheckrun(Symbol *parnm, int posno){	Lextok *n, *now, *v; int i, m;	int res = 0; char buf[16], buf2[16];	for (n = runstmnts; n; n = n->rgt)	{	now = n->lft;		if (now->sym != parnm->context)			continue;		for (v = now->lft, i = 0; v; v = v->rgt, i++)			if (i == posno)			{	m = v->lft->ntyp;				if (m == CONST)				{	m = v->lft->val;					if (m != 0 && m != 1)						res |= 4;					if (m < 0 || m > 256)						res |= 8;				} else if (m == NAME)				{	m = v->lft->sym->type;					if (m != BIT)					{	res |= 4;						if (m != BYTE)							res |= 8;					}				} else					res |= (4|8); /* unknown */				break;	}		}	if (!(res&4) || !(res&8))	{	if (!(verbose&32)) return;		strcpy(buf2, (!(res&4))?"bit":"byte");		sputtype(buf, parnm->type);		i = (int) strlen(buf);		while (buf[--i] == ' ') buf[i] = '\0';		if (strcmp(buf, buf2) == 0) return;		prehint(parnm);		printf("proctype %s, '%s %s' could be declared",			parnm->context->name, buf, parnm->name);		printf(" '%s %s'\n", buf2, parnm->name);	}}voidtrackchanuse(Lextok *m, Lextok *w, int t){	Lextok *n = m; int cnt = 1;	while (n)	{	if (n->lft		&&  n->lft->sym		&&  n->lft->sym->type == CHAN)			setaccess(n->lft->sym, w?w->sym:ZS, cnt, t);		n = n->rgt; cnt++;	}}voidsetptype(Lextok *n, int t, Lextok *vis)	/* predefined types */{	int oln = lineno, cnt = 1; extern int Expand_Ok;	while (n)	{	if (n->sym->type && !(n->sym->hidden&32))		{ lineno = n->ln; Fname = n->fn;		  non_fatal("redeclaration of '%s'", n->sym->name);		  lineno = oln;		}		n->sym->type = (short) t;		if (Expand_Ok)		{	n->sym->hidden |= (4|8|16); /* formal par */			if (t == CHAN)			setaccess(n->sym, ZS, cnt, 'F');		}		if (t == UNSIGNED)		{	if (n->sym->nbits < 0)			fatal("(%s) has invalid width-field", n->sym->name);			if (n->sym->nbits == 0)			{	n->sym->nbits = 16;				non_fatal("unsigned without width-field", 0);			}		} else if (n->sym->nbits > 0)		{	non_fatal("(%s) only an unsigned can have width-field",				n->sym->name);		}		if (vis)		{	if (strncmp(vis->sym->name, ":hide:", 6) == 0)			{	n->sym->hidden |= 1;				if (t == BIT)				fatal("bit variable (%s) cannot be hidden",					n->sym->name);			} else if (strncmp(vis->sym->name, ":show:", 6) == 0)			{	n->sym->hidden |= 2;			} else if (strncmp(vis->sym->name, ":local:", 7) == 0)			{	n->sym->hidden |= 64;			}		}		if (t == CHAN)			n->sym->Nid = ++Nid;		else		{	n->sym->Nid = 0;			if (n->sym->ini			&&  n->sym->ini->ntyp == CHAN)			{	Fname = n->fn;				lineno = n->ln;				fatal("chan initializer for non-channel %s",				n->sym->name);			}		}		if (n->sym->nel <= 0)		{ lineno = n->ln; Fname = n->fn;		  non_fatal("bad array size for '%s'", n->sym->name);		  lineno = oln;		}		n = n->rgt; cnt++;	}}static voidsetonexu(Symbol *sp, int t){	sp->xu |= t;	if (t == XR || t == XS)	{	if (sp->xup[t-1]		&&  strcmp(sp->xup[t-1]->name, context->name))		{	printf("error: x[rs] claims from %s and %s\n",				sp->xup[t-1]->name, context->name);			non_fatal("conflicting claims on chan '%s'",				sp->name);		}		sp->xup[t-1] = context;	}}static voidsetallxu(Lextok *n, int t){	Lextok *fp, *tl;	for (fp = n; fp; fp = fp->rgt)	for (tl = fp->lft; tl; tl = tl->rgt)	{	if (tl->sym->type == STRUCT)			setallxu(tl->sym->Slst, t);		else if (tl->sym->type == CHAN)			setonexu(tl->sym, t);	}}Lextok *Xu_List = (Lextok *) 0;voidsetxus(Lextok *p, int t){	Lextok *m, *n;	has_xu = 1; 	if (!context)	{	lineno = p->ln;		Fname = p->fn;		non_fatal("non-local x[rs] assertion", (char *)0);	}	for (m = p; m; m = m->rgt)	{	Lextok *Xu_new = (Lextok *) emalloc(sizeof(Lextok));		Xu_new->val = t;		Xu_new->lft = m->lft;		Xu_new->sym = context;		Xu_new->rgt = Xu_List;		Xu_List = Xu_new;		n = m->lft;		if (n->sym->type == STRUCT)			setallxu(n->sym->Slst, t);		else if (n->sym->type == CHAN)			setonexu(n->sym, t);		else		{	int oln = lineno;			lineno = n->ln; Fname = n->fn;			non_fatal("xr or xs of non-chan '%s'",				n->sym->name);			lineno = oln;		}	}}Lextok *Mtype = (Lextok *) 0;voidsetmtype(Lextok *m){	Lextok *n;	int cnt, oln = lineno;	if (m) { lineno = m->ln; Fname = m->fn; }	if (!Mtype)		Mtype = m;	else	{	for (n = Mtype; n->rgt; n = n->rgt)			;		n->rgt = m;	/* concatenate */	}	for (n = Mtype, cnt = 1; n; n = n->rgt, cnt++)	/* syntax check */	{	if (!n->lft || !n->lft->sym		||   n->lft->ntyp != NAME		||   n->lft->lft)	/* indexed variable */			fatal("bad mtype definition", (char *)0);		/* label the name */		if (n->lft->sym->type != MTYPE)		{	n->lft->sym->hidden |= 32;			n->lft->sym->type = MTYPE;			n->lft->sym->ini = nn(ZN,CONST,ZN,ZN);			n->lft->sym->ini->val = cnt;		} else if (n->lft->sym->ini->val != cnt)			non_fatal("name %s appears twice in mtype declaration",				n->lft->sym->name);	}	lineno = oln;	if (cnt > 256)	fatal("too many mtype elements (>255)", (char *)0);}intismtype(char *str)	/* name to number */{	Lextok *n;	int cnt = 1;	for (n = Mtype; n; n = n->rgt)	{	if (strcmp(str, n->lft->sym->name) == 0)			return cnt;		cnt++;	}	return 0;}intsputtype(char *foo, int m){	switch (m) {	case UNSIGNED:	strcpy(foo, "unsigned "); break;	case BIT:	strcpy(foo, "bit   "); break;	case BYTE:	strcpy(foo, "byte  "); break;	case CHAN:	strcpy(foo, "chan  "); break;	case SHORT:	strcpy(foo, "short "); break;	case INT:	strcpy(foo, "int   "); break;	case MTYPE:	strcpy(foo, "mtype "); break;	case STRUCT:	strcpy(foo, "struct"); break;	case PROCTYPE:	strcpy(foo, "proctype"); break;	case LABEL:	strcpy(foo, "label "); return 0;	default:	strcpy(foo, "value "); return 0;	}	return 1;}static intputtype(int m){	char buf[128];	if (sputtype(buf, m))	{	printf("%s", buf);		return 1;	}	return 0;}voidsymvar(Symbol *sp){	Lextok *m;	if (!puttype(sp->type))		return;	printf("\t");	if (sp->owner) printf("%s.", sp->owner->name);	printf("%s", sp->name);	if (sp->nel > 1) printf("[%d]", sp->nel);	if (sp->type == CHAN)		printf("\t%d", (sp->ini)?sp->ini->val:0);	else if (sp->type == STRUCT) /* Frank Weil, 2.9.8 */		printf("\t%s", sp->Snm->name);	else		printf("\t%d", eval(sp->ini));	if (sp->owner)		printf("\t<:struct-field:>");	else	if (!sp->context)		printf("\t<:global:>");	else		printf("\t<%s>", sp->context->name);	if (sp->Nid < 0)	/* formal parameter */		printf("\t<parameter %d>", -(sp->Nid));	else		printf("\t<variable>");	if (sp->type == CHAN && sp->ini)	{	int i;		for (m = sp->ini->rgt, i = 0; m; m = m->rgt)			i++;		printf("\t%d\t", i);		for (m = sp->ini->rgt; m; m = m->rgt)		{	if (m->ntyp == STRUCT)				printf("struct %s", m->sym->name);			else				(void) puttype(m->ntyp);			if (m->rgt) printf("\t");		}	}	printf("\n");}voidsymdump(void){	Ordered *walk;	for (walk = all_names; walk; walk = walk->next)		symvar(walk->entry);}voidchname(Symbol *sp){	printf("chan ");	if (sp->context) printf("%s-", sp->context->name);	if (sp->owner) printf("%s.", sp->owner->name);	printf("%s", sp->name);	if (sp->nel > 1) printf("[%d]", sp->nel);	printf("\t");}static struct X {	int typ; char *nm;} xx[] = {	{ 'A', "exported as run parameter" },	{ 'F', "imported as proctype parameter" },	{ 'L', "used as l-value in asgnmnt" },	{ 'V', "used as r-value in asgnmnt" },	{ 'P', "polled in receive stmnt" },	{ 'R', "used as parameter in receive stmnt" },	{ 'S', "used as parameter in send stmnt" },	{ 'r', "received from" },	{ 's', "sent to" },};static voidchan_check(Symbol *sp){	Access *a; int i, b=0, d;	if (verbose&1) goto report;	/* -C -g */	for (a = sp->access; a; a = a->lnk)		if (a->typ == 'r')			b |= 1;		else if (a->typ == 's')			b |= 2;	if (b == 3 || (sp->hidden&16))	/* balanced or formal par */		return;report:	chname(sp);	for (i = d = 0; i < sizeof(xx)/sizeof(struct X); i++)	{	b = 0;		for (a = sp->access; a; a = a->lnk)			if (a->typ == xx[i].typ) b++;		if (b == 0) continue; d++;		printf("\n\t%s by: ", xx[i].nm);		for (a = sp->access; a; a = a->lnk)		  if (a->typ == xx[i].typ)		  {	printf("%s", a->who->name);			if (a->what) printf(" to %s", a->what->name);			if (a->cnt)  printf(" par %d", a->cnt);			if (--b > 0) printf(", ");		  }	}	printf("%s\n", (!d)?"\n\tnever used under this name":"");}voidchanaccess(void){	Ordered *walk;	char buf[128];	extern int Caccess, separate;	extern short has_code;	for (walk = all_names; walk; walk = walk->next)	{	if (!walk->entry->owner)		switch (walk->entry->type) {		case CHAN:			if (Caccess) chan_check(walk->entry);			break;		case MTYPE:		case BIT:		case BYTE:		case SHORT:		case INT:		case UNSIGNED:			if ((walk->entry->hidden&32))				continue;			if (!separate			&&  !walk->entry->context			&&  !has_code			&&   deadvar)				walk->entry->hidden |= 1; /* auto-hide */			if (!(verbose&32) || has_code) continue;			printf("spin: warning, %s, ", Fname->name);			sputtype(buf, walk->entry->type);			if (walk->entry->context)				printf("proctype %s",					walk->entry->context->name);			else				printf("global");			printf(", '%s%s' variable is never used\n",				buf, walk->entry->name);	}	}}

⌨️ 快捷键说明

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