henesyinit from p9fd787fda5 years agoHistory
149 lines · 2.9 KB · C
RawDownload
#include	<u.h>#include	<libc.h>#include	<bio.h> enum{	Nname	= 20,}; typedef	struct	Name	Name;struct	Name{	char	name[Nname];	int	count;	int	value;}; Name	list[1000];char	name[Nname]; Name*lookup(char *s){	Name *n; 	for(n=list; n->name[0]; n++)		if(strcmp(s, n->name) == 0)			return n;	strcpy(n->name, s);	return n;} voidmain(int argc, char *argv[]){	Biobuf *bin, *bout;	char *s, *p, *q;	long lineno;	Name *n;	int i, value, swout;; 	ARGBEGIN {	default:		fprint(2, "usage: mkstate statefile cfile\n");		exits(0);	} ARGEND	if(argc != 2) {		fprint(2, "usage: mkstate statefile cfile\n");		exits("usage");	}	bin = Bopen(argv[0], OREAD);	bout = Bopen(argv[1], OWRITE);	lineno = 0;	Bprint(bout, "#line %d \"%s\"\n", 1, argv[0]);	n = 0;	swout = 0;	value = 1;	for(;;) {		s = Brdline(bin, '\n');		if(s == 0)			break;		lineno++;		s[Blinelen(bin)-1] = 0;		p = strchr(s, '@');		if(p == 0)			goto prline; 		if(p[1] == '@') {			for(n=list; n->name[0]; n++) {				Bprint(bout, "case %6d: goto A%s;\n", n->value, n->name);				for(i=1; i<n->count; i++)					Bprint(bout, "case %6d: goto A%s_%d;\n", n->value+i, n->name, i);			}			Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);			swout = 1;			continue;		} 		if(p[1] == '"') {			for(n=list; n->name[0]; n++)				Bprint(bout, "\t\"%s\", %d,\n", n->name, n->value);			Bprint(bout, "\t0\n");			Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);			swout = 1;			continue;		}		if(p[1] == '\'') {			for(n=list; n->name[0]; n++)				Bprint(bout, "\t[%d]	= \"%s\",\n", n->value, n->name);			Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);			swout = 1;			continue;		}		if(p[1] >= '1' && p[1] <= '9' && (p[2] == 'b' || p[2] == 'f')) {			p[0] = 0;			i = p[1] - '1';			if(p[2] == 'b')				i = -i - 1;			i += n->count;			if(i)				Bprint(bout, "%s%s_%d%s\n", s, name, i, p+3);			else				Bprint(bout, "%s%s%s\n", s, name, p+3);			continue;		} 		q = strchr(p, ':');		if(q) {			if(swout)				fprint(2, "%ld: cannot create label after switch has been generated\n",					lineno);			if(p[1] == ':') {				n = lookup(name);				if(n->count == 0)					fprint(2, "%ld:  no base name\n", lineno);				goto prbreak;			} 			i = 0;			if(n != nil)				i = n->count; 			memset(name, 0, sizeof(name));			memcpy(name, p+1, q-p-1);			n = lookup(name);			if(n->count)				fprint(2, "%ld: %s: redefined\n", lineno, name);			value += i;			n->value = value; 		prbreak:			if(n->count) {				Bprint(bout, "goto B%s_%d; B%s_%d: x->state = %d; goto out; A%s_%d: x->state = %d;\n",					name, n->count, name, n->count,					n->value+n->count, name, n->count, n->value);			} else {				Bprint(bout, "goto B%s; B%s: x->state = %d; goto out; A%s: x->state = %d;\n",					name, name, n->value, name, n->value);			}			n->count++;			Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], q+1);			continue;		} 	prline:		Bprint(bout, "%s\n", s);	}	exits(0);}