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

📄 flow.c

📁 对软件进行可达性测试的软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (z = s; z; prev_z = z, z = z->nxt)		add_el(t, z->this);	/* append target */	if (tok == DO)	{	add_el(t, cur_s->this); /* target upfront */		t = new_el(nn(n, BREAK, ZN, ZN)); /* break target */		set_lab(break_dest(), t);	/* new exit  */		breakstack = breakstack->nxt;	/* pop stack */	}	add_el(e, cur_s->this);	add_el(t, cur_s->this);	return e;			/* destination node for label */}static voidescape_el(Element *f, Sequence *e){	SeqList *z;	for (z = f->esc; z; z = z->nxt)		if (z->this == e)			return;	/* already there */	/* cover the lower-level escapes of this state */	for (z = f->esc; z; z = z->nxt)		attach_escape(z->this, e);	/* now attach escape to the state itself */	f->esc = seqlist(e, f->esc);	/* in lifo order... */#ifdef DEBUG	printf("attach %d (", e->frst->Seqno);	comment(stdout, e->frst->n, 0);	printf(")	to %d (", f->Seqno);	comment(stdout, f->n, 0);	printf(")\n");#endif	switch (f->n->ntyp) {	case UNLESS:		attach_escape(f->sub->this, e);		break;	case IF:	case DO:		for (z = f->sub; z; z = z->nxt)			attach_escape(z->this, e);		break;	case D_STEP:		/* attach only to the guard stmnt */		escape_el(f->n->sl->this->frst, e);		break;	case ATOMIC:	case NON_ATOMIC:		/* attach to all stmnts */		attach_escape(f->n->sl->this, e);		break;	}}static voidattach_escape(Sequence *n, Sequence *e){	Element *f;	for (f = n->frst; f; f = f->nxt)	{	escape_el(f, e);		if (f == n->extent)			break;	}}static Element *unless_seq(Lextok *n){	SeqList	*s  = n->sl;	Element	*e  = new_el(ZN);	Element	*t  = new_el(nn(ZN,'.',ZN,ZN)); /* target */	SeqList	*z;	e->n = nn(n, UNLESS, ZN, ZN);	e->n->sl = s;			/* info only */	e->sub = s;	/* need 2 sequences: normal execution and escape */	if (!s || !s->nxt || s->nxt->nxt)		fatal("unexpected unless structure", (char *)0);	/* append the target state to both */	for (z = s; z; z = z->nxt)		add_el(t, z->this);	/* attach escapes to all states in normal sequence */	attach_escape(s->this, s->nxt->this);	add_el(e, cur_s->this);	add_el(t, cur_s->this);#ifdef DEBUG	printf("unless element (%d,%d):\n", e->Seqno, t->Seqno);	for (z = s; z; z = z->nxt)	{	Element *x; printf("\t%d,%d,%d :: ",		z->this->frst->Seqno,		z->this->extent->Seqno,		z->this->last->Seqno);		for (x = z->this->frst; x; x = x->nxt)			printf("(%d)", x->Seqno);		printf("\n");	}#endif	return e;}Element *mk_skip(void){	Lextok  *t = nn(ZN, CONST, ZN, ZN);	t->val = 1;	return new_el(nn(ZN, 'c', t, ZN));}static voidadd_el(Element *e, Sequence *s){	if (e->n->ntyp == GOTO)	{	Symbol *z = has_lab(e, (1|2|4));		if (z)		{	Element *y; /* insert a skip */			y = mk_skip();			mov_lab(z, e, y); /* inherit label */			add_el(y, s);	}	}#ifdef DEBUG	printf("add_el %d after %d -- ",	e->Seqno, (s->last)?s->last->Seqno:-1);	comment(stdout, e->n, 0);	printf("\n");#endif	if (!s->frst)		s->frst = e;	else		s->last->nxt = e;	s->last = e;}static Element *colons(Lextok *n){	if (!n)		return ZE;	if (n->ntyp == ':')	{	Element *e = colons(n->lft);		set_lab(n->sym, e);		return e;	}	innermost = n;	return new_el(n);}voidadd_seq(Lextok *n){	Element *e;	if (!n) return;	innermost = n;	e = colons(n);	if (innermost->ntyp != IF	&&  innermost->ntyp != DO	&&  innermost->ntyp != UNLESS)		add_el(e, cur_s->this);}voidset_lab(Symbol *s, Element *e){	Label *l; extern Symbol *context;	if (!s) return;	for (l = labtab; l; l = l->nxt)		if (l->s == s && l->c == context)		{	non_fatal("label %s redeclared", s->name);			break;		}	l = (Label *) emalloc(sizeof(Label));	l->s = s;	l->c = context;	l->e = e;	l->nxt = labtab;	labtab = l;}Element *get_lab(Lextok *n, int md){	Label *l;	Symbol *s = n->sym;	for (l = labtab; l; l = l->nxt)		if (s == l->s)			return (l->e);	lineno = n->ln;	Fname = n->fn;	if (md) fatal("undefined label %s", s->name);	return ZE;}Symbol *has_lab(Element *e, int special){	Label *l;	for (l = labtab; l; l = l->nxt)	{	if (e != l->e)			continue;		if (special == 0		||  ((special&1) && !strncmp(l->s->name, "accept", 6))		||  ((special&2) && !strncmp(l->s->name, "end", 3))		||  ((special&4) && !strncmp(l->s->name, "progress", 8)))			return (l->s);	}	return ZS;}static voidmov_lab(Symbol *z, Element *e, Element *y){	Label *l;	for (l = labtab; l; l = l->nxt)		if (e == l->e)		{	l->e = y;			return;		}	if (e->n)	{	lineno = e->n->ln;		Fname  = e->n->fn;	}	fatal("cannot happen - mov_lab %s", z->name);}voidfix_dest(Symbol *c, Symbol *a)		/* c:label name, a:proctype name */{	Label *l; extern Symbol *context;#if 0	printf("ref to label '%s' in proctype '%s', search:\n",		c->name, a->name);	for (l = labtab; l; l = l->nxt)		printf("	%s in	%s\n", l->s->name, l->c->name);#endif	for (l = labtab; l; l = l->nxt)	{	if (strcmp(c->name, l->s->name) == 0		&&  strcmp(a->name, l->c->name) == 0)	/* ? */			break;	}	if (!l)	{	printf("spin: label '%s' (proctype %s)\n", c->name, a->name);		non_fatal("unknown label '%s'", c->name);		if (context == a)		printf("spin: cannot remote ref a label inside the same proctype\n");		return;	}	if (!l->e || !l->e->n)		fatal("fix_dest error (%s)", c->name);	if (l->e->n->ntyp == GOTO)	{	Element	*y = (Element *) emalloc(sizeof(Element));		int	keep_ln = l->e->n->ln;		Symbol	*keep_fn = l->e->n->fn;		/* insert skip - or target is optimized away */		y->n = l->e->n;		  /* copy of the goto   */		y->seqno = find_maxel(a); /* unique seqno within proc */		y->nxt = l->e->nxt;		y->Seqno = Unique++; y->Nxt = Al_El; Al_El = y;		/* turn the original element+seqno into a skip */		l->e->n = nn(ZN, 'c', nn(ZN, CONST, ZN, ZN), ZN);		l->e->n->ln = l->e->n->lft->ln = keep_ln;		l->e->n->fn = l->e->n->lft->fn = keep_fn;		l->e->n->lft->val = 1;		l->e->nxt = y;		/* append the goto  */	}	l->e->status |= CHECK2;	/* treat as if global */	if (l->e->status & (ATOM | L_ATOM | D_ATOM))	{	non_fatal("cannot reference label inside atomic or d_step (%s)",			c->name);	}}intfind_lab(Symbol *s, Symbol *c, int markit){	Label *l;	for (l = labtab; l; l = l->nxt)	{	if (strcmp(s->name, l->s->name) == 0		&&  strcmp(c->name, l->c->name) == 0)		{	l->visible |= markit;			return (l->e->seqno);	}	}	return 0;}voidpushbreak(void){	Lbreak *r = (Lbreak *) emalloc(sizeof(Lbreak));	Symbol *l;	char buf[64];	sprintf(buf, ":b%d", break_id++);	l = lookup(buf);	r->l = l;	r->nxt = breakstack;	breakstack = r;}Symbol *break_dest(void){	if (!breakstack)		fatal("misplaced break statement", (char *)0);	return breakstack->l;}voidmake_atomic(Sequence *s, int added){	Element *f;	walk_atomic(s->frst, s->last, added);	f = s->last;	switch (f->n->ntyp) {	/* is last step basic stmnt or sequence ? */	case NON_ATOMIC:	case ATOMIC:		/* redo and search for the last step of that sequence */		make_atomic(f->n->sl->this, added);		break;	case UNLESS:		/* escapes are folded into main sequence */		make_atomic(f->sub->this, added);		break;	default:		f->status &= ~ATOM;		f->status |= L_ATOM;		break;	}}static voidwalk_atomic(Element *a, Element *b, int added){	Element *f; Symbol *ofn; int oln;	SeqList *h;	ofn = Fname;	oln = lineno;	for (f = a; ; f = f->nxt)	{	f->status |= (ATOM|added);		switch (f->n->ntyp) {		case ATOMIC:			if (verbose&32)			  printf("spin: warning, line %3d %s, atomic inside %s (ignored)\n",			  f->n->ln, f->n->fn->name, (added)?"d_step":"atomic");			goto mknonat;		case D_STEP:			if (!(verbose&32))			{	if (added) goto mknonat;				break;			}			printf("spin: warning, line %3d %s, d_step inside ",			 f->n->ln, f->n->fn->name);			if (added)			{	printf("d_step (ignored)\n");				goto mknonat;			}			printf("atomic\n");			break;		case NON_ATOMIC:mknonat:		f->n->ntyp = NON_ATOMIC; /* can jump here */			h = f->n->sl;			walk_atomic(h->this->frst, h->this->last, added);			break;		case UNLESS:			if (added)			{ printf("spin: error, line %3d %s, unless in d_step (ignored)\n",			 	 f->n->ln, f->n->fn->name);			}		}		for (h = f->sub; h; h = h->nxt)			walk_atomic(h->this->frst, h->this->last, added);		if (f == b)			break;	}	Fname = ofn;	lineno = oln;}voiddumplabels(void){	Label *l;	for (l = labtab; l; l = l->nxt)		if (l->c != 0 && l->s->name[0] != ':')		printf("label	%s	%d	<%s>\n",		l->s->name, l->e->seqno, l->c->name);}

⌨️ 快捷键说明

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