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.

945 lines
24 KiB

  1. /*++
  2. Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. language.c
  5. Abstract:
  6. This file contains functions necessary to parse and write the language
  7. specific tables to a data file.
  8. External Routines in this file:
  9. ParseLanguage
  10. WriteLanguage
  11. ParseLangException
  12. WriteLangException
  13. Revision History:
  14. 12-10-91 JulieB Created.
  15. --*/
  16. //
  17. // Include Files.
  18. //
  19. #include "nlstrans.h"
  20. //
  21. // Forward Declarations.
  22. //
  23. int
  24. GetUpperTable(
  25. PLANGUAGE pLang,
  26. int Size);
  27. int
  28. GetLowerTable(
  29. PLANGUAGE pLang,
  30. int Size);
  31. int
  32. GetLangExceptionTable(
  33. PLANG_EXCEPT pLangExcept,
  34. int Size);
  35. int
  36. WriteUpper(
  37. PLANGUAGE pLang,
  38. FILE *pOutputFile);
  39. int
  40. WriteLower(
  41. PLANGUAGE pLang,
  42. FILE *pOutputFile);
  43. int
  44. WriteLangExceptionTable(
  45. PLANG_EXCEPT pLangExcept,
  46. FILE *pOutputFile);
  47. //-------------------------------------------------------------------------//
  48. // EXTERNAL ROUTINES //
  49. //-------------------------------------------------------------------------//
  50. ////////////////////////////////////////////////////////////////////////////
  51. //
  52. // ParseLanguage
  53. //
  54. // This routine parses the input file for the language specific tables.
  55. // This routine is only entered when the LANGUAGE keyword is found.
  56. // The parsing continues until the ENDLANGUAGE keyword is found.
  57. //
  58. // 12-10-91 JulieB Created.
  59. ////////////////////////////////////////////////////////////////////////////
  60. int ParseLanguage(
  61. PLANGUAGE pLang,
  62. PSZ pszKeyWord)
  63. {
  64. int size; // size of table to follow
  65. while (fscanf(pInputFile, "%s", pszKeyWord) == 1)
  66. {
  67. if (_stricmp(pszKeyWord, "UPPERCASE") == 0)
  68. {
  69. if (Verbose)
  70. printf("\n\nFound UPPERCASE keyword.\n");
  71. //
  72. // Get size parameter.
  73. //
  74. if (GetSize(&size))
  75. return (1);
  76. //
  77. // Get UPPERCASE Table.
  78. //
  79. if (GetUpperTable(pLang, size))
  80. {
  81. return (1);
  82. }
  83. //
  84. // Set WriteFlags for UPPERCASE Table.
  85. //
  86. pLang->WriteFlags |= F_UPPER;
  87. }
  88. else if (_stricmp(pszKeyWord, "LOWERCASE") == 0)
  89. {
  90. if (Verbose)
  91. printf("\n\nFound LOWERCASE keyword.\n");
  92. //
  93. // Get size parameter.
  94. //
  95. if (GetSize(&size))
  96. return (1);
  97. //
  98. // Get LOWERCASE Table.
  99. //
  100. if (GetLowerTable(pLang, size))
  101. {
  102. return (1);
  103. }
  104. //
  105. // Set WriteFlags for LOWERCASE Table.
  106. //
  107. pLang->WriteFlags |= F_LOWER;
  108. }
  109. else if (_stricmp(pszKeyWord, "ENDLANGUAGE") == 0)
  110. {
  111. if (Verbose)
  112. printf("\n\nFound ENDLANGUAGE keyword.\n");
  113. //
  114. // Return success.
  115. //
  116. return (0);
  117. }
  118. else
  119. {
  120. printf("Parse Error: Invalid Instruction '%s'.\n", pszKeyWord);
  121. return (1);
  122. }
  123. }
  124. //
  125. // If this point is reached, then the ENDLANGUAGE keyword was
  126. // not found. Return an error.
  127. //
  128. printf("Parse Error: Expecting ENDLANGUAGE keyword.\n");
  129. return (1);
  130. }
  131. ////////////////////////////////////////////////////////////////////////////
  132. //
  133. // WriteLanguage
  134. //
  135. // This routine writes the language specific tables to an output file.
  136. //
  137. // 12-10-91 JulieB Created.
  138. ////////////////////////////////////////////////////////////////////////////
  139. int WriteLanguage(
  140. PLANGUAGE pLang)
  141. {
  142. FILE *pOutputFile; // ptr to output file
  143. WORD wValue; // temp storage value
  144. //
  145. // Make sure all tables are present.
  146. //
  147. if (!((pLang->WriteFlags & F_UPPER) && (pLang->WriteFlags & F_LOWER)))
  148. {
  149. printf("Write Error: All tables must be present -\n");
  150. printf(" Uppercase and Lowercase Tables.\n");
  151. return (1);
  152. }
  153. //
  154. // Make sure output file can be opened for writing.
  155. //
  156. if ((pOutputFile = fopen(LANGUAGE_FILE, "w+b")) == 0)
  157. {
  158. printf("Error opening output file %s.\n", LANGUAGE_FILE);
  159. return (1);
  160. }
  161. if (Verbose)
  162. printf("\n\nWriting output file %s...\n", LANGUAGE_FILE);
  163. //
  164. // Write IfDefault value to file.
  165. //
  166. pLang->IfDefault = 1;
  167. wValue = (WORD)(pLang->IfDefault);
  168. if (FileWrite( pOutputFile,
  169. &wValue,
  170. sizeof(WORD),
  171. 1,
  172. "IfDefault" ))
  173. {
  174. return (1);
  175. }
  176. //
  177. // Write UPPERCASE Table to output file.
  178. //
  179. if (WriteUpper(pLang, pOutputFile))
  180. {
  181. fclose(pOutputFile);
  182. return (1);
  183. }
  184. //
  185. // Free UPPERCASE table structures.
  186. //
  187. Free844(pLang->pUpper);
  188. //
  189. // Write LOWERCASE Table to output file.
  190. //
  191. if (WriteLower(pLang, pOutputFile))
  192. {
  193. fclose(pOutputFile);
  194. return (1);
  195. }
  196. //
  197. // Free LOWERCASE table structures.
  198. //
  199. Free844(pLang->pLower);
  200. //
  201. // Close the output file.
  202. //
  203. fclose(pOutputFile);
  204. //
  205. // Return success.
  206. //
  207. printf("\nSuccessfully wrote output file %s\n", LANGUAGE_FILE);
  208. return (0);
  209. }
  210. ////////////////////////////////////////////////////////////////////////////
  211. //
  212. // ParseLangException
  213. //
  214. // This routine parses the input file for the language exception specific
  215. // tables. This routine is only entered when the LANGUAGE_EXCEPTION keyword
  216. // is found.
  217. //
  218. // 08-30-95 JulieB Created.
  219. ////////////////////////////////////////////////////////////////////////////
  220. int ParseLangException(
  221. PLANG_EXCEPT pLangExcept,
  222. PSZ pszKeyWord)
  223. {
  224. int size; // size of table to follow
  225. //
  226. // Get size parameter.
  227. //
  228. if (GetSize(&size))
  229. return (1);
  230. //
  231. // Get EXCEPTION Table.
  232. //
  233. if (GetLangExceptionTable(pLangExcept, size))
  234. {
  235. return (1);
  236. }
  237. //
  238. // Return success.
  239. //
  240. return (0);
  241. }
  242. ////////////////////////////////////////////////////////////////////////////
  243. //
  244. // WriteLangException
  245. //
  246. // This routine writes the language excpetion specific tables to an output
  247. // file.
  248. //
  249. // 08-30-95 JulieB Created.
  250. ////////////////////////////////////////////////////////////////////////////
  251. int WriteLangException(
  252. PLANG_EXCEPT pLangExcept)
  253. {
  254. FILE *pOutputFile; // ptr to output file
  255. int ctr; // loop counter
  256. //
  257. // Make sure output file can be opened for writing.
  258. //
  259. if ((pOutputFile = fopen(LANG_EXCEPT_FILE, "w+b")) == 0)
  260. {
  261. printf("Error opening output file %s.\n", LANG_EXCEPT_FILE);
  262. return (1);
  263. }
  264. if (Verbose)
  265. printf("\n\nWriting output file %s...\n", LANG_EXCEPT_FILE);
  266. //
  267. // Write EXCEPTION Table to output file.
  268. //
  269. if (WriteLangExceptionTable(pLangExcept, pOutputFile))
  270. {
  271. fclose(pOutputFile);
  272. return (1);
  273. }
  274. //
  275. // Free EXCEPTION header and table structures.
  276. //
  277. for (ctr = 0; ctr < pLangExcept->NumException; ctr++)
  278. {
  279. if ((pLangExcept->pExceptTbl)[ctr])
  280. {
  281. free((pLangExcept->pExceptTbl)[ctr]);
  282. }
  283. }
  284. free(pLangExcept->pExceptTbl);
  285. free(pLangExcept->pExceptHdr);
  286. //
  287. // Close the output file.
  288. //
  289. fclose(pOutputFile);
  290. //
  291. // Return success.
  292. //
  293. printf("\nSuccessfully wrote output file %s\n", LANG_EXCEPT_FILE);
  294. return (0);
  295. }
  296. //-------------------------------------------------------------------------//
  297. // INTERNAL ROUTINES //
  298. //-------------------------------------------------------------------------//
  299. ////////////////////////////////////////////////////////////////////////////
  300. //
  301. // GetUpperTable
  302. //
  303. // This routine gets the upper case table from the input file. It uses
  304. // the size parameter to know when to stop reading from the file. If an
  305. // error is encountered, a message is printed and an error is returned.
  306. //
  307. // 07-30-91 JulieB Created.
  308. // 12-10-91 JulieB Modified for new table format.
  309. ////////////////////////////////////////////////////////////////////////////
  310. int GetUpperTable(
  311. PLANGUAGE pLang,
  312. int Size)
  313. {
  314. int LoChar; // lower case value
  315. int UpChar; // upper case value
  316. register int Ctr; // loop counter
  317. int NumItems; // number of items returned from fscanf
  318. //
  319. // Allocate top buffer for 8:4:4 table - 256 pointers.
  320. //
  321. if (Allocate8(&pLang->pUpper))
  322. {
  323. return (1);
  324. }
  325. //
  326. // For each entry in table, read in the upper case and lower case
  327. // character from input file, allocate necessary 16 word buffers
  328. // based on upper case value, and store difference to lower case
  329. // character.
  330. //
  331. for (Ctr = 0; Ctr < Size; Ctr++)
  332. {
  333. //
  334. // Read in lower case and upper case characters.
  335. //
  336. NumItems = fscanf( pInputFile,
  337. "%x %x ;%*[^\n]",
  338. &LoChar,
  339. &UpChar );
  340. if (NumItems != 2)
  341. {
  342. printf("Parse Error: Error reading UPPERCASE values.\n");
  343. return (1);
  344. }
  345. if (Verbose)
  346. printf(" Lower = %x\tUpper = %x\n", LoChar, UpChar);
  347. //
  348. // Insert difference (UpChar - LoChar) into 8:4:4 table.
  349. //
  350. if (Insert844( pLang->pUpper,
  351. (WORD)LoChar,
  352. (WORD)(UpChar - LoChar),
  353. &pLang->UPBuf2,
  354. &pLang->UPBuf3,
  355. sizeof(WORD) ))
  356. {
  357. return (1);
  358. }
  359. }
  360. //
  361. // Return success.
  362. //
  363. return (0);
  364. }
  365. ////////////////////////////////////////////////////////////////////////////
  366. //
  367. // GetLowerTable
  368. //
  369. // This routine gets the lower case table from the input file. It uses
  370. // the size parameter to know when to stop reading from the file. If an
  371. // error is encountered, a message is printed and an error is returned.
  372. //
  373. // 07-30-91 JulieB Created.
  374. // 12-10-91 JulieB Modified for new table format.
  375. ////////////////////////////////////////////////////////////////////////////
  376. int GetLowerTable(
  377. PLANGUAGE pLang,
  378. int Size)
  379. {
  380. int UpChar; // upper case value
  381. int LoChar; // lower case value
  382. register int Ctr; // loop counter
  383. int NumItems; // number of items returned from fscanf
  384. //
  385. // Allocate top buffer for 8:4:4 table - 256 pointers.
  386. //
  387. if (Allocate8(&pLang->pLower))
  388. {
  389. return (1);
  390. }
  391. //
  392. // For each entry in table, read in the upper case and lower case
  393. // character from input file, allocate necessary 16 word buffers
  394. // based on lower case value, and store difference to upper case
  395. // character.
  396. //
  397. for (Ctr = 0; Ctr < Size; Ctr++)
  398. {
  399. //
  400. // Read in lower case and upper case characters.
  401. //
  402. NumItems = fscanf( pInputFile,
  403. "%x %x ;%*[^\n]",
  404. &UpChar,
  405. &LoChar );
  406. if (NumItems != 2)
  407. {
  408. printf("Parse Error: Error reading LOWERCASE values.\n");
  409. return (1);
  410. }
  411. if (Verbose)
  412. printf(" Upper = %x\tLower = %x\n", UpChar, LoChar);
  413. //
  414. // Insert difference (LoChar - UpChar) into 8:4:4 table.
  415. //
  416. if (Insert844( pLang->pLower,
  417. (WORD)UpChar,
  418. (WORD)(LoChar - UpChar),
  419. &pLang->LOBuf2,
  420. &pLang->LOBuf3,
  421. sizeof(WORD) ))
  422. {
  423. return (1);
  424. }
  425. }
  426. //
  427. // Return success.
  428. //
  429. return (0);
  430. }
  431. ////////////////////////////////////////////////////////////////////////////
  432. //
  433. // GetLangExceptionTable
  434. //
  435. // This routine gets the exception table from the input file.
  436. // It uses the size parameter to know when to stop reading from the file.
  437. // If an error is encountered, a message is printed and an error is returned.
  438. //
  439. // 08-30-95 JulieB Created.
  440. ////////////////////////////////////////////////////////////////////////////
  441. int GetLangExceptionTable(
  442. PLANG_EXCEPT pLangExcept,
  443. int Size)
  444. {
  445. DWORD Locale; // locale id
  446. int NumUp; // number of entries for upper case
  447. int NumLo; // number of entries for lower case
  448. int TotalNum; // total number of exceptions for locale
  449. int UCP1; // exception code point 1
  450. int UCP2; // exception code point 2
  451. int Offset = 0; // offset to store
  452. int Ctr; // loop counter
  453. int Ctr2; // loop counter
  454. int LcidCtr; // loop counter
  455. int NumItems; // number of items returned from fscanf
  456. int Num; // temp value
  457. char pszTemp[MAX]; // temp buffer for string
  458. //
  459. // Allocate exception header and exception table and set size of
  460. // table in language exception tables structure.
  461. //
  462. if (AllocateLangException(pLangExcept, Size))
  463. {
  464. return (1);
  465. }
  466. //
  467. // For each entry in table, read in the LCID keyword, locale id,
  468. // the number of upper case entries for that locale id, and the
  469. // number of lower case entries for that locale id. Then, for all
  470. // entries for the locale id, read in the exception code point and
  471. // the upper/lower case code point. Store all values in the
  472. // exception header and the exception table.
  473. //
  474. Ctr = 0;
  475. while (Ctr < Size)
  476. {
  477. //
  478. // Read in the LCID keyword, locale id, and the number of
  479. // entries for the locale id.
  480. //
  481. NumItems = fscanf( pInputFile,
  482. " LCID %i %i %i ;%*[^\n]",
  483. &Locale,
  484. &NumUp,
  485. &NumLo );
  486. if (NumItems != 3)
  487. {
  488. printf("Parse Error: Error reading EXCEPTION LCID values.\n");
  489. return (1);
  490. }
  491. if (Verbose)
  492. printf("\n LCID = %lx\tNumUpper = %d\tNumLower = %d\n\n",
  493. Locale, NumUp, NumLo);
  494. //
  495. // Store the locale id and the number of entries in the header.
  496. //
  497. ((pLangExcept->pExceptHdr)[Ctr]).Locale = (DWORD)Locale;
  498. ((pLangExcept->pExceptHdr)[Ctr]).Offset = (DWORD)Offset;
  499. ((pLangExcept->pExceptHdr)[Ctr]).NumUpEntries = (DWORD)NumUp;
  500. ((pLangExcept->pExceptHdr)[Ctr]).NumLoEntries = (DWORD)NumLo;
  501. //
  502. // See if there are any other LCIDs for this exception table.
  503. //
  504. LcidCtr = 1;
  505. while (NumItems = fscanf( pInputFile,
  506. " LCID %i ;%*[^\n]",
  507. &Locale ))
  508. {
  509. if (NumItems > 2)
  510. {
  511. printf("Parse Error: Error reading secondary EXCEPTION LCID values.\n");
  512. return (1);
  513. }
  514. if (Verbose)
  515. printf("\n LCID = %lx\tNumUpper = %d\tNumLower = %d\n\n",
  516. Locale, NumUp, NumLo);
  517. //
  518. // Store the locale id and the number of entries in the header.
  519. //
  520. ((pLangExcept->pExceptHdr)[Ctr + LcidCtr]).Locale = (DWORD)Locale;
  521. ((pLangExcept->pExceptHdr)[Ctr + LcidCtr]).Offset = (DWORD)Offset;
  522. ((pLangExcept->pExceptHdr)[Ctr + LcidCtr]).NumUpEntries = (DWORD)NumUp;
  523. ((pLangExcept->pExceptHdr)[Ctr + LcidCtr]).NumLoEntries = (DWORD)NumLo;
  524. LcidCtr++;
  525. }
  526. //
  527. // Add (Num times number of words in exception node) to Offset
  528. // to get the offset of the next LCID entries.
  529. //
  530. TotalNum = NumUp + NumLo;
  531. Offset += (TotalNum * NUM_L_EXCEPT_WORDS);
  532. //
  533. // Allocate exception nodes for current LCID.
  534. //
  535. if (AllocateLangExceptionNodes(pLangExcept, TotalNum, Ctr))
  536. {
  537. return (1);
  538. }
  539. //
  540. // Read in the UPPERCASE keyword.
  541. //
  542. NumItems = fscanf(pInputFile, "%s", pszTemp);
  543. if ((NumItems != 1) ||
  544. (_stricmp(pszTemp, "UPPERCASE") != 0))
  545. {
  546. printf("Parse Error: Error reading UPPERCASE keyword for LCID %lx.\n",
  547. Locale);
  548. return (1);
  549. }
  550. else
  551. {
  552. if (Verbose)
  553. printf("\n\nFound UPPERCASE keyword.\n");
  554. }
  555. //
  556. // For each entry for the locale id, read in the exception code
  557. // point and the upper/lower case code point. Store the values
  558. // in the exception table nodes.
  559. //
  560. for (Ctr2 = 0; Ctr2 < TotalNum; Ctr2++)
  561. {
  562. if (Ctr2 == NumUp)
  563. {
  564. //
  565. // Read in the LOWERCASE keyword.
  566. //
  567. NumItems = fscanf(pInputFile, "%s", pszTemp);
  568. if ((NumItems != 1) ||
  569. (_stricmp(pszTemp, "LOWERCASE") != 0))
  570. {
  571. printf("Parse Error: Error reading LOWERCASE keyword for LCID %lx.\n",
  572. Locale);
  573. return (1);
  574. }
  575. else
  576. {
  577. if (Verbose)
  578. printf("\n\nFound LOWERCASE keyword.\n");
  579. }
  580. }
  581. //
  582. // Read in code point and the upper/lower case code point.
  583. //
  584. NumItems = fscanf( pInputFile,
  585. "%i %i ;%*[^\n]",
  586. &UCP1,
  587. &UCP2 );
  588. if (NumItems != 2)
  589. {
  590. printf("Parse Error: Error reading EXCEPTION values for LCID %lx.\n",
  591. Locale);
  592. return (1);
  593. }
  594. if (Verbose)
  595. printf(" UCP1 = %x\tUCP2 = %x\n", UCP1, UCP2);
  596. //
  597. // Store the weights in the exception table.
  598. //
  599. (((pLangExcept->pExceptTbl)[Ctr])[Ctr2]).UCP = (WORD)UCP1;
  600. (((pLangExcept->pExceptTbl)[Ctr])[Ctr2]).AddAmount = (WORD)(UCP2 - UCP1);
  601. }
  602. Ctr += LcidCtr;
  603. }
  604. //
  605. // Return success.
  606. //
  607. return (0);
  608. }
  609. ////////////////////////////////////////////////////////////////////////////
  610. //
  611. // WriteUpper
  612. //
  613. // This routine writes the UPPERCASE information to the output file.
  614. //
  615. // 07-30-91 JulieB Created.
  616. ////////////////////////////////////////////////////////////////////////////
  617. int WriteUpper(
  618. PLANGUAGE pLang,
  619. FILE *pOutputFile)
  620. {
  621. int TblSize; // size of table
  622. WORD wValue; // temp storage value
  623. if (Verbose)
  624. printf("\nWriting UPPERCASE Table...\n");
  625. //
  626. // Compute size of table.
  627. //
  628. TblSize = Compute844Size( pLang->UPBuf2,
  629. pLang->UPBuf3,
  630. sizeof(WORD) ) + 1;
  631. //
  632. // Make sure the total size of the table is not greater than 64K.
  633. // If it is, then the WORD offsets are too small.
  634. //
  635. if (TblSize > MAX_844_TBL_SIZE)
  636. {
  637. printf("Write Error: Size of UPPER table is greater than 64K.\n");
  638. return (1);
  639. }
  640. //
  641. // Write the size to the output file.
  642. //
  643. wValue = (WORD)TblSize;
  644. if (FileWrite( pOutputFile,
  645. &wValue,
  646. sizeof(WORD),
  647. 1,
  648. "UPPER size" ))
  649. {
  650. return (1);
  651. }
  652. //
  653. // Write UPPERCASE 8:4:4 table to file.
  654. //
  655. if (Write844Table( pOutputFile,
  656. pLang->pUpper,
  657. pLang->UPBuf2,
  658. TblSize - 1,
  659. sizeof(WORD) ))
  660. {
  661. return (1);
  662. }
  663. //
  664. // Return success.
  665. //
  666. return (0);
  667. }
  668. ////////////////////////////////////////////////////////////////////////////
  669. //
  670. // WriteLower
  671. //
  672. // This routine writes the LOWERCASE information to the output file.
  673. //
  674. // 07-30-91 JulieB Created.
  675. ////////////////////////////////////////////////////////////////////////////
  676. int WriteLower(
  677. PLANGUAGE pLang,
  678. FILE *pOutputFile)
  679. {
  680. int TblSize; // size of table
  681. WORD wValue; // temp storage value
  682. if (Verbose)
  683. printf("\nWriting LOWERCASE Table...\n");
  684. //
  685. // Compute size of table.
  686. //
  687. TblSize = Compute844Size( pLang->LOBuf2,
  688. pLang->LOBuf3,
  689. sizeof(WORD) ) + 1;
  690. //
  691. // Make sure the total size of the table is not greater than 64K.
  692. // If it is, then the WORD offsets are too small.
  693. //
  694. if (TblSize > MAX_844_TBL_SIZE)
  695. {
  696. printf("Write Error: Size of LOWER table is greater than 64K.\n");
  697. return (1);
  698. }
  699. //
  700. // Write the size to the output file.
  701. //
  702. wValue = (WORD)TblSize;
  703. if (FileWrite( pOutputFile,
  704. &wValue,
  705. sizeof(WORD),
  706. 1,
  707. "LOWER size" ))
  708. {
  709. return (1);
  710. }
  711. //
  712. // Write LOWERCASE 8:4:4 table to file.
  713. //
  714. if (Write844Table( pOutputFile,
  715. pLang->pLower,
  716. pLang->LOBuf2,
  717. TblSize - 1,
  718. sizeof(WORD) ))
  719. {
  720. return (1);
  721. }
  722. //
  723. // Return success.
  724. //
  725. return (0);
  726. }
  727. ////////////////////////////////////////////////////////////////////////////
  728. //
  729. // WriteLangExceptionTable
  730. //
  731. // This routine writes the EXCEPTION information to the output file.
  732. //
  733. // 08-30-95 JulieB Created.
  734. ////////////////////////////////////////////////////////////////////////////
  735. int WriteLangExceptionTable(
  736. PLANG_EXCEPT pLangExcept,
  737. FILE *pOutputFile)
  738. {
  739. int TblSize; // size of table
  740. int Ctr; // loop counter
  741. WORD wValue; // temp storage value
  742. if (Verbose)
  743. printf("\nWriting EXCEPTION Table...\n");
  744. //
  745. // Get the size of the table.
  746. //
  747. TblSize = pLangExcept->NumException;
  748. //
  749. // Write the number of exception locales to the output file.
  750. //
  751. wValue = (WORD)TblSize;
  752. if (FileWrite( pOutputFile,
  753. &wValue,
  754. sizeof(DWORD),
  755. 1,
  756. "Exception Size" ))
  757. {
  758. return (1);
  759. }
  760. //
  761. // Write the exception header to the output file.
  762. //
  763. if (FileWrite( pOutputFile,
  764. pLangExcept->pExceptHdr,
  765. sizeof(L_EXCEPT_HDR),
  766. TblSize,
  767. "Exception Header" ))
  768. {
  769. return (1);
  770. }
  771. //
  772. // Write the exception table to the output file.
  773. //
  774. for (Ctr = 0; Ctr < TblSize; Ctr++)
  775. {
  776. if ((pLangExcept->pExceptTbl)[Ctr])
  777. {
  778. if (FileWrite( pOutputFile,
  779. (pLangExcept->pExceptTbl)[Ctr],
  780. sizeof(L_EXCEPT_NODE),
  781. ( ((pLangExcept->pExceptHdr)[Ctr]).NumUpEntries +
  782. ((pLangExcept->pExceptHdr)[Ctr]).NumLoEntries ),
  783. "Exception Table" ))
  784. {
  785. return (1);
  786. }
  787. }
  788. }
  789. //
  790. // Return success.
  791. //
  792. return (0);
  793. }