Source code of Windows XP (NT5)
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.

1670 lines
55 KiB

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