cpp.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <stdio.h>
  12. #include "cpp.h"
  13. #define OUTS 16384
  14. char outbuf[OUTS];
  15. char *outp = outbuf;
  16. Source *cursource;
  17. int nerrs;
  18. struct token nltoken = { NL, 0, 0, 0, 1, (uint8_t*)"\n" };
  19. char *curtime;
  20. int incdepth;
  21. int ifdepth;
  22. int ifsatisfied[NIF];
  23. int skipping;
  24. int
  25. main(int argc, char **argv)
  26. {
  27. Tokenrow tr;
  28. int32_t t;
  29. char ebuf[BUFSIZ];
  30. setbuf(stderr, ebuf);
  31. t = time(NULL);
  32. curtime = ctime(t);
  33. maketokenrow(3, &tr);
  34. expandlex();
  35. setup(argc, argv);
  36. fixlex();
  37. iniths();
  38. genline();
  39. process(&tr);
  40. flushout();
  41. fflush(stderr);
  42. exits(nerrs? "errors" : 0);
  43. return 0;
  44. }
  45. void
  46. process(Tokenrow *trp)
  47. {
  48. int anymacros = 0;
  49. for (;;) {
  50. if (trp->tp >= trp->lp) {
  51. trp->tp = trp->lp = trp->bp;
  52. outp = outbuf;
  53. anymacros |= gettokens(trp, 1);
  54. trp->tp = trp->bp;
  55. }
  56. if (trp->tp->type == END) {
  57. if (--incdepth>=0) {
  58. if (cursource->ifdepth)
  59. error(ERROR,
  60. "Unterminated conditional in #include");
  61. unsetsource();
  62. cursource->line += cursource->lineinc;
  63. trp->tp = trp->lp;
  64. genline();
  65. continue;
  66. }
  67. if (ifdepth)
  68. error(ERROR, "Unterminated #if/#ifdef/#ifndef");
  69. break;
  70. }
  71. if (trp->tp->type==SHARP) {
  72. trp->tp += 1;
  73. control(trp);
  74. } else if (!skipping && anymacros)
  75. expandrow(trp, NULL, Notinmacro);
  76. if (skipping)
  77. setempty(trp);
  78. puttokens(trp);
  79. anymacros = 0;
  80. cursource->line += cursource->lineinc;
  81. if (cursource->lineinc>1) {
  82. genline();
  83. }
  84. }
  85. }
  86. void
  87. control(Tokenrow *trp)
  88. {
  89. Nlist *np;
  90. Token *tp;
  91. tp = trp->tp;
  92. if (tp->type!=NAME) {
  93. if (tp->type==NUMBER)
  94. goto kline;
  95. if (tp->type != NL)
  96. error(ERROR, "Unidentifiable control line");
  97. return; /* else empty line */
  98. }
  99. if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
  100. error(WARNING, "Unknown preprocessor control %t", tp);
  101. return;
  102. }
  103. if (skipping) {
  104. if ((np->flag&ISKW)==0)
  105. return;
  106. switch (np->val) {
  107. case KENDIF:
  108. if (--ifdepth<skipping)
  109. skipping = 0;
  110. --cursource->ifdepth;
  111. setempty(trp);
  112. return;
  113. case KIFDEF:
  114. case KIFNDEF:
  115. case KIF:
  116. if (++ifdepth >= NIF)
  117. error(FATAL, "#if too deeply nested");
  118. ++cursource->ifdepth;
  119. return;
  120. case KELIF:
  121. case KELSE:
  122. if (ifdepth<=skipping)
  123. break;
  124. return;
  125. default:
  126. return;
  127. }
  128. }
  129. switch (np->val) {
  130. case KDEFINE:
  131. dodefine(trp);
  132. break;
  133. case KUNDEF:
  134. tp += 1;
  135. if (tp->type!=NAME || trp->lp - trp->bp != 4) {
  136. error(ERROR, "Syntax error in #undef");
  137. break;
  138. }
  139. if ((np = lookup(tp, 0))) {
  140. if (np->flag&ISUNCHANGE) {
  141. error(ERROR, "#defined token %t can't be undefined", tp);
  142. return;
  143. }
  144. np->flag &= ~ISDEFINED;
  145. }
  146. break;
  147. case KPRAGMA:
  148. return;
  149. case KIFDEF:
  150. case KIFNDEF:
  151. case KIF:
  152. if (++ifdepth >= NIF)
  153. error(FATAL, "#if too deeply nested");
  154. ++cursource->ifdepth;
  155. ifsatisfied[ifdepth] = 0;
  156. if (eval(trp, np->val))
  157. ifsatisfied[ifdepth] = 1;
  158. else
  159. skipping = ifdepth;
  160. break;
  161. case KELIF:
  162. if (ifdepth==0) {
  163. error(ERROR, "#elif with no #if");
  164. return;
  165. }
  166. if (ifsatisfied[ifdepth]==2)
  167. error(ERROR, "#elif after #else");
  168. if (eval(trp, np->val)) {
  169. if (ifsatisfied[ifdepth])
  170. skipping = ifdepth;
  171. else {
  172. skipping = 0;
  173. ifsatisfied[ifdepth] = 1;
  174. }
  175. } else
  176. skipping = ifdepth;
  177. break;
  178. case KELSE:
  179. if (ifdepth==0 || cursource->ifdepth==0) {
  180. error(ERROR, "#else with no #if");
  181. return;
  182. }
  183. if (ifsatisfied[ifdepth]==2)
  184. error(ERROR, "#else after #else");
  185. if (trp->lp - trp->bp != 3)
  186. error(ERROR, "Syntax error in #else");
  187. skipping = ifsatisfied[ifdepth]? ifdepth: 0;
  188. ifsatisfied[ifdepth] = 2;
  189. break;
  190. case KENDIF:
  191. if (ifdepth==0 || cursource->ifdepth==0) {
  192. error(ERROR, "#endif with no #if");
  193. return;
  194. }
  195. --ifdepth;
  196. --cursource->ifdepth;
  197. if (trp->lp - trp->bp != 3)
  198. error(WARNING, "Syntax error in #endif");
  199. break;
  200. case KERROR:
  201. trp->tp = tp+1;
  202. error(ERROR, "#error directive: %r", trp);
  203. break;
  204. case KWARNING:
  205. trp->tp = tp+1;
  206. error(WARNING, "#warning directive: %r", trp);
  207. break;
  208. case KLINE:
  209. trp->tp = tp+1;
  210. expandrow(trp, "<line>", Notinmacro);
  211. tp = trp->bp+2;
  212. kline:
  213. if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
  214. || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
  215. error(ERROR, "Syntax error in #line");
  216. return;
  217. }
  218. cursource->line = atol((char*)tp->t)-1;
  219. if (cursource->line<0 || cursource->line>=32768)
  220. error(WARNING, "#line specifies number out of range");
  221. tp = tp+1;
  222. if (tp+1<trp->lp)
  223. cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
  224. return;
  225. case KDEFINED:
  226. error(ERROR, "Bad syntax for control line");
  227. break;
  228. case KINCLUDE:
  229. doinclude(trp);
  230. trp->lp = trp->bp;
  231. return;
  232. case KEVAL:
  233. eval(trp, np->val);
  234. break;
  235. default:
  236. error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
  237. break;
  238. }
  239. setempty(trp);
  240. return;
  241. }
  242. void *
  243. dorealloc(void *ptr, int size)
  244. {
  245. void *p = realloc(ptr, size);
  246. if (p==NULL)
  247. error(FATAL, "Out of memory from realloc");
  248. return p;
  249. }
  250. void *
  251. domalloc(int size)
  252. {
  253. void *p = malloc(size);
  254. if (p==NULL)
  255. error(FATAL, "Out of memory from malloc");
  256. return p;
  257. }
  258. void
  259. dofree(void *p)
  260. {
  261. free(p);
  262. }
  263. void
  264. error(enum errtype type, char *string, ...)
  265. {
  266. va_list ap;
  267. char *cp, *ep;
  268. Token *tp;
  269. Tokenrow *trp;
  270. Source *s;
  271. int i;
  272. void *p;
  273. fprintf(stderr, "cpp: ");
  274. for (s=cursource; s; s=s->next)
  275. if (*s->filename)
  276. fprintf(stderr, "%s:%d ", s->filename, s->line);
  277. va_start(ap, string);
  278. for (ep=string; *ep; ep++) {
  279. if (*ep=='%') {
  280. switch (*++ep) {
  281. case 's':
  282. cp = va_arg(ap, char *);
  283. fprintf(stderr, "%s", cp);
  284. break;
  285. case 'd':
  286. i = va_arg(ap, int);
  287. fprintf(stderr, "%d", i);
  288. break;
  289. case 'p':
  290. p = va_arg(ap, void *);
  291. fprintf(stderr, "%p", p);
  292. break;
  293. case 't':
  294. tp = va_arg(ap, Token *);
  295. fprintf(stderr, "%.*s", tp->len, tp->t);
  296. break;
  297. case 'r':
  298. trp = va_arg(ap, Tokenrow *);
  299. for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
  300. if (tp>trp->tp && tp->wslen)
  301. fputc(' ', stderr);
  302. fprintf(stderr, "%.*s", tp->len, tp->t);
  303. }
  304. break;
  305. default:
  306. fputc(*ep, stderr);
  307. break;
  308. }
  309. } else
  310. fputc(*ep, stderr);
  311. }
  312. va_end(ap);
  313. fputc('\n', stderr);
  314. if (type==FATAL)
  315. exits("error");
  316. if (type!=WARNING)
  317. nerrs = 1;
  318. fflush(stderr);
  319. }