preprocess.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* PREPROCESSOR DRIVER */
  7. #include <system.h>
  8. #include "input.h"
  9. #include "obufsize.h"
  10. #include "LLlex.h"
  11. #include "class.h"
  12. #include "idf.h"
  13. #include "idfsize.h"
  14. #include "bits.h"
  15. #include "line_prefix.h"
  16. #ifdef DOBITS
  17. char bits[128];
  18. #endif
  19. char _obuf[OBUFSIZE];
  20. extern int do_preprocess;
  21. Xflush()
  22. {
  23. if (do_preprocess) sys_write(STDOUT, _obuf, OBUFSIZE);
  24. }
  25. preprocess(fn)
  26. char *fn;
  27. {
  28. register int c;
  29. register char *op = _obuf;
  30. register char *ob = &_obuf[OBUFSIZE];
  31. char Xbuf[256];
  32. int lineno = 0;
  33. extern char options[];
  34. #define flush(X) (! do_preprocess || sys_write(STDOUT,_obuf,X))
  35. #define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
  36. #define newline() echo('\n')
  37. if (! options['P']) {
  38. /* Generate a line directive communicating the
  39. source filename
  40. */
  41. register char *p = Xbuf;
  42. sprint(p, "%s 1 \"%s\"\n",
  43. LINE_PREFIX,
  44. FileName);
  45. while (*p) {
  46. echo(*p++);
  47. }
  48. }
  49. for (;;) {
  50. LineNumber++;
  51. lineno++;
  52. LoadChar(c);
  53. while (c == '#') {
  54. domacro();
  55. lineno++;
  56. newline();
  57. LoadChar(c);
  58. }
  59. if (lineno != LineNumber || fn != FileName) {
  60. fn = FileName;
  61. lineno = LineNumber;
  62. if (! options['P']) {
  63. register char *p = Xbuf;
  64. sprint(p, "%s %d \"%s\"\n",
  65. LINE_PREFIX,
  66. LineNumber,
  67. FileName);
  68. while (*p) {
  69. echo(*p++);
  70. }
  71. }
  72. }
  73. for (;;) {
  74. if (c & 0200) {
  75. if (c == EOI) {
  76. newline();
  77. flush(op-_obuf);
  78. return;
  79. }
  80. fatal("non-ascii character read");
  81. }
  82. if (c == '/') {
  83. LoadChar(c);
  84. if (c == '*') {
  85. NoUnstack++;
  86. if (options['C']) {
  87. echo('/');
  88. echo('*');
  89. }
  90. for (;;) {
  91. LoadChar(c);
  92. if (c == '\n') {
  93. ++LineNumber;
  94. ++lineno;
  95. echo(c);
  96. }
  97. else if (c == EOI) {
  98. newline();
  99. flush(op - _obuf);
  100. return;
  101. }
  102. else if (c == '*') {
  103. if (options['C']) {
  104. echo(c);
  105. }
  106. LoadChar(c);
  107. if (c == '/') {
  108. if (options['C']) {
  109. echo(c);
  110. }
  111. break;
  112. }
  113. else {
  114. PushBack();
  115. }
  116. }
  117. else if (options['C']) {
  118. echo(c);
  119. }
  120. }
  121. NoUnstack--;
  122. LoadChar(c);
  123. continue;
  124. }
  125. echo('/');
  126. continue;
  127. }
  128. switch(class(c)) {
  129. case STNL:
  130. echo(c);
  131. break;
  132. case STSTR:
  133. case STCHAR: {
  134. register int stopc = c;
  135. int escaped;
  136. do {
  137. escaped = 0;
  138. echo(c);
  139. LoadChar(c);
  140. if (c == '\n') {
  141. break;
  142. }
  143. else if (c == EOI) {
  144. newline();
  145. flush(op-_obuf);
  146. return;
  147. }
  148. if (c == '\\') {
  149. echo(c);
  150. LoadChar(c);
  151. if (c == '\n') {
  152. ++LineNumber;
  153. lineno++;
  154. }
  155. else escaped = 1;
  156. }
  157. } while (escaped || c != stopc);
  158. echo(c);
  159. if (c == '\n')
  160. break; /* Don't eat # */
  161. LoadChar(c);
  162. continue;
  163. }
  164. case STNUM:
  165. #define getdec(c) do { echo(c); LoadChar(c);} while (is_dig(c))
  166. #define gethex(c) do { echo(c); LoadChar(c);} while (is_hex(c))
  167. if (c != '0') {
  168. getdec(c);
  169. if (c == '.') getdec(c);
  170. if (c == 'e') {
  171. echo(c);
  172. LoadChar(c);
  173. if (c == '+' || c == '-') {
  174. echo(c);
  175. LoadChar(c);
  176. }
  177. if (is_dig(c)) getdec(c);
  178. }
  179. }
  180. else {
  181. echo(c);
  182. LoadChar(c);
  183. if (c == 'x' || c == 'X') gethex(c);
  184. else if (is_dig(c)) getdec(c);
  185. }
  186. continue;
  187. case STIDF: {
  188. extern int idfsize; /* ??? */
  189. char buf[IDFSIZE + 1];
  190. register char *tg = &buf[0];
  191. register char *maxpos = &buf[idfsize];
  192. register struct idf *idef;
  193. #define tstmac(bx) if (!(bits[c] & bx)) goto nomac
  194. #define cpy if (Unstacked) EnableMacros(); *tg++ = c
  195. #define load LoadChar(c); if (!in_idf(c)) goto endidf
  196. #ifdef DOBITS
  197. cpy; tstmac(bit0); load;
  198. cpy; tstmac(bit1); load;
  199. cpy; tstmac(bit2); load;
  200. cpy; tstmac(bit3); load;
  201. cpy; tstmac(bit4); load;
  202. cpy; tstmac(bit5); load;
  203. cpy; tstmac(bit6); load;
  204. cpy; tstmac(bit7); load;
  205. #endif
  206. for(;;) {
  207. if (tg < maxpos) {
  208. cpy;
  209. }
  210. else break;
  211. load;
  212. }
  213. endidf:
  214. PushBack();
  215. *tg = '\0'; /* mark the end of the identifier */
  216. idef = findidf(buf);
  217. if (idef && idef->id_macro) {
  218. do {
  219. LoadChar(c);
  220. } while (in_idf(c));
  221. PushBack();
  222. if (replace(idef)) {
  223. LoadChar(c);
  224. continue;
  225. }
  226. }
  227. nomac:
  228. *tg = 0;
  229. tg = buf;
  230. while (*tg) {
  231. echo(*tg++);
  232. }
  233. LoadChar(c);
  234. while (in_idf(c)) {
  235. echo(c);
  236. LoadChar(c);
  237. }
  238. continue;
  239. }
  240. default:
  241. echo(c);
  242. LoadChar(c);
  243. continue;
  244. }
  245. break;
  246. }
  247. }
  248. /*NOTREACHED*/
  249. }