mkstate.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. enum
  5. {
  6. Nname = 20,
  7. };
  8. typedef struct Name Name;
  9. struct Name
  10. {
  11. char name[Nname];
  12. int count;
  13. int value;
  14. };
  15. Name list[1000];
  16. char name[Nname];
  17. Name*
  18. lookup(char *s)
  19. {
  20. Name *n;
  21. for(n=list; n->name[0]; n++)
  22. if(strcmp(s, n->name) == 0)
  23. return n;
  24. strcpy(n->name, s);
  25. return n;
  26. }
  27. void
  28. main(int argc, char *argv[])
  29. {
  30. Biobuf *bin, *bout;
  31. char *s, *p, *q;
  32. long lineno;
  33. Name *n;
  34. int i, value, swout;;
  35. ARGBEGIN {
  36. default:
  37. fprint(2, "usage: mkstate statefile cfile\n");
  38. exits(0);
  39. } ARGEND
  40. if(argc != 2) {
  41. fprint(2, "usage: mkstate statefile cfile\n");
  42. exits("usage");
  43. }
  44. bin = Bopen(argv[0], OREAD);
  45. bout = Bopen(argv[1], OWRITE);
  46. lineno = 0;
  47. Bprint(bout, "#line %d \"%s\"\n", 1, argv[0]);
  48. n = 0;
  49. swout = 0;
  50. value = 1;
  51. for(;;) {
  52. s = Brdline(bin, '\n');
  53. if(s == 0)
  54. break;
  55. lineno++;
  56. s[Blinelen(bin)-1] = 0;
  57. p = strchr(s, '@');
  58. if(p == 0)
  59. goto prline;
  60. if(p[1] == '@') {
  61. for(n=list; n->name[0]; n++) {
  62. Bprint(bout, "case %6d: goto A%s;\n", n->value, n->name);
  63. for(i=1; i<n->count; i++)
  64. Bprint(bout, "case %6d: goto A%s_%d;\n", n->value+i, n->name, i);
  65. }
  66. Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);
  67. swout = 1;
  68. continue;
  69. }
  70. if(p[1] == '"') {
  71. for(n=list; n->name[0]; n++)
  72. Bprint(bout, "\t\"%s\", %d,\n", n->name, n->value);
  73. Bprint(bout, "\t0\n");
  74. Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);
  75. swout = 1;
  76. continue;
  77. }
  78. if(p[1] == '\'') {
  79. for(n=list; n->name[0]; n++)
  80. Bprint(bout, "\t[%d] = \"%s\",\n", n->value, n->name);
  81. Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], p+2);
  82. swout = 1;
  83. continue;
  84. }
  85. if(p[1] >= '1' && p[1] <= '9' && (p[2] == 'b' || p[2] == 'f')) {
  86. p[0] = 0;
  87. i = p[1] - '1';
  88. if(p[2] == 'b')
  89. i = -i - 1;
  90. i += n->count;
  91. if(i)
  92. Bprint(bout, "%s%s_%d%s\n", s, name, i, p+3);
  93. else
  94. Bprint(bout, "%s%s%s\n", s, name, p+3);
  95. continue;
  96. }
  97. q = strchr(p, ':');
  98. if(q) {
  99. if(swout)
  100. fprint(2, "%ld: cannot create label after switch has been generated\n",
  101. lineno);
  102. if(p[1] == ':') {
  103. n = lookup(name);
  104. if(n->count == 0)
  105. fprint(2, "%ld: no base name\n", lineno);
  106. goto prbreak;
  107. }
  108. i = 0;
  109. if(n != nil)
  110. i = n->count;
  111. memset(name, 0, sizeof(name));
  112. memcpy(name, p+1, q-p-1);
  113. n = lookup(name);
  114. if(n->count)
  115. fprint(2, "%ld: %s: redefined\n", lineno, name);
  116. value += i;
  117. n->value = value;
  118. prbreak:
  119. if(n->count) {
  120. Bprint(bout, "goto B%s_%d; B%s_%d: x->state = %d; goto out; A%s_%d: x->state = %d;\n",
  121. name, n->count, name, n->count,
  122. n->value+n->count, name, n->count, n->value);
  123. } else {
  124. Bprint(bout, "goto B%s; B%s: x->state = %d; goto out; A%s: x->state = %d;\n",
  125. name, name, n->value, name, n->value);
  126. }
  127. n->count++;
  128. Bprint(bout, "#line %ld \"%s\"\n%s\n", lineno, argv[0], q+1);
  129. continue;
  130. }
  131. prline:
  132. Bprint(bout, "%s\n", s);
  133. }
  134. exits(0);
  135. }