123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #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;
- }
- void
- main(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);
- }
|