Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1633 lines
53 KiB

  1. /***********************************************************************
  2. * Microsoft (R) Windows (R) Resource Compiler
  3. *
  4. * Copyright (c) Microsoft Corporation. All rights reserved.
  5. *
  6. * File Comments:
  7. *
  8. *
  9. ***********************************************************************/
  10. #include "rc.h"
  11. /************************************************************************
  12. **
  13. ** WARNING: gather_chars() depends ELIMIT being the boundary of
  14. ** Macro_buffer.
  15. ************************************************************************/
  16. #define ACT_BUFFER &Macro_buffer[0]
  17. #define EXP_BUFFER &Macro_buffer[BIG_BUFFER * 2]
  18. #define EXP_PAD 5
  19. #define ALIMIT &Macro_buffer[BIG_BUFFER * 2]
  20. #define ELIMIT (&Macro_buffer[BIG_BUFFER * 4] - EXP_PAD)
  21. /************************************************************************
  22. ** actual argument lists are length preceeded strings which are copied
  23. ** into ACT_BUFFER. the first argument is pt'd to by exp_actuals in the
  24. ** expansion_t construct. the next actual is obtained by adding the length
  25. ** of the current actual to the start of the current actual.
  26. ************************************************************************/
  27. #define ACTUAL_SIZE(P) (*(short *)(P))
  28. #define ACTUAL_TEXT(P) ((ptext_t)(((char *)(P)) + sizeof(short)))
  29. #define ACTUAL_NEXT(P) ((ptext_t)(((char *)(P)) + ACTUAL_SIZE(P)))
  30. expansion_t Macro_expansion[LIMIT_MACRO_DEPTH];
  31. ptext_t P_defn_start;
  32. int N_formals;
  33. pdefn_t Defn_level_0[LEVEL_0 + 1];
  34. /************************************************************************
  35. ** These are needed by p0scanner (Exp_ptr,Tiny_lexer_nesting)
  36. ************************************************************************/
  37. ptext_t Exp_ptr = EXP_BUFFER; /* ptr to free exp space */
  38. int Tiny_lexer_nesting; /* stay in tiny lexer or back to main */
  39. static ptext_t Act_ptr = ACT_BUFFER; /* ptr to free actuals space */
  40. static ptext_t Save_Exp_ptr = EXP_BUFFER; /* for buffering unbal parens */
  41. static ptext_t P_actuals; /* actuals for this (level) macro */
  42. static int N_actuals; /* number of actuals in invocation */
  43. static int Macro_line; /* where we started the macro */
  44. /************************************************************************/
  45. /* Local Function Prototypes */
  46. /************************************************************************/
  47. void chkbuf(ptext_t);
  48. ptext_t do_strformal(void);
  49. ptext_t do_macformal(int *);
  50. void expand_actual(UCHAR);
  51. void expand_definition(void);
  52. void expand_macro(void);
  53. void fatal_in_macro(int);
  54. ptext_t gather_chars(ptext_t, WCHAR);
  55. void get_actuals(pdefn_t, int);
  56. int get_definition(void);
  57. void get_formals(void);
  58. int is_macro_arg(ptext_t);
  59. void move_to_actual(ptext_t, ptext_t);
  60. void move_to_exp(ptext_t);
  61. void move_to_exp_esc(int, ptext_t);
  62. int post_paste(void);
  63. void push_macro(pdefn_t);
  64. int redefn (ptext_t, ptext_t, int);
  65. int rescan_expansion(void);
  66. /************************************************************************
  67. ** UNDEFINE - remove a symbol from the symbol table
  68. ** No noise is made if the programmer attempts to undefine a predefined
  69. ** macro, but it is not done.
  70. ************************************************************************/
  71. void
  72. undefine(
  73. void
  74. )
  75. {
  76. pdefn_t pdef;
  77. pdefn_t prev;
  78. prev = NULL;
  79. pdef = Defn_level_0[Reuse_W_hash & LEVEL_0];
  80. while(pdef) {
  81. if(memcmp (Reuse_W, DEFN_IDENT(pdef), Reuse_W_length * sizeof(WCHAR)) == 0) {
  82. if(PRE_DEFINED(pdef)) {
  83. warning(4117, Reuse_W, L"#undef");
  84. break;
  85. }
  86. if(prev == NULL) /* match at head of list */
  87. Defn_level_0[Reuse_W_hash & LEVEL_0] = DEFN_NEXT(pdef);
  88. else
  89. DEFN_NEXT(prev) = DEFN_NEXT(pdef);
  90. if (wcscmp(DEFN_NAME(pdef), afxSzHiddenSymbols) == 0)
  91. afxHiddenSymbols = FALSE;
  92. if (wcscmp(DEFN_NAME(pdef), afxSzReadOnlySymbols) == 0)
  93. afxReadOnlySymbols = FALSE;
  94. break;
  95. }
  96. prev = pdef;
  97. pdef = DEFN_NEXT(pdef);
  98. }
  99. }
  100. /************************************************************************
  101. ** BEGIN DEFINE A MACRO {
  102. ************************************************************************/
  103. void
  104. define(
  105. void
  106. )
  107. {
  108. WCHAR c;
  109. if (! (LX_IS_IDENT(c = skip_cwhite())) ) {
  110. error(2007); /* #define syntax */
  111. skip_cnew();
  112. return;
  113. }
  114. getid(c);
  115. N_formals = 0;
  116. P_defn_start = Macro_buffer;
  117. /*
  118. ** the next character must be white space or an open paren
  119. */
  120. first_switch:
  121. switch(CHARMAP(c = GETCH())) {
  122. case LX_OPAREN: /* we have formal parameters */
  123. get_formals(); /* changes N_formals and fills Macro_buffer */
  124. if(N_formals == 0) { /* empty formal list */
  125. /*
  126. ** we must special case this since the expand() reads in the
  127. ** actual arguments iff there are formal parameters. thus if we
  128. ** #define foo() bar()
  129. ** . . .
  130. ** foo()
  131. ** will expand as
  132. ** bar()()
  133. ** we put the right paren in to fool the expander into looking
  134. ** for actuals.
  135. */
  136. N_formals = -1;
  137. }
  138. break;
  139. case LX_WHITE:
  140. break;
  141. case LX_CR:
  142. goto first_switch;
  143. case LX_SLASH:
  144. if( ! skip_comment()) {
  145. error(2008, L'/');
  146. }
  147. break;
  148. case LX_NL: /* no definition */
  149. UNGETCH();
  150. definstall((ptext_t)0, 0, 0);
  151. return;
  152. break;
  153. case LX_EOS:
  154. if(handle_eos() != BACKSLASH_EOS) {
  155. goto first_switch;
  156. }
  157. /* got BACKSLASH_EOS */
  158. /*
  159. ** FALLTHROUGH
  160. */
  161. default:
  162. error(2008, c); /* unexpected character in macro definition */
  163. }
  164. definstall(P_defn_start, get_definition(), N_formals);
  165. }
  166. /************************************************************************
  167. ** get_formals : collect comma separated idents until the first closing paren
  168. ** (the openning paren has already been read)
  169. ** since we can't be in a macro when we're asked for this, we can be assured
  170. ** that we can use a single buffer to collect all the formal names.
  171. ************************************************************************/
  172. void
  173. get_formals(
  174. void
  175. )
  176. {
  177. WCHAR c;
  178. ptext_t p_stop;
  179. ptext_t p_id;
  180. p_id = p_stop = ACTUAL_TEXT(P_defn_start);
  181. for(;;) {
  182. switch(CHARMAP(c = skip_cwhite())) {
  183. case LX_ID:
  184. if( p_id != p_stop ) {
  185. error(2010, c);
  186. }
  187. *p_stop++ = c;
  188. for(;;) {
  189. while(LXC_IS_IDENT(c = GETCH())) { /* while an id char */
  190. *p_stop++ = c; /* collect it */
  191. } if(c == EOS_CHAR) {
  192. /*
  193. ** found end of buffer marker, make sure it is,
  194. ** then handle it.
  195. */
  196. if(io_eob()) { /* end of buffer in here is bad */
  197. fatal(1004);
  198. }
  199. continue;
  200. }
  201. if((c == L'\\') && (checknl())) {
  202. continue;
  203. }
  204. UNGETCH();
  205. break;
  206. }
  207. *p_stop++ = L'\0';
  208. break;
  209. case LX_COMMA:
  210. case LX_CPAREN:
  211. if( p_stop > p_id ) {
  212. /* make sure an identifier was read */
  213. if((p_stop - p_id) >= TINY_BUFFER) {
  214. p_id[TINY_BUFFER - 1] = L'\0';
  215. warning(4011); /* id truncated */
  216. p_stop = p_id + TINY_BUFFER;
  217. }
  218. if(is_macro_arg(p_id) >= 1) {
  219. error(2009, p_id); /* reuse of formal */
  220. } else {
  221. ACTUAL_SIZE(P_defn_start) = (short)(p_stop - P_defn_start) * sizeof(WCHAR);
  222. P_defn_start = p_stop;
  223. N_formals++;
  224. }
  225. } else {
  226. if( (CHARMAP(c) == LX_COMMA) || (N_formals > 0) ) {
  227. error(2010, c);
  228. }
  229. }
  230. if( CHARMAP(c) == LX_CPAREN ) {
  231. return;
  232. }
  233. p_id = p_stop = ACTUAL_TEXT(P_defn_start);
  234. break;
  235. default:
  236. error(2010, c); /* unexpected char in formal list */
  237. break;
  238. }
  239. }
  240. }
  241. /************************************************************************
  242. ** definstall - Install a new definition. id is in Reuse_W.
  243. ** p_text : ptr to the definition
  244. ** n : number of bytes in the definition (may contain embedded nulls)
  245. ** number : number of formals
  246. ************************************************************************/
  247. void
  248. definstall(
  249. WCHAR * p_text,
  250. int n,
  251. int number
  252. )
  253. {
  254. pdefn_t p;
  255. if(n == 0) {
  256. p_text = NULL;
  257. }
  258. if( wcscmp (Reuse_W, L"defined") == 0) {
  259. warning(4117, Reuse_W, L"#define");/* name reserved */
  260. return;
  261. }
  262. if((p = get_defined()) != 0) {
  263. if(PRE_DEFINED(p)) {
  264. warning(4117, Reuse_W, L"#define");/* name reserved */
  265. return;
  266. } else {
  267. if(redefn(p_text, DEFN_TEXT(p), n)) {
  268. warning(4005, Reuse_W);/* redefinition */
  269. } else {
  270. return;
  271. }
  272. }
  273. } else {
  274. hln_t ident;
  275. HLN_NAME(ident) = Reuse_W;
  276. HLN_HASH(ident) = Reuse_W_hash;
  277. HLN_LENGTH(ident) = (UINT)Reuse_W_length;
  278. p = (pdefn_t) MyAlloc(sizeof(defn_t));
  279. if (p == NULL) {
  280. error(1002);
  281. return;
  282. }
  283. DEFN_IDENT(p) = HLN_TO_NAME(&ident);
  284. DEFN_NEXT(p) = Defn_level_0[Reuse_W_hash & LEVEL_0];
  285. DEFN_TEXT(p) = (WCHAR*)NULL;
  286. DEFN_EXPANDING(p) = 0;
  287. Defn_level_0[Reuse_W_hash & LEVEL_0] = p;
  288. }
  289. if(n != 0) {
  290. DEFN_TEXT(p) = pstrndup(p_text, n);
  291. if(number == FROM_COMMAND) { /* special case from cmd line */
  292. *(DEFN_TEXT(p) + n - 1) = EOS_DEFINITION; /* for handle_eos */
  293. }
  294. }
  295. DEFN_NFORMALS(p) = (char)((number != FROM_COMMAND) ? number : 0);
  296. if (fAFXSymbols && !PRE_DEFINED(p) && DEFN_NFORMALS(p) == 0)
  297. AfxOutputMacroDefn(p);
  298. }
  299. /************************************************************************
  300. ** get_defined : is the given id in the macro symbol table?
  301. ** return a ptr to it if so, NULL if not.
  302. ************************************************************************/
  303. pdefn_t
  304. get_defined(
  305. void
  306. )
  307. {
  308. pdefn_t pdef;
  309. for( pdef = Defn_level_0[Reuse_W_hash & LEVEL_0]; pdef;
  310. pdef = DEFN_NEXT(pdef)) {
  311. if(memcmp (Reuse_W, DEFN_IDENT(pdef), Reuse_W_length * sizeof(WCHAR)) == 0) {
  312. return(pdef);
  313. }
  314. }
  315. return(NULL);
  316. }
  317. /************************************************************************
  318. ** redefn : are the two definitions the same?
  319. ************************************************************************/
  320. int
  321. redefn(
  322. REG PWCHAR p_new,
  323. PWCHAR p_old,
  324. int n
  325. )
  326. {
  327. if(p_old && p_new) {
  328. if(wcsncmp(p_new, p_old, n) == 0) { /* strings are exact */
  329. return(FALSE);
  330. }
  331. return(TRUE);
  332. }
  333. return((p_old != NULL) || (p_new != NULL));
  334. }
  335. /************************************************************************
  336. ** get_definition : accumulate the macro definition, stops when it finds
  337. ** a newline (it uses it). returns a ptr to the end of the string it builds.
  338. ** builds the string in Macro_buffer. (given the start in P_defn_start)
  339. ************************************************************************/
  340. int
  341. get_definition(
  342. void
  343. )
  344. {
  345. REG ptext_t p;
  346. WCHAR c;
  347. int stringize = FALSE;
  348. int charize = FALSE;
  349. p = P_defn_start;
  350. c = skip_cwhite();
  351. for(;;) {
  352. chkbuf(p);
  353. switch(CHARMAP(c)) {
  354. case LX_EOS:
  355. if(handle_eos() == BACKSLASH_EOS) {
  356. /* got backslash EOS */
  357. /* \<anything else> goes out as is. The <anything else>
  358. * character must be emitted now, so that
  359. * #define FOO(name) \name
  360. * . . .
  361. * FOO(bar)
  362. *
  363. * does NOT see occurence of name in the definition as an
  364. * occurence of the formal param and emit \bar when it is
  365. * expanded later,but if the definition is \nname it will
  366. * find name as a formal paramater and emit \nbar
  367. */
  368. *p++ = c; /* put in backslash, break'll add new char */
  369. c = get_non_eof();
  370. } else {
  371. c = GETCH();
  372. continue;
  373. }
  374. break;
  375. case LX_NL: /* only way out */
  376. UNGETCH();
  377. if(p == P_defn_start) {
  378. return(0);
  379. }
  380. chkbuf(p);
  381. *p++ = EOS_CHAR;
  382. *p++ = EOS_DEFINITION; /* tells handle_eos defn finished */
  383. return((int)(p - P_defn_start));/* p's last incr counts the 0*/
  384. break;
  385. case LX_DQUOTE:
  386. case LX_SQUOTE:
  387. p = gather_chars(p, c);
  388. c = GETCH();
  389. continue;
  390. break;
  391. case LX_POUND:
  392. split_op:
  393. switch(CHARMAP(GETCH())) {
  394. case LX_POUND:
  395. /*
  396. ** handle ## processing. cant be the first or the last.
  397. */
  398. if(p == P_defn_start) {
  399. error(2160); /* ## not allowed as first entry */
  400. continue;
  401. }
  402. if(*(p - 1) == L' ') { /* hose the last blank */
  403. p--;
  404. }
  405. if(CHARMAP(c = skip_cwhite()) == LX_NL) {
  406. UNGETCH();
  407. error(2161);
  408. continue;
  409. }
  410. /* this case does *not* fall through to LX_ID */
  411. continue;
  412. break;
  413. case LX_EACH:
  414. charize = TRUE;
  415. break;
  416. case LX_EOS:
  417. if( handle_eos() != BACKSLASH_EOS ) {
  418. goto split_op;
  419. }
  420. /*
  421. ** FALLTHROUGH
  422. */
  423. default:
  424. UNGETCH();
  425. stringize = TRUE;
  426. break;
  427. }
  428. if(CHARMAP(c = skip_cwhite()) != LX_ID) {
  429. error(2162); /* must have id following */
  430. continue;
  431. }
  432. /*
  433. ** FALLTHROUGH
  434. */
  435. case LX_ID:
  436. {
  437. /* we have the start of an identifier - check it to see if
  438. * its an occurence of a formal parameter name.
  439. * we gather the id ourselves (instead of getid()) since this
  440. * wil save us from having to copy it to our string if it's
  441. * not a formal parameter.
  442. */
  443. int n;
  444. ptext_t p_macformal;
  445. p_macformal = p;
  446. do {
  447. chkbuf(p);
  448. *p++ = c;
  449. get_more_id:
  450. c = GETCH();
  451. } while(LXC_IS_IDENT(c));
  452. if(CHARMAP(c) == LX_EOS) {
  453. if(handle_eos() != BACKSLASH_EOS) {
  454. goto get_more_id;
  455. }
  456. }
  457. *p = L'\0'; /* term. string, but do not advance ptr */
  458. if((n = is_macro_arg(p_macformal)) >= 1) {
  459. /*
  460. ** this is an occurance of formal 'n', replace the id with
  461. ** the special MAC character.
  462. */
  463. p = p_macformal;
  464. if(stringize) {
  465. *p++ = LX_FORMALSTR;
  466. } else {
  467. if(charize) {
  468. *p++ = LX_FORMALCHAR;
  469. } else {
  470. *p++ = LX_FORMALMARK;
  471. }
  472. }
  473. *p++ = (WCHAR) n;
  474. } else if(charize || stringize) {
  475. error(2162);
  476. }
  477. stringize = FALSE;
  478. charize = FALSE;
  479. continue; /* we broke out of the loop with a new char */
  480. }
  481. case LX_SLASH:
  482. if( ! skip_comment() ) { /* really is a slash */
  483. break;
  484. }
  485. /*
  486. ** FALLTHROUGH
  487. */
  488. case LX_CR:
  489. case LX_WHITE:
  490. /*
  491. ** this is white space, all contiguous whitespace is transformed
  492. ** to 1 blank. (hence the skip_cwhite() and the continue).
  493. */
  494. if(CHARMAP(c = skip_cwhite()) != LX_NL) {
  495. *p++ = L' ';
  496. }
  497. continue; /* restart loop */
  498. case LX_ILL:
  499. error(2018, c);
  500. c = GETCH();
  501. continue;
  502. }
  503. *p++ = c;
  504. c = GETCH();
  505. }
  506. }
  507. /************************************************************************/
  508. /* is_macro_arg () */
  509. /************************************************************************/
  510. int
  511. is_macro_arg(
  512. ptext_t name
  513. )
  514. {
  515. REG int i;
  516. REG ptext_t p;
  517. p = Macro_buffer;
  518. for(i = 1; i <= N_formals; i++) {
  519. if( wcscmp(name, ACTUAL_TEXT(p)) == 0) {
  520. return(i);
  521. }
  522. p = ACTUAL_NEXT(p);
  523. }
  524. return(-1);
  525. }
  526. /************************************************************************/
  527. /* chkbuf () */
  528. /************************************************************************/
  529. void
  530. chkbuf(
  531. ptext_t p
  532. )
  533. {
  534. if( p >= ELIMIT ) {
  535. fatal(1011, Reuse_W);
  536. }
  537. }
  538. /************************************************************************
  539. ** gather_chars : collect chars until a matching one is found.
  540. ** skip backslashed chars. moves the chars into the buffer,
  541. ** returns a ptr past the last char copied.
  542. ************************************************************************/
  543. ptext_t
  544. gather_chars(
  545. REG ptext_t p,
  546. WCHAR match_c
  547. )
  548. {
  549. WCHAR c;
  550. *p++ = match_c;
  551. for(;;) {
  552. if(p > ELIMIT) {
  553. return(ELIMIT);
  554. }
  555. switch(CHARMAP(c = GETCH())) {
  556. case LX_NL:
  557. error(2001);
  558. UNGETCH();
  559. c = match_c;
  560. /*
  561. ** FALLTHROUGH
  562. */
  563. case LX_DQUOTE:
  564. case LX_SQUOTE:
  565. if(c == match_c) {
  566. *p++ = c;
  567. return(p); /* only way out */
  568. }
  569. break;
  570. case LX_EOS:
  571. if(handle_eos() != BACKSLASH_EOS) {
  572. continue;
  573. } else {
  574. /* got backslash */
  575. *p++ = L'\\';
  576. c = get_non_eof();
  577. if((c == '\\') && (checknl())) {
  578. continue;
  579. }
  580. }
  581. break;
  582. }
  583. *p++ = c;
  584. }
  585. }
  586. /************************************************************************
  587. ** END DEFINING MACROS }
  588. ************************************************************************/
  589. /************************************************************************
  590. ** BEGIN EXPANDING MACROS {
  591. ************************************************************************/
  592. /************************************************************************
  593. ** can_expand: tries to expand the macro passed to it - returns
  594. ** true if it succeeded in expanding it. It will only return FALSE
  595. ** if a macro name was found, a paren was expected, and a paren was
  596. ** not the next non white character.
  597. ************************************************************************/
  598. int
  599. can_expand(
  600. pdefn_t pdef
  601. )
  602. {
  603. WCHAR c;
  604. int n_formals;
  605. int return_value = FALSE;
  606. Tiny_lexer_nesting = 0;
  607. Save_Exp_ptr = Exp_ptr; /* not necessarily EXP_BUFFER */
  608. Macro_line = Linenumber;
  609. expand_name:
  610. P_actuals = Act_ptr;
  611. N_actuals = 0;
  612. n_formals = DEFN_NFORMALS(pdef);
  613. if( PRE_DEFINED(pdef) ) {
  614. push_macro(pdef);
  615. DEFN_EXPANDING(CURRENT_MACRO)++;
  616. if(rescan_expansion()) {
  617. return(TRUE); /* could expand macro */
  618. }
  619. }
  620. else if( n_formals == 0 ) {
  621. return_value = TRUE;
  622. if(DEFN_TEXT(pdef)) {
  623. push_macro(pdef);
  624. expand_definition();
  625. } else {
  626. /*
  627. ** Macro expands to nothing (no definition). Since it
  628. ** didn't have any actuals, Act_ptr is already correct.
  629. ** Exp_ptr must be changed however to delete the
  630. ** identifier from the expanded text.
  631. */
  632. Exp_ptr = Save_Exp_ptr;
  633. }
  634. } else {
  635. if( n_formals == -1 ) {
  636. n_formals = 0;
  637. }
  638. name_comment_paren:
  639. if( can_get_non_white()) {
  640. if(CHARMAP(CHECKCH()) == LX_SLASH) {
  641. SKIPCH();
  642. if(skip_comment()) {
  643. goto name_comment_paren;
  644. } else {
  645. UNGETCH();
  646. }
  647. }
  648. if(CHARMAP(CHECKCH())==LX_OPAREN) {
  649. SKIPCH();
  650. return_value = TRUE;
  651. get_actuals(pdef, n_formals);
  652. } else {
  653. /*
  654. ** #define xx(a) a
  655. ** xx bar();
  656. ** don't lose white space between "xx" and "bar"
  657. */
  658. ptext_t p = Exp_ptr;
  659. push_macro(pdef);
  660. DEFN_EXPANDING(CURRENT_MACRO)++;
  661. Exp_ptr = p;
  662. if( rescan_expansion() ) {
  663. return(FALSE);
  664. }
  665. }
  666. } else {
  667. }
  668. }
  669. /*
  670. ** makes sure a macro is being worked on. At this point, there will
  671. ** be a macro to expand, unless the macro expand_the_named_macro was
  672. ** passed had no definition text. If it had no defintion text,
  673. ** Tiny_lexer_nesting was not incremented.
  674. */
  675. while(Tiny_lexer_nesting != 0) {
  676. if(Exp_ptr >= ELIMIT) {
  677. fatal_in_macro(10056);
  678. }
  679. switch(CHARMAP(c = GETCH())) {
  680. case LX_ID:
  681. case LX_MACFORMAL:
  682. Save_Exp_ptr = Exp_ptr;
  683. if(tl_getid(c) && ((pdef = get_defined())!= 0)) {
  684. if(DEFN_EXPANDING(pdef)) {
  685. /*
  686. ** the macro is already being expanded, so just
  687. ** write the do not expand marker and the
  688. ** identifier to the expand area. The do not
  689. ** expand marker is necessary so this macro
  690. ** doesn't get expanded on the rescan
  691. */
  692. int len = Reuse_W_length - 1;
  693. *Exp_ptr++ = LX_NOEXPANDMARK;
  694. *Exp_ptr++ = ((WCHAR)len);
  695. } else {
  696. /*
  697. ** a legal identifier was read, it is defined, and
  698. ** it is not currently being expanded. This means
  699. ** there is reason to believe it can be expanded.
  700. */
  701. goto expand_name;
  702. }
  703. }
  704. if(InIf &&(memcmp(Reuse_W, L"defined", 8 * sizeof(WCHAR)) ==0)) {
  705. do_defined(Reuse_W);
  706. }
  707. continue;
  708. break;
  709. case LX_NUMBER:
  710. /* getnum with Prep on to keep leading 0x on number */
  711. {
  712. int Save_prep = Prep;
  713. Prep = TRUE;
  714. getnum(c);
  715. Prep = Save_prep;
  716. }
  717. continue;
  718. break;
  719. case LX_DOT:
  720. *Exp_ptr++ = L'.';
  721. dot_switch:
  722. switch(CHARMAP(c = GETCH())) {
  723. case LX_EOS:
  724. if(handle_eos() != BACKSLASH_EOS) {
  725. if(Tiny_lexer_nesting > 0) {
  726. goto dot_switch;
  727. }
  728. continue;
  729. }
  730. break;
  731. case LX_DOT:
  732. *Exp_ptr++ = L'.';
  733. if( ! checkop(L'.')) {
  734. break; /* error will be caught on rescan */
  735. }
  736. *Exp_ptr++ = L'.';
  737. continue;
  738. break;
  739. case LX_NUMBER:
  740. *Exp_ptr++ = c;
  741. get_real(Exp_ptr);
  742. continue;
  743. }
  744. UNGETCH();
  745. continue;
  746. case LX_CHARFORMAL:
  747. move_to_exp_esc(L'\'', do_strformal());
  748. continue;
  749. break;
  750. case LX_STRFORMAL:
  751. move_to_exp_esc(L'"', do_strformal());
  752. continue;
  753. break;
  754. case LX_DQUOTE:
  755. case LX_SQUOTE:
  756. /*
  757. ** gather_chars is called even though the error reported
  758. ** on overflow may need to be changed.
  759. */
  760. Exp_ptr = gather_chars(Exp_ptr, c);
  761. continue;
  762. break;
  763. case LX_WHITE:
  764. while(LXC_IS_WHITE(GETCH())) {
  765. ;
  766. }
  767. UNGETCH();
  768. c = L' ';
  769. break;
  770. case LX_EOS:
  771. if(handle_eos() == BACKSLASH_EOS) {
  772. *Exp_ptr++ = c;
  773. c = GETCH();
  774. break;
  775. }
  776. continue;
  777. break;
  778. }
  779. *Exp_ptr++ = c;
  780. }
  781. return(return_value);
  782. }
  783. /************************************************************************
  784. ** get_actuals : Paren must already be found. If all the actuals can
  785. ** be read, the macro is pushed and expansion begins. Otherwise,
  786. ** this function is quickly exited and lets the tiny lexer take
  787. ** care of rescanning.
  788. ************************************************************************/
  789. void
  790. get_actuals(
  791. pdefn_t pdef,
  792. int n_formals
  793. )
  794. {
  795. /*
  796. ** The only concern with this is that a rescan could finish while
  797. ** this is trying to collect actuals. When a rescan finishes, it
  798. ** may reset Act_ptr and Exp_ptr. Unless these are saved before the
  799. ** end of rescan is handled, the part of the actual collected so far
  800. ** would be lost.
  801. */
  802. REG ptext_t start;
  803. WCHAR c;
  804. ptext_t actuals_start;
  805. int paste;
  806. int level;
  807. *Exp_ptr++ = PREVCH(); /* must be oparen */
  808. level = 0;
  809. actuals_start = Act_ptr;
  810. while( level >= 0) {
  811. if(Exp_ptr >= ELIMIT) {
  812. fatal_in_macro(10056);
  813. }
  814. more_white:
  815. if( ! can_get_non_white()) {
  816. return;
  817. }
  818. if(CHARMAP(CHECKCH()) == LX_SLASH) {
  819. SKIPCH();
  820. if(skip_comment()) {
  821. goto more_white;
  822. } else {
  823. start = Exp_ptr;
  824. *Exp_ptr++ = L'/';
  825. }
  826. } else {
  827. start = Exp_ptr;
  828. }
  829. paste = FALSE;
  830. for(;;) {
  831. switch(CHARMAP(c = GETCH())) {
  832. case LX_CPAREN:
  833. if(--level < 0) {
  834. goto leave_loop;
  835. }
  836. break;
  837. case LX_COMMA:
  838. /*
  839. ** if the comma is not at level == 0, it is part of
  840. ** a parenthesized list and not a delimiter
  841. */
  842. if(level == 0) {
  843. goto leave_loop;
  844. }
  845. break;
  846. case LX_SLASH:
  847. if( ! skip_comment()) {
  848. break;
  849. }
  850. if(*(Exp_ptr - 1) == L' ') {
  851. continue;
  852. }
  853. c = L' ';
  854. break;
  855. case LX_CR:
  856. case LX_NL:
  857. case LX_WHITE:
  858. UNGETCH(); /* This char is valid white space */
  859. if( ! can_get_non_white()) {
  860. return;
  861. }
  862. continue;
  863. break;
  864. case LX_OPAREN:
  865. ++level;
  866. break;
  867. case LX_DQUOTE:
  868. case LX_SQUOTE:
  869. Exp_ptr = gather_chars(Exp_ptr, c);
  870. continue;
  871. break;
  872. case LX_ID:
  873. *Exp_ptr++ = c;
  874. while(LXC_IS_IDENT(c = GETCH())) {
  875. if(Exp_ptr >= ELIMIT) {
  876. fatal_in_macro(10056);
  877. }
  878. *Exp_ptr++ = c;
  879. }
  880. if(CHARMAP(c) != LX_MACFORMAL) {
  881. UNGETCH();
  882. continue;
  883. }
  884. paste = TRUE;
  885. /*
  886. ** FALLTHROUGH
  887. */
  888. case LX_MACFORMAL:
  889. move_to_exp(do_macformal(&paste));
  890. continue;
  891. break;
  892. case LX_STRFORMAL:
  893. move_to_exp_esc(L'"', do_strformal());
  894. continue;
  895. break;
  896. case LX_CHARFORMAL:
  897. move_to_exp_esc(L'\'', do_strformal());
  898. continue;
  899. break;
  900. case LX_EOS:
  901. /*
  902. ** Will saving this pointers create dead space in the
  903. ** buffers? Yes, but only temporarily.
  904. **
  905. ** handle_eos() may reset Act_ptr and Exp_ptr to the
  906. ** beginning of the buffers if a rescan is finishing
  907. ** and Macro_depth is going to be 0. ANSI allows
  908. ** actuals to start within a macro defintion and be
  909. ** completed (further actuals and closing paren) later
  910. ** in the text.
  911. **
  912. ** These buffer pointers will eventually be reset to
  913. ** the beginnings of their respective buffers when the
  914. ** macro for the actuals being collected right now
  915. ** finish rescan
  916. **
  917. ** This is special handling for folks who use
  918. ** unbalanced parens in macro definitions
  919. */
  920. {
  921. ptext_t Exp_save;
  922. ptext_t Act_save;
  923. int eos_res;
  924. Exp_save = Exp_ptr;
  925. Act_save = Act_ptr;
  926. if((eos_res = handle_eos()) & (ACTUAL_EOS | RESCAN_EOS)) {
  927. return;
  928. }
  929. Act_ptr = Act_save;
  930. Exp_ptr = Exp_save;
  931. if(eos_res == BACKSLASH_EOS) { /* ??? DFP QUESTION */
  932. *Exp_ptr++ = c; /* save the \ */
  933. c = get_non_eof(); /* get char following \ */
  934. break;
  935. }
  936. }
  937. continue;
  938. break;
  939. }
  940. *Exp_ptr++ = c;
  941. }
  942. leave_loop:
  943. /*
  944. ** if the last character was whitespace, hose it
  945. */
  946. if(CHARMAP(*(Exp_ptr - 1)) == LX_WHITE) {
  947. Exp_ptr--;
  948. }
  949. /*
  950. ** if Exp_ptr <= start, foo() was read, don't incr N_actuals
  951. */
  952. if(Exp_ptr > start) {
  953. N_actuals++;
  954. move_to_actual(start, Exp_ptr);
  955. }
  956. *Exp_ptr++ = c;
  957. }
  958. P_actuals = actuals_start;
  959. if(n_formals < N_actuals) {
  960. warning(4002, Reuse_W);
  961. }
  962. else if(n_formals > N_actuals) {
  963. warning(4003, Reuse_W);
  964. }
  965. if(DEFN_TEXT(pdef)) {
  966. push_macro(pdef);
  967. expand_macro();
  968. } else {
  969. /*
  970. ** the macro expands to nothing (no definition)
  971. ** This essentially means delete the macro and its actuals
  972. ** from the expanded text
  973. */
  974. Act_ptr = P_actuals; /* reset pointer to get rid of actuals */
  975. Exp_ptr = Save_Exp_ptr; /* delete macro & actuals from exp text */
  976. }
  977. }
  978. /************************************************************************
  979. ** rescan_expansion: pops a level off of tiny lexer. If this is the
  980. ** original macro called, the rescan is set up, otherwise the MACRO
  981. ** (not only the tiny lexer level) is popped.
  982. ************************************************************************/
  983. int
  984. rescan_expansion(
  985. void
  986. )
  987. {
  988. if(--Tiny_lexer_nesting == 0) {
  989. if(Exp_ptr >= ELIMIT) {
  990. fatal_in_macro(10056);
  991. }
  992. if (fAFXSymbols && !InIf && (DEFN_NFORMALS(CURRENT_MACRO)==0))
  993. AfxOutputMacroUse(CURRENT_MACRO);
  994. *Exp_ptr++ = EOS_CHAR;
  995. *Exp_ptr++ = EOS_RESCAN;
  996. Current_char = CURRENT_TEXT;
  997. return(TRUE); /* rescan the expanded text */
  998. } else {
  999. /* reset Current_char, pop the macro */
  1000. Current_char = CURRENT_STRING;
  1001. Act_ptr = CURRENT_ACTUALS; /* don't need its actuals */
  1002. DEFN_EXPANDING(CURRENT_MACRO)--;
  1003. --Macro_depth;
  1004. return(FALSE); /* do not rescan expanded text */
  1005. }
  1006. }
  1007. /************************************************************************
  1008. ** move_to_actual: moves the string located between start and finish
  1009. ** inclusive to the current location in ACT_BUFFER as a new actual.
  1010. ************************************************************************/
  1011. void
  1012. move_to_actual(
  1013. ptext_t start,
  1014. ptext_t finish
  1015. )
  1016. {
  1017. REG ptext_t p;
  1018. REG int len;
  1019. len = (int)(finish - start);
  1020. if(Act_ptr + len >= ALIMIT - 2) {
  1021. fatal_in_macro(10056);
  1022. }
  1023. wcsncpy(ACTUAL_TEXT(Act_ptr), start, len);
  1024. p = ACTUAL_TEXT(Act_ptr);
  1025. p += len;
  1026. if ((((ULONG_PTR)p) & 1) == 0) {
  1027. *p++ = EOS_CHAR;
  1028. *p++ = EOS_ACTUAL;
  1029. } else {
  1030. *p++ = EOS_CHAR;
  1031. *p++ = EOS_PAD;
  1032. *p++ = EOS_ACTUAL;
  1033. }
  1034. ACTUAL_SIZE(Act_ptr) = (short)(p - Act_ptr) * sizeof(WCHAR);
  1035. Act_ptr = p;
  1036. }
  1037. /************************************************************************
  1038. ** move_to_exp_esc: moves zero terminated string starting at source to
  1039. ** the current position in EXP_BUFFER, with quotes placed around the
  1040. ** string and interior backslashes and dquotes are escaped with a
  1041. ** backslash. The terminating null should not be copied. The null
  1042. ** does not come from the property of a string, but rather is the
  1043. ** marker used to indicate there is no more actual.
  1044. ************************************************************************/
  1045. void
  1046. move_to_exp_esc(
  1047. int quote_char,
  1048. REG ptext_t source
  1049. )
  1050. {
  1051. int mapped_c;
  1052. int mapped_quote;
  1053. int in_quoted = FALSE;
  1054. if( ! source ) {
  1055. return;
  1056. }
  1057. *Exp_ptr++ = (WCHAR)quote_char;
  1058. for(;;) {
  1059. if(Exp_ptr >= ELIMIT) {
  1060. fatal_in_macro(10056);
  1061. }
  1062. switch(mapped_c = CHARMAP(*source)) {
  1063. case LX_EOS:
  1064. if(*source == EOS_CHAR) {
  1065. goto leave_move_stringize;
  1066. }
  1067. /* got BACKSLASH */
  1068. /* but it can't be backslash-newline combination because
  1069. ** we are reprocessing text already read in
  1070. */
  1071. if(in_quoted) {
  1072. *Exp_ptr++ = L'\\';
  1073. }
  1074. break;
  1075. case LX_DQUOTE:
  1076. if(CHARMAP((WCHAR)quote_char) == LX_DQUOTE) {
  1077. *Exp_ptr++ = L'\\';
  1078. }
  1079. /*
  1080. ** FALLTHROUGH
  1081. */
  1082. case LX_SQUOTE:
  1083. if(CHARMAP((WCHAR)quote_char) == LX_SQUOTE) {
  1084. break;
  1085. }
  1086. if(in_quoted ) {
  1087. if(mapped_c == mapped_quote) {
  1088. in_quoted = FALSE;
  1089. }
  1090. } else {
  1091. in_quoted = TRUE;
  1092. mapped_quote = mapped_c;
  1093. }
  1094. break;
  1095. }
  1096. *Exp_ptr++ = *source++;
  1097. }
  1098. leave_move_stringize:
  1099. *Exp_ptr++ = (WCHAR)quote_char;
  1100. }
  1101. /************************************************************************
  1102. ** move_to_exp: moves zero terminated string starting at source to
  1103. ** the current position in EXP_BUFFER. The terminating null should
  1104. ** not be copied.
  1105. ************************************************************************/
  1106. void
  1107. move_to_exp(
  1108. REG ptext_t source
  1109. )
  1110. {
  1111. if( ! source ) {
  1112. return;
  1113. }
  1114. while( *source ) {
  1115. if(Exp_ptr >= ELIMIT) {
  1116. fatal_in_macro(10056);
  1117. }
  1118. *Exp_ptr++ = *source++;
  1119. }
  1120. }
  1121. /************************************************************************
  1122. ** push_macro: pushes macro information onto the macro stack.
  1123. ** Information such as the current location in the Exp and Act buffers
  1124. ** will be used by whatever macros this one may call.
  1125. ************************************************************************/
  1126. void
  1127. push_macro(
  1128. pdefn_t pdef
  1129. )
  1130. {
  1131. /*
  1132. ** note that increment leaves element 0 of the macro stack unused.
  1133. ** this element can be reserved for links to dynamically allocated
  1134. ** macro expansion stacks, if they become desirable
  1135. */
  1136. if(++Macro_depth >= LIMIT_MACRO_DEPTH) {
  1137. fatal(1009, Reuse_W);
  1138. }
  1139. Tiny_lexer_nesting++;
  1140. CURRENT_MACRO = pdef;
  1141. CURRENT_ACTUALS = P_actuals;
  1142. CURRENT_NACTUALS = (UCHAR)N_actuals;
  1143. CURRENT_NACTSEXPANDED = 0;
  1144. CURRENT_STRING = Current_char;
  1145. CURRENT_TEXT = Exp_ptr = Save_Exp_ptr;
  1146. }
  1147. /************************************************************************
  1148. **expand_definition: sets the input stream to start reading from
  1149. ** the macro definition. Also marks the macro as in the process of
  1150. ** expanding so if it eventually invokes itself, it will not expand
  1151. ** the new occurence.
  1152. ************************************************************************/
  1153. void
  1154. expand_definition(
  1155. void
  1156. )
  1157. {
  1158. Current_char = DEFN_TEXT(CURRENT_MACRO);
  1159. DEFN_EXPANDING(CURRENT_MACRO)++;
  1160. }
  1161. /************************************************************************
  1162. **expand_actual: sets the input stream to start reading from
  1163. ** the actual specified in actual.
  1164. ************************************************************************/
  1165. void
  1166. expand_actual(
  1167. UCHAR actual
  1168. )
  1169. {
  1170. ptext_t p;
  1171. p = CURRENT_ACTUALS;
  1172. while(--actual) {
  1173. p = ACTUAL_NEXT(p);
  1174. }
  1175. Current_char = ACTUAL_TEXT(p);
  1176. }
  1177. /************************************************************************
  1178. ** expand_macro: if there are still actuals for this macro to be
  1179. ** expanded, the next one is set up, otherwise this sets up to
  1180. ** expand the macro definition
  1181. ************************************************************************/
  1182. void
  1183. expand_macro(
  1184. void
  1185. )
  1186. {
  1187. if(CURRENT_NACTUALS > CURRENT_NACTSEXPANDED) {
  1188. expand_actual(++CURRENT_NACTSEXPANDED);
  1189. } else {
  1190. expand_definition();
  1191. }
  1192. }
  1193. /************************************************************************
  1194. **post_paste: looks ahead one character to find out if a paste has
  1195. ** been requested immediately after this identifier. If the next
  1196. ** character can continue an identifier, or is the macformal marker,
  1197. ** a paste should be done. This is called after a macformal is found
  1198. ** to find out if the expanded or unexpanded actual should be used.
  1199. ************************************************************************/
  1200. int
  1201. post_paste(
  1202. void
  1203. )
  1204. {
  1205. WCHAR c;
  1206. if((CHARMAP(c = GETCH()) == LX_MACFORMAL) || (LXC_IS_IDENT(c))) {
  1207. UNGETCH();
  1208. return(TRUE);
  1209. }
  1210. UNGETCH();
  1211. return(FALSE);
  1212. }
  1213. /************************************************************************
  1214. **do_macformal: This function is called after a macformal marker is
  1215. ** found. It reads the next character to find out which macformal is
  1216. ** wanted. Then it checks to see if a paste is wanted, to find out
  1217. ** if the expanded or unexpanded actual should be used. The return
  1218. ** value is a pointer to the text of the actual wanted, or NULL if the
  1219. ** actual asked for was not provided.
  1220. ************************************************************************/
  1221. ptext_t
  1222. do_macformal(
  1223. int *pre_paste
  1224. )
  1225. {
  1226. WCHAR n;
  1227. ptext_t p;
  1228. int temp_paste;
  1229. p = CURRENT_ACTUALS;
  1230. n = GETCH();
  1231. if(n > CURRENT_NACTUALS) {
  1232. return(NULL); /* already output warning */
  1233. }
  1234. temp_paste = post_paste();
  1235. if(( ! (*pre_paste)) && ( ! temp_paste) ) {
  1236. /*
  1237. ** if the programmer provided x actuals, actuals x+1 to 2x are
  1238. ** those actuals expanded
  1239. */
  1240. n += CURRENT_NACTUALS;
  1241. }
  1242. *pre_paste = temp_paste;
  1243. if (n != 0)
  1244. while(--n) {
  1245. p = ACTUAL_NEXT(p);
  1246. }
  1247. return(ACTUAL_TEXT(p));
  1248. }
  1249. /************************************************************************
  1250. **tl_getid: This function reads an identifier for the tiny lexer
  1251. ** into EXP_BUFFER. if macformal is found, the text of that actual
  1252. ** (expanded or not) is appended to the identifier. It is possible
  1253. ** that this text will contain characters that are not legal
  1254. ** identifiers so return value is whether checking to see if the
  1255. ** "identifier" is defined is worth the bother.
  1256. ************************************************************************/
  1257. int
  1258. tl_getid(
  1259. WCHAR c
  1260. )
  1261. {
  1262. WCHAR *p;
  1263. int paste;
  1264. int legal_identifier;
  1265. int length = 0;
  1266. p = Exp_ptr;
  1267. paste = FALSE;
  1268. legal_identifier = TRUE;
  1269. do_handle_macformal:
  1270. if(CHARMAP(c) == LX_MACFORMAL) {
  1271. ptext_t p_buf;
  1272. if((p_buf = do_macformal(&paste)) != 0) {
  1273. while( *p_buf ) {
  1274. if( ! LXC_IS_IDENT(*p_buf)) {
  1275. legal_identifier = FALSE;
  1276. }
  1277. if(Exp_ptr >= ELIMIT) {
  1278. fatal_in_macro(10056);
  1279. }
  1280. *Exp_ptr++ = *p_buf++;
  1281. }
  1282. }
  1283. } else {
  1284. *Exp_ptr++ = c;
  1285. }
  1286. do_handle_eos:
  1287. while(LXC_IS_IDENT(c = GETCH())) {
  1288. if(Exp_ptr >= ELIMIT) {
  1289. fatal_in_macro(10056);
  1290. }
  1291. *Exp_ptr++ = c;
  1292. }
  1293. if(CHARMAP(c) == LX_NOEXPAND) {
  1294. length = (int)GETCH(); /* just skip length */
  1295. goto do_handle_eos;
  1296. }
  1297. if(CHARMAP(c) == LX_MACFORMAL) {
  1298. paste = TRUE;
  1299. goto do_handle_macformal;
  1300. }
  1301. UNGETCH();
  1302. if(legal_identifier && (length == (Exp_ptr - p))) {
  1303. legal_identifier = FALSE;
  1304. }
  1305. if(legal_identifier) {
  1306. if(((Exp_ptr - p) > LIMIT_ID_LENGTH) && ( ! Prep)) {
  1307. Exp_ptr = &p[LIMIT_ID_LENGTH];
  1308. *Exp_ptr = L'\0'; /* terminates identifier for warning */
  1309. warning(4011, p); /* id truncated */
  1310. } else {
  1311. *Exp_ptr = L'\0'; /* terminates identifier for expandable check */
  1312. }
  1313. /*
  1314. ** Whether or not we are doing Prep output, we still have to make
  1315. ** sure the identifier will fit in Reuse_W
  1316. */
  1317. if((Exp_ptr - p) > (sizeof(Reuse_W) / sizeof(WCHAR))) {
  1318. Exp_ptr = &p[LIMIT_ID_LENGTH];
  1319. *Exp_ptr = L'\0';
  1320. warning(4011, p);
  1321. }
  1322. /*
  1323. ** copy into Reuse_W for warnings about mismatched number of
  1324. ** formals/actuals, and in case it's not expandable
  1325. */
  1326. memcpy(Reuse_W, p, (int)((Exp_ptr - p) + 1) * sizeof(WCHAR));
  1327. Reuse_W_hash = local_c_hash(Reuse_W);
  1328. /*
  1329. ** the characters from Exp_ptr to p inclusive do not include the
  1330. ** the hash character, the length character, and the terminating
  1331. ** null.
  1332. */
  1333. Reuse_W_length = (UINT)((Exp_ptr - p) + 1);
  1334. }
  1335. return(legal_identifier);
  1336. }
  1337. /************************************************************************
  1338. ** do_strformal: returns pointer to the actual requested without
  1339. ** checking for paste (a legal token is not possible, so if a paste
  1340. ** is being done on a strformal, the behavior is undefined
  1341. ************************************************************************/
  1342. ptext_t
  1343. do_strformal(
  1344. void
  1345. )
  1346. {
  1347. WCHAR n;
  1348. ptext_t p;
  1349. /* use unexpanded actual */
  1350. p = CURRENT_ACTUALS;
  1351. n = GETCH();
  1352. if(n > CURRENT_NACTUALS) {
  1353. return(NULL); /* already output warning */
  1354. }
  1355. if (n != 0)
  1356. while(--n) {
  1357. p = ACTUAL_NEXT(p);
  1358. }
  1359. return(ACTUAL_TEXT(p));
  1360. }
  1361. /************************************************************************
  1362. ** can_get_non_white: tries to get the next non white character
  1363. ** using P1 rules for white space (NL included). If the end of
  1364. ** an actual, or a rescan is found, this returns FALSE, so control
  1365. ** can drop into one of the lexers.
  1366. ************************************************************************/
  1367. int
  1368. can_get_non_white(
  1369. void
  1370. )
  1371. {
  1372. int return_value = FALSE;
  1373. int white_found = FALSE;
  1374. for(;;) {
  1375. switch(CHARMAP(GETCH())) {
  1376. case LX_NL:
  1377. if(On_pound_line) {
  1378. UNGETCH();
  1379. goto leave_cgnw;
  1380. }
  1381. Linenumber++;
  1382. /*
  1383. ** FALLTHROUGH
  1384. */
  1385. case LX_WHITE:
  1386. case LX_CR:
  1387. white_found = TRUE;
  1388. break;
  1389. case LX_EOS:
  1390. {
  1391. int eos_res;
  1392. if((eos_res = handle_eos()) & (ACTUAL_EOS | RESCAN_EOS)) {
  1393. goto leave_cgnw;
  1394. }
  1395. if(eos_res != BACKSLASH_EOS) {
  1396. break;
  1397. }
  1398. }
  1399. /*
  1400. ** FALLTHROUGH
  1401. */
  1402. default:
  1403. UNGETCH();
  1404. return_value = TRUE;
  1405. goto leave_cgnw;
  1406. break;
  1407. }
  1408. }
  1409. leave_cgnw:
  1410. if(white_found) {
  1411. if(Exp_ptr >= ELIMIT) {
  1412. fatal_in_macro(10056);
  1413. }
  1414. if(*(Exp_ptr - 1) != L' ') {
  1415. *Exp_ptr++ = L' ';
  1416. }
  1417. }
  1418. return(return_value); /* could you get next non white? */
  1419. }
  1420. /************************************************************************/
  1421. /* fatal_in_macro () */
  1422. /************************************************************************/
  1423. void
  1424. fatal_in_macro(
  1425. int e
  1426. )
  1427. {
  1428. Linenumber = Macro_line;
  1429. fatal(e);
  1430. }
  1431. /************************************************************************
  1432. ** handle_eos : handle the end of a string.
  1433. ************************************************************************/
  1434. int
  1435. handle_eos(
  1436. void
  1437. )
  1438. {
  1439. if(PREVCH() == L'\\') {
  1440. if(checknl()) {
  1441. return(FILE_EOS);
  1442. } else {
  1443. return(BACKSLASH_EOS);
  1444. }
  1445. }
  1446. if(Macro_depth == 0) { /* found end of file buffer or backslash */
  1447. if(io_eob()) { /* end of buffer in here is bad */
  1448. fatal(1004);
  1449. }
  1450. return(FILE_EOS);
  1451. }
  1452. again:
  1453. switch(GETCH()) {
  1454. case EOS_PAD:
  1455. goto again;
  1456. case EOS_ACTUAL:
  1457. /*
  1458. ** Just finished expanding actual. Check to see if there are
  1459. ** any more actuals to be expanded. If there are, set up to
  1460. ** expand them and return. Otherwise, set up to expand defn
  1461. */
  1462. /* move expanded text of this actual to act_buffer */
  1463. move_to_actual(CURRENT_TEXT, Exp_ptr);
  1464. /* reset Exp_ptr for more expansions at this macro depth */
  1465. Exp_ptr = CURRENT_TEXT;
  1466. /* expand next actual if there, otherwise expand definition */
  1467. expand_macro();
  1468. return(ACTUAL_EOS);
  1469. case EOS_DEFINITION:
  1470. if(rescan_expansion()) {
  1471. return(RESCAN_EOS);
  1472. } else {
  1473. return(DEFINITION_EOS);
  1474. }
  1475. case EOS_RESCAN:
  1476. /*
  1477. ** Reset Current_char, Exp_ptr and Act_ptr, pop the macro
  1478. */
  1479. /* get input from the previous stream */
  1480. Current_char = CURRENT_STRING;
  1481. /* mark this macro as not expanding */
  1482. DEFN_EXPANDING(CURRENT_MACRO)--;
  1483. /*
  1484. ** if looking for the actuals of a macro, these pointers
  1485. ** should really not be reset, however, it is cleaner to
  1486. ** save them before calling handle_eos, and restore them
  1487. ** upon returning, than check a static variable here.
  1488. */
  1489. if(Macro_depth == 1) {
  1490. Act_ptr = ACT_BUFFER;
  1491. Exp_ptr = EXP_BUFFER;
  1492. }
  1493. --Macro_depth;
  1494. return(DEFINITION_EOS);
  1495. /* the following conditional compile is so brackets match */
  1496. default:
  1497. return(FILE_EOS);
  1498. }
  1499. }
  1500. /************************************************************************
  1501. ** END EXPANDING MACRO }
  1502. ************************************************************************/