cpp.c 5.8 KB

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