macbody 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. #define VARMAC 0x80
  2. long
  3. getnsn(void)
  4. {
  5. long n;
  6. int c;
  7. c = getnsc();
  8. if(c < '0' || c > '9')
  9. return -1;
  10. n = 0;
  11. while(c >= '0' && c <= '9') {
  12. n = n*10 + c-'0';
  13. c = getc();
  14. }
  15. unget(c);
  16. return n;
  17. }
  18. Sym*
  19. getsym(void)
  20. {
  21. int c;
  22. char *cp;
  23. c = getnsc();
  24. if(!isalpha(c) && c != '_') {
  25. unget(c);
  26. return S;
  27. }
  28. for(cp = symb;;) {
  29. if(cp <= symb+NSYMB-4)
  30. *cp++ = c;
  31. c = getc();
  32. if(isalnum(c) || c == '_')
  33. continue;
  34. unget(c);
  35. break;
  36. }
  37. *cp = 0;
  38. if(cp > symb+NSYMB-4)
  39. yyerror("symbol too large: %s", symb);
  40. return lookup();
  41. }
  42. Sym*
  43. getsymdots(int *dots)
  44. {
  45. int c;
  46. Sym *s;
  47. s = getsym();
  48. if(s != S)
  49. return s;
  50. c = getnsc();
  51. if(c != '.'){
  52. unget(c);
  53. return S;
  54. }
  55. if(getc() != '.' || getc() != '.')
  56. yyerror("bad dots in macro");
  57. *dots = 1;
  58. return slookup("__VA_ARGS__");
  59. }
  60. int
  61. getcom(void)
  62. {
  63. int c;
  64. for(;;) {
  65. c = getnsc();
  66. if(c != '/')
  67. break;
  68. c = getc();
  69. if(c == '/') {
  70. while(c != '\n')
  71. c = getc();
  72. break;
  73. }
  74. if(c != '*')
  75. break;
  76. c = getc();
  77. for(;;) {
  78. if(c == '*') {
  79. c = getc();
  80. if(c != '/')
  81. continue;
  82. c = getc();
  83. break;
  84. }
  85. if(c == '\n') {
  86. yyerror("comment across newline");
  87. break;
  88. }
  89. c = getc();
  90. }
  91. if(c == '\n')
  92. break;
  93. }
  94. return c;
  95. }
  96. void
  97. dodefine(char *cp)
  98. {
  99. Sym *s;
  100. char *p;
  101. long l;
  102. strcpy(symb, cp);
  103. p = strchr(symb, '=');
  104. if(p) {
  105. *p++ = 0;
  106. s = lookup();
  107. l = strlen(p) + 2; /* +1 null, +1 nargs */
  108. while(l & 3)
  109. l++;
  110. while(nhunk < l)
  111. gethunk();
  112. *hunk = 0;
  113. strcpy(hunk+1, p);
  114. s->macro = hunk;
  115. hunk += l;
  116. nhunk -= l;
  117. } else {
  118. s = lookup();
  119. s->macro = "\0001"; /* \000 is nargs */
  120. }
  121. if(debug['m'])
  122. print("#define (-D) %s %s\n", s->name, s->macro+1);
  123. }
  124. struct
  125. {
  126. char *macname;
  127. void (*macf)(void);
  128. } mactab[] =
  129. {
  130. "ifdef", 0, /* macif(0) */
  131. "ifndef", 0, /* macif(1) */
  132. "else", 0, /* macif(2) */
  133. "line", maclin,
  134. "define", macdef,
  135. "include", macinc,
  136. "undef", macund,
  137. "pragma", macprag,
  138. "endif", macend,
  139. 0
  140. };
  141. void
  142. domacro(void)
  143. {
  144. int i;
  145. Sym *s;
  146. s = getsym();
  147. if(s == S)
  148. s = slookup("endif");
  149. for(i=0; mactab[i].macname; i++)
  150. if(strcmp(s->name, mactab[i].macname) == 0) {
  151. if(mactab[i].macf)
  152. (*mactab[i].macf)();
  153. else
  154. macif(i);
  155. return;
  156. }
  157. yyerror("unknown #: %s", s->name);
  158. macend();
  159. }
  160. void
  161. macund(void)
  162. {
  163. Sym *s;
  164. s = getsym();
  165. macend();
  166. if(s == S) {
  167. yyerror("syntax in #undef");
  168. return;
  169. }
  170. s->macro = 0;
  171. }
  172. #define NARG 25
  173. void
  174. macdef(void)
  175. {
  176. Sym *s, *a;
  177. char *args[NARG], *np, *base;
  178. int n, i, c, len, dots;
  179. int ischr;
  180. s = getsym();
  181. if(s == S)
  182. goto bad;
  183. if(s->macro)
  184. yyerror("macro redefined: %s", s->name);
  185. c = getc();
  186. n = -1;
  187. dots = 0;
  188. if(c == '(') {
  189. n++;
  190. c = getnsc();
  191. if(c != ')') {
  192. unget(c);
  193. for(;;) {
  194. a = getsymdots(&dots);
  195. if(a == S)
  196. goto bad;
  197. if(n >= NARG) {
  198. yyerror("too many arguments in #define: %s", s->name);
  199. goto bad;
  200. }
  201. args[n++] = a->name;
  202. c = getnsc();
  203. if(c == ')')
  204. break;
  205. if(c != ',' || dots)
  206. goto bad;
  207. }
  208. }
  209. c = getc();
  210. }
  211. if(isspace(c))
  212. if(c != '\n')
  213. c = getnsc();
  214. base = hunk;
  215. len = 1;
  216. ischr = 0;
  217. for(;;) {
  218. if(isalpha(c) || c == '_') {
  219. np = symb;
  220. *np++ = c;
  221. c = getc();
  222. while(isalnum(c) || c == '_') {
  223. *np++ = c;
  224. c = getc();
  225. }
  226. *np = 0;
  227. for(i=0; i<n; i++)
  228. if(strcmp(symb, args[i]) == 0)
  229. break;
  230. if(i >= n) {
  231. i = strlen(symb);
  232. base = allocn(base, len, i);
  233. memcpy(base+len, symb, i);
  234. len += i;
  235. continue;
  236. }
  237. base = allocn(base, len, 2);
  238. base[len++] = '#';
  239. base[len++] = 'a' + i;
  240. continue;
  241. }
  242. if(ischr){
  243. if(c == '\\'){
  244. base = allocn(base, len, 1);
  245. base[len++] = c;
  246. c = getc();
  247. }else if(c == ischr)
  248. ischr = 0;
  249. }else{
  250. if(c == '"' || c == '\''){
  251. base = allocn(base, len, 1);
  252. base[len++] = c;
  253. ischr = c;
  254. c = getc();
  255. continue;
  256. }
  257. if(c == '/') {
  258. c = getc();
  259. if(c == '/'){
  260. c = getc();
  261. for(;;) {
  262. if(c == '\n')
  263. break;
  264. c = getc();
  265. }
  266. continue;
  267. }
  268. if(c == '*'){
  269. c = getc();
  270. for(;;) {
  271. if(c == '*') {
  272. c = getc();
  273. if(c != '/')
  274. continue;
  275. c = getc();
  276. break;
  277. }
  278. if(c == '\n') {
  279. yyerror("comment and newline in define: %s", s->name);
  280. break;
  281. }
  282. c = getc();
  283. }
  284. continue;
  285. }
  286. base = allocn(base, len, 1);
  287. base[len++] = '/';
  288. continue;
  289. }
  290. }
  291. if(c == '\\') {
  292. c = getc();
  293. if(c == '\n') {
  294. c = getc();
  295. continue;
  296. }
  297. else if(c == '\r') {
  298. c = getc();
  299. if(c == '\n') {
  300. c = getc();
  301. continue;
  302. }
  303. }
  304. base = allocn(base, len, 1);
  305. base[len++] = '\\';
  306. continue;
  307. }
  308. if(c == '\n')
  309. break;
  310. if(c == '#')
  311. if(n > 0) {
  312. base = allocn(base, len, 1);
  313. base[len++] = c;
  314. }
  315. base = allocn(base, len, 1);
  316. base[len++] = c;
  317. c = ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff));
  318. if(c == '\n')
  319. lineno++;
  320. if(c == -1) {
  321. yyerror("eof in a macro: %s", s->name);
  322. break;
  323. }
  324. }
  325. do {
  326. base = allocn(base, len, 1);
  327. base[len++] = 0;
  328. } while(len & 3);
  329. *base = n+1;
  330. if(dots)
  331. *base |= VARMAC;
  332. s->macro = base;
  333. if(debug['m'])
  334. print("#define %s %s\n", s->name, s->macro+1);
  335. return;
  336. bad:
  337. if(s == S)
  338. yyerror("syntax in #define");
  339. else
  340. yyerror("syntax in #define: %s", s->name);
  341. macend();
  342. }
  343. void
  344. macexpand(Sym *s, char *b)
  345. {
  346. char buf[2000];
  347. int n, l, c, nargs;
  348. char *arg[NARG], *cp, *ob, *ecp, dots;
  349. ob = b;
  350. if(*s->macro == 0) {
  351. strcpy(b, s->macro+1);
  352. if(debug['m'])
  353. print("#expand %s %s\n", s->name, ob);
  354. return;
  355. }
  356. nargs = (char)(*s->macro & ~VARMAC) - 1;
  357. dots = *s->macro & VARMAC;
  358. c = getnsc();
  359. if(c != '(')
  360. goto bad;
  361. n = 0;
  362. c = getc();
  363. if(c != ')') {
  364. unget(c);
  365. l = 0;
  366. cp = buf;
  367. ecp = cp + sizeof(buf)-4;
  368. arg[n++] = cp;
  369. for(;;) {
  370. if(cp >= ecp)
  371. goto toobig;
  372. c = getc();
  373. if(c == '"')
  374. for(;;) {
  375. if(cp >= ecp)
  376. goto toobig;
  377. *cp++ = c;
  378. c = getc();
  379. if(c == '\\') {
  380. *cp++ = c;
  381. c = getc();
  382. continue;
  383. }
  384. if(c == '\n')
  385. goto bad;
  386. if(c == '"')
  387. break;
  388. }
  389. if(c == '\'')
  390. for(;;) {
  391. if(cp >= ecp)
  392. goto toobig;
  393. *cp++ = c;
  394. c = getc();
  395. if(c == '\\') {
  396. *cp++ = c;
  397. c = getc();
  398. continue;
  399. }
  400. if(c == '\n')
  401. goto bad;
  402. if(c == '\'')
  403. break;
  404. }
  405. if(c == '/') {
  406. c = getc();
  407. switch(c) {
  408. case '*':
  409. for(;;) {
  410. c = getc();
  411. if(c == '*') {
  412. c = getc();
  413. if(c == '/')
  414. break;
  415. }
  416. }
  417. *cp++ = ' ';
  418. continue;
  419. case '/':
  420. while((c = getc()) != '\n')
  421. ;
  422. break;
  423. default:
  424. unget(c);
  425. c = '/';
  426. }
  427. }
  428. if(l == 0) {
  429. if(c == ',') {
  430. if(n == nargs && dots) {
  431. *cp++ = ',';
  432. continue;
  433. }
  434. *cp++ = 0;
  435. arg[n++] = cp;
  436. if(n > nargs)
  437. break;
  438. continue;
  439. }
  440. if(c == ')')
  441. break;
  442. }
  443. if(c == '\n')
  444. c = ' ';
  445. *cp++ = c;
  446. if(c == '(')
  447. l++;
  448. if(c == ')')
  449. l--;
  450. }
  451. *cp = 0;
  452. }
  453. if(n != nargs) {
  454. yyerror("argument mismatch expanding: %s", s->name);
  455. *b = 0;
  456. return;
  457. }
  458. cp = s->macro+1;
  459. for(;;) {
  460. c = *cp++;
  461. if(c == '\n')
  462. c = ' ';
  463. if(c != '#') {
  464. *b++ = c;
  465. if(c == 0)
  466. break;
  467. continue;
  468. }
  469. c = *cp++;
  470. if(c == 0)
  471. goto bad;
  472. if(c == '#') {
  473. *b++ = c;
  474. continue;
  475. }
  476. c -= 'a';
  477. if(c < 0 || c >= n)
  478. continue;
  479. strcpy(b, arg[c]);
  480. b += strlen(arg[c]);
  481. }
  482. *b = 0;
  483. if(debug['m'])
  484. print("#expand %s %s\n", s->name, ob);
  485. return;
  486. bad:
  487. yyerror("syntax in macro expansion: %s", s->name);
  488. *b = 0;
  489. return;
  490. toobig:
  491. yyerror("too much text in macro expansion: %s", s->name);
  492. *b = 0;
  493. }
  494. void
  495. macinc(void)
  496. {
  497. int c0, c, i, f;
  498. char str[STRINGSZ], *hp;
  499. c0 = getnsc();
  500. if(c0 != '"') {
  501. c = c0;
  502. if(c0 != '<')
  503. goto bad;
  504. c0 = '>';
  505. }
  506. for(hp = str;;) {
  507. c = getc();
  508. if(c == c0)
  509. break;
  510. if(c == '\n')
  511. goto bad;
  512. *hp++ = c;
  513. }
  514. *hp = 0;
  515. c = getcom();
  516. if(c != '\n')
  517. goto bad;
  518. f = -1;
  519. for(i=0; i<ninclude; i++) {
  520. if(i == 0 && c0 == '>')
  521. continue;
  522. strcpy(symb, include[i]);
  523. strcat(symb, "/");
  524. if(strcmp(symb, "./") == 0)
  525. symb[0] = 0;
  526. strcat(symb, str);
  527. f = open(symb, 0);
  528. if(f >= 0)
  529. break;
  530. }
  531. if(f < 0)
  532. strcpy(symb, str);
  533. c = strlen(symb) + 1;
  534. while(c & 3)
  535. c++;
  536. while(nhunk < c)
  537. gethunk();
  538. hp = hunk;
  539. memcpy(hunk, symb, c);
  540. nhunk -= c;
  541. hunk += c;
  542. newio();
  543. pushio();
  544. newfile(hp, f);
  545. return;
  546. bad:
  547. unget(c);
  548. yyerror("syntax in #include");
  549. macend();
  550. }
  551. void
  552. maclin(void)
  553. {
  554. char *cp;
  555. int c;
  556. long n;
  557. n = getnsn();
  558. c = getc();
  559. if(n < 0)
  560. goto bad;
  561. for(;;) {
  562. if(c == ' ' || c == '\t') {
  563. c = getc();
  564. continue;
  565. }
  566. if(c == '"')
  567. break;
  568. if(c == '\n') {
  569. strcpy(symb, "<noname>");
  570. goto nn;
  571. }
  572. goto bad;
  573. }
  574. cp = symb;
  575. for(;;) {
  576. c = getc();
  577. if(c == '"')
  578. break;
  579. *cp++ = c;
  580. }
  581. *cp = 0;
  582. c = getcom();
  583. if(c != '\n')
  584. goto bad;
  585. nn:
  586. c = strlen(symb) + 1;
  587. while(c & 3)
  588. c++;
  589. while(nhunk < c)
  590. gethunk();
  591. cp = hunk;
  592. memcpy(hunk, symb, c);
  593. nhunk -= c;
  594. hunk += c;
  595. linehist(cp, n);
  596. return;
  597. bad:
  598. unget(c);
  599. yyerror("syntax in #line");
  600. macend();
  601. }
  602. void
  603. macif(int f)
  604. {
  605. int c, l, bol;
  606. Sym *s;
  607. if(f == 2)
  608. goto skip;
  609. s = getsym();
  610. if(s == S)
  611. goto bad;
  612. if(getcom() != '\n')
  613. goto bad;
  614. if((s->macro != 0) ^ f)
  615. return;
  616. skip:
  617. bol = 1;
  618. l = 0;
  619. for(;;) {
  620. c = getc();
  621. if(c != '#') {
  622. if(!isspace(c))
  623. bol = 0;
  624. if(c == '\n')
  625. bol = 1;
  626. continue;
  627. }
  628. if(!bol)
  629. continue;
  630. s = getsym();
  631. if(s == S)
  632. continue;
  633. if(strcmp(s->name, "endif") == 0) {
  634. if(l) {
  635. l--;
  636. continue;
  637. }
  638. macend();
  639. return;
  640. }
  641. if(strcmp(s->name, "ifdef") == 0 || strcmp(s->name, "ifndef") == 0) {
  642. l++;
  643. continue;
  644. }
  645. if(l == 0 && f != 2 && strcmp(s->name, "else") == 0) {
  646. macend();
  647. return;
  648. }
  649. }
  650. bad:
  651. yyerror("syntax in #if(n)def");
  652. macend();
  653. }
  654. void
  655. macprag(void)
  656. {
  657. Sym *s;
  658. int c0, c;
  659. char *hp;
  660. Hist *h;
  661. s = getsym();
  662. if(s && strcmp(s->name, "lib") == 0)
  663. goto praglib;
  664. if(s && strcmp(s->name, "pack") == 0) {
  665. pragpack();
  666. return;
  667. }
  668. if(s && strcmp(s->name, "fpround") == 0) {
  669. pragfpround();
  670. return;
  671. }
  672. if(s && strcmp(s->name, "profile") == 0) {
  673. pragprofile();
  674. return;
  675. }
  676. if(s && strcmp(s->name, "varargck") == 0) {
  677. pragvararg();
  678. return;
  679. }
  680. if(s && strcmp(s->name, "incomplete") == 0) {
  681. pragincomplete();
  682. return;
  683. }
  684. while(getnsc() != '\n')
  685. ;
  686. return;
  687. praglib:
  688. c0 = getnsc();
  689. if(c0 != '"') {
  690. c = c0;
  691. if(c0 != '<')
  692. goto bad;
  693. c0 = '>';
  694. }
  695. for(hp = symb;;) {
  696. c = getc();
  697. if(c == c0)
  698. break;
  699. if(c == '\n')
  700. goto bad;
  701. *hp++ = c;
  702. }
  703. *hp = 0;
  704. c = getcom();
  705. if(c != '\n')
  706. goto bad;
  707. /*
  708. * put pragma-line in as a funny history
  709. */
  710. c = strlen(symb) + 1;
  711. while(c & 3)
  712. c++;
  713. while(nhunk < c)
  714. gethunk();
  715. hp = hunk;
  716. memcpy(hunk, symb, c);
  717. nhunk -= c;
  718. hunk += c;
  719. h = alloc(sizeof(Hist));
  720. h->name = hp;
  721. h->line = lineno;
  722. h->offset = -1;
  723. h->link = H;
  724. if(ehist == H) {
  725. hist = h;
  726. ehist = h;
  727. return;
  728. }
  729. ehist->link = h;
  730. ehist = h;
  731. return;
  732. bad:
  733. unget(c);
  734. yyerror("syntax in #pragma lib");
  735. macend();
  736. }
  737. void
  738. macend(void)
  739. {
  740. int c;
  741. for(;;) {
  742. c = getnsc();
  743. if(c < 0 || c == '\n')
  744. return;
  745. }
  746. }
  747. void
  748. linehist(char *f, int offset)
  749. {
  750. Hist *h;
  751. /*
  752. * overwrite the last #line directive if
  753. * no alloc has happened since the last one
  754. */
  755. if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0)
  756. if(f && ehist->name && strcmp(f, ehist->name) == 0) {
  757. ehist->line = lineno;
  758. ehist->offset = offset;
  759. return;
  760. }
  761. if(debug['f'])
  762. if(f) {
  763. if(offset)
  764. print("%4ld: %s (#line %d)\n", lineno, f, offset);
  765. else
  766. print("%4ld: %s\n", lineno, f);
  767. } else
  768. print("%4ld: <pop>\n", lineno);
  769. newflag = 0;
  770. h = alloc(sizeof(Hist));
  771. h->name = f;
  772. h->line = lineno;
  773. h->offset = offset;
  774. h->link = H;
  775. if(ehist == H) {
  776. hist = h;
  777. ehist = h;
  778. return;
  779. }
  780. ehist->link = h;
  781. ehist = h;
  782. }
  783. void
  784. gethunk(void)
  785. {
  786. char *h;
  787. long nh;
  788. nh = NHUNK;
  789. if(thunk >= 10L*NHUNK)
  790. nh = 10L*NHUNK;
  791. h = (char*)mysbrk(nh);
  792. if(h == (char*)-1) {
  793. yyerror("out of memory");
  794. errorexit();
  795. }
  796. hunk = h;
  797. nhunk = nh;
  798. thunk += nh;
  799. }