preprocess.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Header$ */
  6. /* PREPROCESSOR DRIVER */
  7. #include <system.h>
  8. #include <alloc.h>
  9. #include "input.h"
  10. #include "obufsize.h"
  11. #include "arith.h"
  12. #include "LLlex.h"
  13. #include "class.h"
  14. #include "macro.h"
  15. #include "idf.h"
  16. #include "idfsize.h"
  17. #include "bits.h"
  18. #include "ln_prefix.h"
  19. #include "textsize.h"
  20. char _obuf[OBUFSIZE];
  21. #ifdef DOBITS
  22. char bits[128];
  23. #endif
  24. extern int InputLevel;
  25. Xflush()
  26. {
  27. sys_write(STDOUT, _obuf, OBUFSIZE);
  28. }
  29. static char *SkipComment();
  30. extern char options[];
  31. /* #pragma directives are saved here and passed to the compiler later on.
  32. */
  33. struct prag_info {
  34. int pr_linnr;
  35. char *pr_fil;
  36. char *pr_text;
  37. };
  38. static struct prag_info *pragma_tab;
  39. static int pragma_nr;
  40. do_pragma()
  41. {
  42. register int size = ITEXTSIZE;
  43. char *cur_line = Malloc(size);
  44. register char *c_ptr = cur_line;
  45. register int c = GetChar();
  46. *c_ptr = '\0';
  47. while(c != '\n') {
  48. if (c_ptr + 1 - cur_line == size) {
  49. cur_line = Realloc(cur_line, size += ITEXTSIZE);
  50. c_ptr = cur_line + size - 1;
  51. }
  52. *c_ptr++ = c;
  53. c = GetChar();
  54. }
  55. *c_ptr = '\0';
  56. if (!pragma_nr) {
  57. pragma_tab = (struct prag_info *)Malloc(sizeof(struct prag_info));
  58. } else {
  59. pragma_tab = (struct prag_info *)Realloc(pragma_tab
  60. , sizeof(struct prag_info) * (pragma_nr+1));
  61. }
  62. pragma_tab[pragma_nr].pr_linnr = LineNumber;
  63. pragma_tab[pragma_nr].pr_fil = FileName;
  64. pragma_tab[pragma_nr].pr_text = cur_line;
  65. pragma_nr++;
  66. LineNumber++;
  67. }
  68. preprocess(fn)
  69. char *fn;
  70. {
  71. register int c;
  72. register char *op = _obuf;
  73. register char *ob = &_obuf[OBUFSIZE];
  74. char Xbuf[256];
  75. int lineno = 0;
  76. int startline;
  77. #define flush(X) (sys_write(STDOUT,_obuf,X))
  78. #define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
  79. #define newline() echo('\n')
  80. if (!options['P']) {
  81. /* Generate a line directive communicating the
  82. source filename
  83. */
  84. register char *p = Xbuf;
  85. sprint(p, "%s 1 \"%s\"\n",
  86. LINE_PREFIX,
  87. FileName);
  88. while (*p) {
  89. echo(*p++);
  90. }
  91. }
  92. #define do_line_dir(lineno, fn) \
  93. if (lineno != LineNumber || fn != FileName) { \
  94. fn = FileName; \
  95. lineno = LineNumber; \
  96. if (! options['P']) { \
  97. register char *p = Xbuf; \
  98. \
  99. sprint(p, "%s %d \"%s\"\n", \
  100. LINE_PREFIX, \
  101. LineNumber, \
  102. FileName); \
  103. while (*p) { \
  104. echo(*p++); \
  105. } \
  106. } \
  107. }
  108. for (;;) {
  109. LineNumber++;
  110. lineno++;
  111. startline = 1;
  112. c = GetChar();
  113. while (startline) {
  114. /* first flush the saved pragma's */
  115. if (pragma_nr) {
  116. register int i = 0;
  117. int LiNo = LineNumber;
  118. char *FiNam = FileName;
  119. while (i < pragma_nr) {
  120. register char *c_ptr = "#pragma";
  121. LineNumber = pragma_tab[i].pr_linnr;
  122. FileName = pragma_tab[i].pr_fil;
  123. do_line_dir(lineno, fn);
  124. while (*c_ptr) { echo(*c_ptr++); }
  125. c_ptr = pragma_tab[i].pr_text;
  126. while (*c_ptr) { echo(*c_ptr++); }
  127. newline(); lineno++;
  128. free(pragma_tab[i].pr_text);
  129. i++;
  130. }
  131. free(pragma_tab);
  132. pragma_tab = (struct prag_info *)0;
  133. pragma_nr = 0;
  134. LineNumber = LiNo;
  135. FileName = FiNam;
  136. do_line_dir(lineno, fn);
  137. }
  138. while (class(c) == STSKIP || c == '/') {
  139. if (c == '/') {
  140. if (!InputLevel) {
  141. c = GetChar();
  142. if (c == '*') {
  143. op = SkipComment(op, &lineno);
  144. if (!op) return;
  145. if (!options['C']) echo(' ');
  146. c = GetChar();
  147. continue;
  148. }
  149. UnGetChar();
  150. c = '/';
  151. }
  152. break;
  153. }
  154. echo(c);
  155. c = GetChar();
  156. }
  157. if (c == '#') {
  158. domacro();
  159. lineno++;
  160. newline();
  161. c = GetChar();
  162. } else startline = 0;
  163. }
  164. do_line_dir(lineno, fn);
  165. for (;;) {
  166. /* illegal character */
  167. if (c & 0200) {
  168. if (c == EOI) {
  169. newline();
  170. flush(op-_obuf);
  171. return;
  172. }
  173. fatal("non-ascii character read");
  174. }
  175. /* comments */
  176. if (c == '/' && !InputLevel) {
  177. c = GetChar();
  178. if (c == '*') {
  179. op = SkipComment(op, &lineno);
  180. if (!op) return;
  181. if (!options['C']) echo(' ');
  182. c = GetChar();
  183. continue;
  184. }
  185. echo('/');
  186. continue;
  187. }
  188. /* switch on character */
  189. switch(class(c)) {
  190. case STNL:
  191. echo(c);
  192. break;
  193. case STSTR:
  194. case STCHAR:
  195. {
  196. register int stopc = c;
  197. int escaped;
  198. do {
  199. escaped = 0;
  200. echo(c);
  201. c = GetChar();
  202. if (c == '\n') {
  203. break;
  204. }
  205. else if (c == EOI) {
  206. newline();
  207. flush(op-_obuf);
  208. return;
  209. }
  210. if (c == '\\') {
  211. echo(c);
  212. c = GetChar();
  213. if (c == '\n') {
  214. ++LineNumber;
  215. lineno++;
  216. }
  217. else if (c == '\'') escaped = 1;
  218. }
  219. } while (escaped || c != stopc);
  220. echo(c);
  221. if (c == '\n')
  222. break; /* Don't eat # */
  223. c = GetChar();
  224. continue;
  225. }
  226. case STNUM:
  227. /* The following code is quit ugly. This because
  228. * ..3 == . .3 , whereas ...3 == ... 3
  229. */
  230. echo(c);
  231. if (c == '.') {
  232. c = GetChar();
  233. if (c == '.') {
  234. if ((c = GetChar()) == '.') {
  235. echo('.'); echo('.');
  236. c = GetChar();
  237. continue;
  238. }
  239. UnGetChar();
  240. c = '.';
  241. continue;
  242. } else if (!is_dig(c)) {
  243. continue;
  244. } else echo(c);
  245. }
  246. c = GetChar();
  247. while (in_idf(c) || c == '.') {
  248. echo(c);
  249. if (c == 'e' || c == 'E') {
  250. c = GetChar();
  251. if (c == '+' || c == '-') {
  252. echo(c);
  253. c = GetChar();
  254. }
  255. } else c = GetChar();
  256. }
  257. continue;
  258. case STELL:
  259. c = GetChar();
  260. UnGetChar();
  261. if (c == '"' || c == '\'') {
  262. echo('L');
  263. continue;
  264. }
  265. c = 'L';
  266. case STIDF: {
  267. extern int idfsize; /* ??? */
  268. char buf[IDFSIZE + 1];
  269. register char *tg = &buf[0];
  270. register char *maxpos = &buf[idfsize];
  271. register struct idf *idef;
  272. int NoExpandNext = 0;
  273. #define tstmac(bx) if (!(bits[c] & bx)) goto nomac
  274. #define cpy *tg++ = c
  275. #define load c = GetChar(); if (!in_idf(c)) goto endidf
  276. /* unstack macro's when allowed. */
  277. if (Unstacked)
  278. EnableMacros();
  279. if (c == NOEXPM) {
  280. NoExpandNext = 1;
  281. c = GetChar();
  282. }
  283. #ifdef DOBITS
  284. cpy; tstmac(bit0); load;
  285. cpy; tstmac(bit1); load;
  286. cpy; tstmac(bit2); load;
  287. cpy; tstmac(bit3); load;
  288. cpy; tstmac(bit4); load;
  289. cpy; tstmac(bit5); load;
  290. cpy; tstmac(bit6); load;
  291. cpy; tstmac(bit7); load;
  292. #endif
  293. for(;;) {
  294. if (tg < maxpos) {
  295. cpy;
  296. }
  297. load;
  298. }
  299. endidf:
  300. if (c != EOF) UnGetChar();
  301. *tg = '\0'; /* mark the end of the identifier */
  302. if ((idef = findidf(buf))
  303. && idef->id_macro
  304. && ReplaceMacros && !NoExpandNext) {
  305. if (replace(idef)) {
  306. c = GetChar();
  307. continue;
  308. }
  309. tg = buf;
  310. while (*tg) {
  311. echo(*tg++);
  312. }
  313. c = GetChar();
  314. if (in_idf(c)) echo(' ');
  315. continue;
  316. }
  317. nomac:
  318. *tg = '\0';
  319. tg = buf;
  320. while (*tg) {
  321. echo(*tg++);
  322. }
  323. c = GetChar();
  324. while (in_idf(c)) {
  325. echo(c);
  326. c = GetChar();
  327. }
  328. continue;
  329. }
  330. case STMSPEC:
  331. if (InputLevel) {
  332. echo(' '); /* seperate tokens */
  333. c = GetChar();
  334. continue;
  335. }
  336. /* else fallthrough */
  337. default:
  338. echo(c);
  339. c = GetChar();
  340. continue;
  341. }
  342. break;
  343. }
  344. }
  345. /*NOTREACHED*/
  346. }
  347. static char *
  348. SkipComment(op, lineno)
  349. char *op;
  350. int *lineno;
  351. {
  352. char *ob = &_obuf[OBUFSIZE];
  353. register int c;
  354. NoUnstack++;
  355. if (options['C']) {
  356. echo('/');
  357. echo('*');
  358. }
  359. c = GetChar();
  360. for(;;) {
  361. if (c == EOI) {
  362. newline();
  363. flush(op - _obuf);
  364. op = 0;
  365. break;
  366. }
  367. if (options['C']) {
  368. echo(c);
  369. }
  370. if (c == '\n') {
  371. ++LineNumber;
  372. ++*lineno;
  373. if (!options['C']) {
  374. echo(c);
  375. }
  376. }
  377. if (c == '*') {
  378. c = GetChar();
  379. if (c == '/') {
  380. if (options['C']) {
  381. echo(c);
  382. }
  383. break; /* for(;;) */
  384. }
  385. } else c = GetChar();
  386. }
  387. NoUnstack--;
  388. return op;
  389. }