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.

847 lines
28 KiB

  1. /* Copyright (C) Microsoft Corporation, 1998. All rights reserved. */
  2. #include "precomp.h"
  3. #include "getsym.h"
  4. #include "macro.h"
  5. #include "typeid.h"
  6. #include "utils.h"
  7. // local prototypes
  8. BOOL ExpandFile ( LPSTR pszInputFile, LPSTR pszOutputFile, CMacroMgrList *pMacrMgrList );
  9. BOOL CollectMacros ( CInput *, CMacroMgr *, CTypeID *, CMacroMgrList * );
  10. BOOL InstantiateMacros ( CInput *, CMacroMgr * );
  11. BOOL GenerateOutput ( CInput *, COutput *, CMacroMgr *, CTypeID * );
  12. void BuildOutputFileName ( LPSTR pszInputFileName, LPSTR pszNewOutputFileName );
  13. class CFileList : public CList
  14. {
  15. DEFINE_CLIST(CFileList, LPSTR)
  16. };
  17. int __cdecl main ( int argc, char * argv[] )
  18. {
  19. BOOL rc;
  20. BOOL fShowHelp = (1 == argc);
  21. int i;
  22. LPSTR pszMainInputFile = NULL;
  23. LPSTR pszMainOutputFile = NULL;
  24. CFileList FileList;
  25. CMacroMgrList MacroMgrList;
  26. LPSTR psz;
  27. char szScratch[MAX_PATH];
  28. // output product information
  29. printf("ASN.1 Compiler Preprocessor V0.1\n");
  30. printf("Copyright (C) Microsoft Corporation, 1998. All rights reserved.\n");
  31. // parse command line
  32. for (i = 1; i < argc; i++)
  33. {
  34. if ('-' == *argv[i])
  35. {
  36. // parse the option
  37. if (0 == ::strcmp(argv[i], "-h"))
  38. {
  39. fShowHelp = TRUE;
  40. }
  41. else
  42. if (0 == ::strcmp(argv[i], "-o"))
  43. {
  44. pszMainOutputFile = ::My_strdup(argv[++i]);
  45. ASSERT(NULL != pszMainOutputFile);
  46. }
  47. else
  48. {
  49. fprintf(stderr, "Unknown option [%s]\n", argv[i]);
  50. fShowHelp = TRUE;
  51. break;
  52. }
  53. }
  54. else
  55. {
  56. // must be a file name
  57. FileList.Append(argv[i]);
  58. // the last file will be the main input file
  59. pszMainInputFile = argv[i];
  60. }
  61. }
  62. // output help information if needed
  63. if (fShowHelp || 0 == FileList.GetCount() || NULL == pszMainInputFile)
  64. {
  65. printf("Usage: %s [options] [imported.asn ...] main.asn\n", argv[0]);
  66. printf("Options:\n");
  67. printf("-h\t\tthis help\n");
  68. printf("-o filename\toutput file name\n");
  69. return EXIT_SUCCESS;
  70. }
  71. // construct outpt file name if needed
  72. if (NULL == pszMainOutputFile)
  73. {
  74. // create an output file
  75. ::BuildOutputFileName(pszMainInputFile, &szScratch[0]);
  76. pszMainOutputFile = ::My_strdup(&szScratch[0]);
  77. ASSERT(NULL != pszMainOutputFile);
  78. }
  79. // input and output files must have a different name.
  80. ASSERT(0 != ::strcmp(pszMainInputFile, pszMainOutputFile));
  81. // expand macros in the files
  82. FileList.Reset();
  83. while (NULL != (psz = FileList.Iterate()))
  84. {
  85. if (0 != ::strcmp(psz, pszMainInputFile))
  86. {
  87. ::BuildOutputFileName(psz, &szScratch[0]);
  88. rc = ::ExpandFile(psz, &szScratch[0], &MacroMgrList);
  89. ASSERT(rc);
  90. // remove all the instances of macros
  91. MacroMgrList.Uninstance();
  92. }
  93. else
  94. {
  95. // it is main input file
  96. rc = ::ExpandFile(pszMainInputFile, pszMainOutputFile, &MacroMgrList);
  97. ASSERT(rc);
  98. }
  99. }
  100. //
  101. // Cleanup
  102. //
  103. delete pszMainOutputFile;
  104. MacroMgrList.DeleteList();
  105. return EXIT_SUCCESS;
  106. }
  107. BOOL ExpandFile
  108. (
  109. LPSTR pszInputFile,
  110. LPSTR pszOutputFile,
  111. CMacroMgrList *pMacroMgrList
  112. )
  113. {
  114. BOOL rc, rc1, rc2;
  115. CInput *pInput = NULL;
  116. COutput *pOutput = NULL;
  117. CTypeID *pTypeID = NULL;
  118. CMacroMgr *pMacroMgr = NULL;
  119. pInput = new CInput(&rc1, pszInputFile);
  120. pOutput = new COutput(&rc2, pszOutputFile);
  121. pTypeID = new CTypeID();
  122. pMacroMgr = new CMacroMgr();
  123. if (NULL != pInput && rc1 &&
  124. NULL != pOutput && rc2 &&
  125. NULL != pTypeID &&
  126. NULL != pMacroMgr)
  127. {
  128. //
  129. // Locate a list of macros
  130. //
  131. rc = ::CollectMacros(pInput, pMacroMgr, pTypeID, pMacroMgrList);
  132. if (rc)
  133. {
  134. rc = pInput->Rewind();
  135. ASSERT(rc);
  136. //
  137. // Create instances of macros
  138. //
  139. rc = ::InstantiateMacros(pInput, pMacroMgr);
  140. if (rc)
  141. {
  142. rc = pInput->Rewind();
  143. ASSERT(rc);
  144. //
  145. // Generate macro-expanded file
  146. //
  147. rc = ::GenerateOutput(pInput, pOutput, pMacroMgr, pTypeID);
  148. ASSERT(rc);
  149. }
  150. else
  151. {
  152. ASSERT(rc);
  153. }
  154. }
  155. else
  156. {
  157. ASSERT(rc);
  158. }
  159. }
  160. else
  161. {
  162. ASSERT(0);
  163. }
  164. //
  165. // Cleanup
  166. //
  167. if (NULL != pMacroMgrList && NULL != pMacroMgr)
  168. {
  169. pMacroMgrList->Append(pMacroMgr);
  170. }
  171. else
  172. {
  173. delete pMacroMgr;
  174. }
  175. delete pTypeID;
  176. delete pOutput;
  177. delete pInput;
  178. return rc;
  179. }
  180. BOOL CollectMacros
  181. (
  182. CInput *pInput,
  183. CMacroMgr *pMacroMgr,
  184. CTypeID *pTypeID,
  185. CMacroMgrList *pMacroMgrList
  186. )
  187. {
  188. CNameList NameList(16);
  189. // Create a running symbol handler
  190. CSymbol *pSym = new CSymbol(pInput);
  191. if (NULL == pSym)
  192. {
  193. return FALSE;
  194. }
  195. BOOL rc;
  196. BOOL fWasNewLine = TRUE;
  197. BOOL fEndMacro = FALSE;
  198. UINT cInsideBigBracket = 0;
  199. BOOL fInsideComment = FALSE;
  200. char szNameScratch[MAX_PATH];
  201. // Get the module name first
  202. pSym->NextUsefulSymbol();
  203. if (pSym->GetID() == SYMBOL_IDENTIFIER)
  204. {
  205. ::strcpy(&szNameScratch[0], pSym->GetStr());
  206. pSym->NextUsefulSymbol();
  207. if (pSym->GetID() == SYMBOL_KEYWORD &&
  208. 0 == ::strcmp(pSym->GetStr(), "DEFINITIONS"))
  209. {
  210. pMacroMgr->AddModuleName(&szNameScratch[0]);
  211. }
  212. }
  213. // Rewind the input file
  214. rc = pInput->Rewind();
  215. ASSERT(rc);
  216. // Walk through the text
  217. while (pSym->NextSymbol())
  218. {
  219. // printf("symbol:id[%d], str[%s]\n", pSym->GetID(), pSym->GetStr());
  220. if (pSym->GetID() == SYMBOL_SPACE_EOL)
  221. {
  222. fWasNewLine = TRUE;
  223. fInsideComment = FALSE;
  224. continue;
  225. }
  226. if (pSym->IsComment())
  227. {
  228. fInsideComment = ! fInsideComment;
  229. }
  230. else
  231. if (! fInsideComment)
  232. {
  233. if (pSym->IsLeftBigBracket())
  234. {
  235. cInsideBigBracket++;
  236. }
  237. else
  238. if (pSym->IsRightBigBracket())
  239. {
  240. cInsideBigBracket--;
  241. }
  242. else
  243. // The macro must be outside the big brackets and
  244. // in the beginning of a line.
  245. if (fWasNewLine &&
  246. (0 == cInsideBigBracket) &&
  247. (pSym->GetID() == SYMBOL_IDENTIFIER))
  248. {
  249. ::strcpy(&szNameScratch[0], pSym->GetStr());
  250. pSym->NextUsefulSymbol();
  251. if (pSym->IsLeftBigBracket())
  252. {
  253. cInsideBigBracket++;
  254. CMacro *pMacro = new CMacro(&rc, &szNameScratch[0]);
  255. ASSERT(NULL != pMacro);
  256. ASSERT(rc);
  257. // process argument list
  258. do
  259. {
  260. pSym->NextUsefulSymbol();
  261. pMacro->SetArg(pSym->GetStr());
  262. pSym->NextUsefulSymbol();
  263. }
  264. while (pSym->IsComma());
  265. ASSERT(pSym->IsRightBigBracket());
  266. if (pSym->IsRightBigBracket())
  267. {
  268. cInsideBigBracket--;
  269. }
  270. // save the macro body
  271. ASSERT(0 == cInsideBigBracket);
  272. fEndMacro = FALSE;
  273. while (! fEndMacro || pSym->GetID() != SYMBOL_SPACE_EOL)
  274. {
  275. pSym->NextSymbol();
  276. if (pSym->GetID() == SYMBOL_SPACE_EOL)
  277. {
  278. fInsideComment = FALSE;
  279. }
  280. else
  281. if (pSym->IsComment())
  282. {
  283. fInsideComment = ! fInsideComment;
  284. }
  285. else
  286. if (! fInsideComment)
  287. {
  288. if (pSym->IsLeftBigBracket())
  289. {
  290. cInsideBigBracket++;
  291. }
  292. else
  293. if (pSym->IsRightBigBracket())
  294. {
  295. cInsideBigBracket--;
  296. if (0 == cInsideBigBracket && ! fEndMacro)
  297. {
  298. // basically, it is the end of macro
  299. pMacro->SetBodyPart(pSym->GetStr());
  300. fEndMacro = TRUE;
  301. }
  302. }
  303. } // while
  304. // throw away anything possibly in CONSTRAINED BY
  305. if (! fEndMacro)
  306. {
  307. pMacro->SetBodyPart(pSym->GetStr());
  308. }
  309. } // while
  310. // macro must end with a eol
  311. fWasNewLine = TRUE;
  312. fInsideComment = FALSE;
  313. // write out the eol
  314. pMacro->SetBodyPart("\n");
  315. // take a note of ending a macro
  316. pMacro->EndMacro();
  317. pMacroMgr->AddMacro(pMacro);
  318. // to avoid fWasNewLine being reset.
  319. continue;
  320. } // if left bracket
  321. else
  322. if (pSym->GetID() == SYMBOL_DEFINITION)
  323. {
  324. pSym->NextUsefulSymbol();
  325. if (pSym->GetID() == SYMBOL_IDENTIFIER &&
  326. pTypeID->FindAlias(pSym->GetStr()))
  327. {
  328. // Found a type identifier
  329. pSym->NextSymbol();
  330. if (pSym->IsDot())
  331. {
  332. pSym->NextSymbol();
  333. if (pSym->GetID() == SYMBOL_FIELD &&
  334. 0 == ::strcmp("&Type", pSym->GetStr()))
  335. {
  336. // defined type identifier
  337. pSym->NextUsefulSymbol();
  338. ASSERT(pSym->IsLeftParenth());
  339. if (pSym->IsLeftParenth())
  340. {
  341. pSym->NextUsefulSymbol();
  342. if (pSym->GetID() == SYMBOL_IDENTIFIER)
  343. {
  344. rc = pTypeID->AddInstance(&szNameScratch[0], pSym->GetStr());
  345. ASSERT(rc);
  346. pSym->NextUsefulSymbol();
  347. ASSERT(pSym->IsRightParenth());
  348. }
  349. }
  350. }
  351. }
  352. else
  353. {
  354. rc = pTypeID->AddAlias(&szNameScratch[0]);
  355. ASSERT(rc);
  356. }
  357. }
  358. } // if symbol definition
  359. } // if symbol identifier
  360. else
  361. if (fWasNewLine &&
  362. (0 == cInsideBigBracket) &&
  363. (pSym->GetID() == SYMBOL_KEYWORD) &&
  364. (0 == ::strcmp("IMPORTS", pSym->GetStr())))
  365. {
  366. // skip the entire import area
  367. do
  368. {
  369. pSym->NextUsefulSymbol();
  370. if (pSym->GetID() == SYMBOL_IDENTIFIER)
  371. {
  372. ::strcpy(&szNameScratch[0], pSym->GetStr());
  373. pSym->NextUsefulSymbol();
  374. if (pSym->IsLeftBigBracket())
  375. {
  376. NameList.AddName(&szNameScratch[0]);
  377. pSym->NextUsefulSymbol();
  378. ASSERT(pSym->IsRightBigBracket());
  379. }
  380. }
  381. // else // no else because the current symbol can be FROM
  382. if (pSym->GetID() == SYMBOL_KEYWORD &&
  383. 0 == ::strcmp("FROM", pSym->GetStr()))
  384. {
  385. pSym->NextUsefulSymbol();
  386. if (pSym->GetID() == SYMBOL_IDENTIFIER)
  387. {
  388. LPSTR pszName;
  389. CMacro *pMacro;
  390. while (NULL != (pszName = NameList.Get()))
  391. {
  392. pMacro = pMacroMgrList->FindMacro(pSym->GetStr(), pszName);
  393. if (NULL != pMacro)
  394. {
  395. pMacro = new CMacro(&rc, pMacro);
  396. if (NULL != pMacro && rc)
  397. {
  398. pMacroMgr->AddMacro(pMacro);
  399. }
  400. else
  401. {
  402. ASSERT(0);
  403. }
  404. }
  405. else
  406. {
  407. ASSERT(0);
  408. }
  409. delete pszName;
  410. } // while
  411. }
  412. }
  413. }
  414. while (! pSym->IsSemicolon());
  415. }
  416. } // if ! comment
  417. // Must be reset at the end of this block.
  418. fWasNewLine = FALSE;
  419. } // while
  420. delete pSym;
  421. return TRUE;
  422. }
  423. BOOL InstantiateMacros
  424. (
  425. CInput *pInput,
  426. CMacroMgr *pMacroMgr
  427. )
  428. {
  429. // Create a running symbol handler
  430. CSymbol *pSym = new CSymbol(pInput);
  431. if (NULL == pSym)
  432. {
  433. return FALSE;
  434. }
  435. BOOL rc;
  436. BOOL fInsideComment = FALSE;
  437. UINT cInsideBigBracket = 0;
  438. // Walk through the text
  439. while (pSym->NextSymbol())
  440. {
  441. if (pSym->GetID() == SYMBOL_SPACE_EOL)
  442. {
  443. fInsideComment = FALSE;
  444. }
  445. else
  446. if (pSym->IsComment())
  447. {
  448. fInsideComment = ! fInsideComment;
  449. }
  450. else
  451. if (! fInsideComment)
  452. {
  453. if (pSym->IsLeftBigBracket())
  454. {
  455. cInsideBigBracket++;
  456. }
  457. else
  458. if (pSym->IsRightBigBracket())
  459. {
  460. cInsideBigBracket--;
  461. }
  462. else
  463. if ((0 < cInsideBigBracket) &&
  464. (pSym->GetID() == SYMBOL_IDENTIFIER))
  465. {
  466. CMacro *pMacro = pMacroMgr->FindMacro(pSym->GetStr());
  467. if (NULL != pMacro)
  468. {
  469. UINT cCurrBracket = cInsideBigBracket;
  470. // Found a macro instance
  471. pSym->NextUsefulSymbol();
  472. if (pSym->IsLeftBigBracket())
  473. {
  474. cInsideBigBracket++;
  475. // We need to process the argument list now.
  476. do
  477. {
  478. pSym->NextUsefulSymbol();
  479. pMacro->SetArg(pSym->GetStr());
  480. pSym->NextUsefulSymbol();
  481. }
  482. while (pSym->IsComma());
  483. ASSERT(pSym->IsRightBigBracket());
  484. if (pSym->IsRightBigBracket())
  485. {
  486. cInsideBigBracket--;
  487. }
  488. ASSERT(cCurrBracket == cInsideBigBracket);
  489. rc = pMacro->InstantiateMacro();
  490. ASSERT(rc);
  491. }
  492. }
  493. }
  494. } // ! inside comment
  495. } // while
  496. delete pSym;
  497. return TRUE;
  498. }
  499. BOOL GenerateOutput
  500. (
  501. CInput *pInput,
  502. COutput *pOutput,
  503. CMacroMgr *pMacroMgr,
  504. CTypeID *pTypeID
  505. )
  506. {
  507. // Create a running symbol handler
  508. CSymbol *pSym = new CSymbol(pInput);
  509. if (NULL == pSym)
  510. {
  511. return FALSE;
  512. }
  513. BOOL rc;
  514. BOOL fWasNewLine = FALSE;
  515. BOOL fEndMacro = FALSE;
  516. UINT cInsideBigBracket = 0;
  517. BOOL fInsideComment = FALSE;
  518. BOOL fIgnoreThisSym = FALSE;
  519. BOOL fInsideImport = FALSE;
  520. UINT nOutputImportedMacrosNow = 0;
  521. // Walk through the text
  522. while (pSym->NextSymbol())
  523. {
  524. fIgnoreThisSym = FALSE; // default is to output this symbol
  525. if (pSym->GetID() == SYMBOL_SPACE_EOL)
  526. {
  527. fWasNewLine = TRUE;
  528. fInsideComment = FALSE;
  529. }
  530. else
  531. {
  532. if (pSym->IsComment())
  533. {
  534. fInsideComment = ! fInsideComment;
  535. }
  536. else
  537. if (! fInsideComment)
  538. {
  539. if (pSym->IsLeftBigBracket())
  540. {
  541. cInsideBigBracket++;
  542. }
  543. else
  544. if (pSym->IsRightBigBracket())
  545. {
  546. cInsideBigBracket--;
  547. }
  548. else
  549. if (pSym->IsSemicolon())
  550. {
  551. fInsideImport = FALSE;
  552. nOutputImportedMacrosNow++;
  553. }
  554. else
  555. // The macro must be outside the big brackets and
  556. // in the beginning of a line.
  557. if (fWasNewLine &&
  558. (0 == cInsideBigBracket) &&
  559. (pSym->GetID() == SYMBOL_IDENTIFIER))
  560. {
  561. CMacro *pMacro;
  562. LPSTR pszOldSubType;
  563. if (NULL != (pMacro = pMacroMgr->FindMacro(pSym->GetStr())))
  564. {
  565. // Found a macro template
  566. fIgnoreThisSym = TRUE;
  567. if (! pMacro->IsImported())
  568. {
  569. // Output all instances of this macro.
  570. rc = pMacro->OutputInstances(pOutput);
  571. ASSERT(rc);
  572. // Ignore the macro template body
  573. pSym->NextUsefulSymbol();
  574. if (pSym->IsLeftBigBracket())
  575. {
  576. cInsideBigBracket++;
  577. // Ignore the argument list
  578. do
  579. {
  580. // yes, two calls... not a mistake!
  581. pSym->NextUsefulSymbol();
  582. pSym->NextUsefulSymbol();
  583. }
  584. while (pSym->IsComma());
  585. ASSERT(pSym->IsRightBigBracket());
  586. if (pSym->IsRightBigBracket())
  587. {
  588. cInsideBigBracket--;
  589. }
  590. // Ignore the macro body
  591. ASSERT(0 == cInsideBigBracket);
  592. fEndMacro = FALSE;
  593. while (! fEndMacro || pSym->GetID() != SYMBOL_SPACE_EOL)
  594. {
  595. pSym->NextSymbol();
  596. if (pSym->GetID() == SYMBOL_SPACE_EOL)
  597. {
  598. fInsideComment = FALSE;
  599. }
  600. else
  601. if (pSym->IsComment())
  602. {
  603. fInsideComment = ! fInsideComment;
  604. }
  605. else
  606. if (! fInsideComment)
  607. {
  608. if (pSym->IsLeftBigBracket())
  609. {
  610. cInsideBigBracket++;
  611. }
  612. else
  613. if (pSym->IsRightBigBracket())
  614. {
  615. cInsideBigBracket--;
  616. if (0 == cInsideBigBracket)
  617. {
  618. // basically, it is the end of macro
  619. fEndMacro = TRUE;
  620. }
  621. }
  622. }
  623. } // while
  624. // macro must end with a eol
  625. fWasNewLine = TRUE;
  626. fInsideComment = FALSE;
  627. // to avoid fWasNewLine being reset
  628. // it is ok to continue because we do not output this symbol.
  629. ASSERT(fIgnoreThisSym);
  630. continue;
  631. } // if left bracket
  632. } // ! imported
  633. else
  634. {
  635. // Ignore the macro template body
  636. pSym->NextUsefulSymbol();
  637. ASSERT(pSym->IsLeftBigBracket());
  638. pSym->NextUsefulSymbol();
  639. ASSERT(pSym->IsRightBigBracket());
  640. pSym->NextUsefulSymbol();
  641. if (! pSym->IsComma())
  642. {
  643. fIgnoreThisSym = FALSE;
  644. }
  645. } // imported
  646. } // if pMacro
  647. else
  648. if (pTypeID->FindAlias(pSym->GetStr()))
  649. {
  650. // Found a type ID alias. Let's skip this line entirely
  651. do
  652. {
  653. pSym->NextSymbol();
  654. }
  655. while (pSym->GetID() != SYMBOL_SPACE_EOL);
  656. } // if find alias
  657. else
  658. if (NULL != (pszOldSubType = pTypeID->FindInstance(pSym->GetStr())))
  659. {
  660. // Found a type ID instance. Let's output the construct.
  661. rc = pTypeID->GenerateOutput(pOutput, pSym->GetStr(), pszOldSubType);
  662. ASSERT(rc);
  663. // Skip the body entirely
  664. do
  665. {
  666. pSym->NextUsefulSymbol();
  667. }
  668. while (! pSym->IsRightParenth());
  669. // Skip the rest of this line
  670. do
  671. {
  672. pSym->NextSymbol();
  673. }
  674. while (pSym->GetID() != SYMBOL_SPACE_EOL);
  675. } // if find instance
  676. }
  677. else
  678. if ((0 < cInsideBigBracket) &&
  679. (pSym->GetID() == SYMBOL_IDENTIFIER))
  680. {
  681. CMacro *pMacro = pMacroMgr->FindMacro(pSym->GetStr());
  682. if (NULL != pMacro)
  683. {
  684. UINT cCurrBracket = cInsideBigBracket;
  685. // Found a macro instance
  686. fIgnoreThisSym = TRUE;
  687. // Create an instance name.
  688. pSym->NextUsefulSymbol();
  689. if (pSym->IsLeftBigBracket())
  690. {
  691. cInsideBigBracket++;
  692. // We need to process the argument list now.
  693. do
  694. {
  695. pSym->NextUsefulSymbol();
  696. pMacro->SetArg(pSym->GetStr());
  697. pSym->NextUsefulSymbol();
  698. }
  699. while (pSym->IsComma());
  700. ASSERT(pSym->IsRightBigBracket());
  701. if (pSym->IsRightBigBracket())
  702. {
  703. cInsideBigBracket--;
  704. }
  705. ASSERT(cCurrBracket == cInsideBigBracket);
  706. LPSTR pszInstanceName = pMacro->CreateInstanceName();
  707. ASSERT(NULL != pszInstanceName);
  708. if (NULL != pszInstanceName)
  709. {
  710. rc = pOutput->Write(pszInstanceName, ::strlen(pszInstanceName));
  711. ASSERT(rc);
  712. delete pszInstanceName;
  713. }
  714. pMacro->DeleteArgList();
  715. }
  716. }
  717. }
  718. else
  719. if (fWasNewLine &&
  720. (0 == cInsideBigBracket) &&
  721. (pSym->GetID() == SYMBOL_KEYWORD) &&
  722. (0 == ::strcmp("IMPORTS", pSym->GetStr())))
  723. {
  724. fInsideImport = TRUE;
  725. }
  726. } // if ! comment
  727. // Must be reset at the end of this block.
  728. fWasNewLine = FALSE;
  729. } // if ! space eol
  730. if (! fIgnoreThisSym)
  731. {
  732. // write out this symbol
  733. rc = pOutput->Write(pSym->GetStr(), pSym->GetStrLen());
  734. ASSERT(rc);
  735. }
  736. // only generate once
  737. if (1 == nOutputImportedMacrosNow)
  738. {
  739. nOutputImportedMacrosNow++;
  740. rc = pMacroMgr->OutputImportedMacros(pOutput);
  741. ASSERT(rc);
  742. }
  743. } // while
  744. delete pSym;
  745. return TRUE;
  746. }
  747. void BuildOutputFileName
  748. (
  749. LPSTR pszInputFileName,
  750. LPSTR pszNewOutputFileName
  751. )
  752. {
  753. LPSTR psz;
  754. ::strcpy(pszNewOutputFileName, pszInputFileName);
  755. if (NULL != (psz = ::strrchr(pszNewOutputFileName, '.')) &&
  756. 0 == ::strcmpi(psz, ".asn"))
  757. {
  758. ::strcpy(psz, ".out");
  759. }
  760. else
  761. {
  762. ::strcat(pszNewOutputFileName, ".out");
  763. }
  764. }