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.

1017 lines
25 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <tchar.h>
  7. #ifdef RLDOS
  8. #include "dosdefs.h"
  9. #else
  10. #include "windefs.h"
  11. #endif
  12. #include "restok.h"
  13. #include "resread.h"
  14. #include "toklist.h"
  15. #include "commbase.h"
  16. #define MAXLINE 1024
  17. #define MAXTERM 512
  18. extern UCHAR szDHW[];
  19. extern PROJDATA gProj;
  20. extern MSTRDATA gMstr;
  21. #ifdef WIN32
  22. extern HINSTANCE hInst; // Instance of the main window
  23. #else
  24. extern HWND hInst; // Instance of the main window
  25. #endif
  26. static fUnicodeGlossary = FALSE;
  27. static long GetGlossaryIndex( FILE *, TCHAR, long []);
  28. static void ParseGlossEntry( TCHAR *, TCHAR *, TCHAR[], TCHAR *, TCHAR[]);
  29. static void ParseTextHotKeyToBuf( TCHAR *, TCHAR, TCHAR *);
  30. static void ParseBufToTextHotKey( TCHAR *, TCHAR[], TCHAR *);
  31. static WORD NormalizeIndex( TCHAR);
  32. static int MyPutGlossStr( TCHAR *, FILE *);
  33. static TCHAR *MyGetGlossStr( TCHAR *, int, FILE *);
  34. static void BuildGlossEntry( TCHAR *, TCHAR *, TCHAR, TCHAR *, TCHAR);
  35. static BOOL NotAMember( TRANSLIST *, TCHAR *);
  36. FILE * OpenGlossary( CHAR *szGlossFile, CHAR chAccessType)
  37. {
  38. CHAR * szRW[4] = {"rb", "rt", "wb", "wt"};
  39. int nRW = 0; // assume access type is 'r' (read)
  40. FILE *fpRC = NULL;
  41. if ( chAccessType == 'w' ) // is access type 'w' (write)?
  42. {
  43. nRW = fUnicodeGlossary ? 2 : 3; // yes (Unicode file or not?)
  44. }
  45. fpRC = fopen( szGlossFile, szRW[ nRW]);
  46. if ( fpRC && chAccessType == 'r' )
  47. {
  48. USHORT usMark = GetWord( fpRC, NULL);
  49. if ( usMark == 0xfeff )
  50. {
  51. fUnicodeGlossary = TRUE; // it's a Unicode text file
  52. }
  53. else if ( usMark == 0xfffe )
  54. {
  55. QuitA( IDS_WRONGENDIAN, szGlossFile, NULL);
  56. }
  57. else
  58. {
  59. fclose( fpRC);
  60. fpRC = fopen( szGlossFile, szRW[ ++nRW]); // it's an ANSI text file
  61. }
  62. }
  63. return( fpRC);
  64. }
  65. /**
  66. *
  67. *
  68. * Function:
  69. *
  70. *
  71. * Arguments:
  72. *
  73. * Returns:
  74. *
  75. * Errors Codes:
  76. *
  77. * History:
  78. *
  79. *
  80. **/
  81. int MakeGlossIndex( LONG * lFilePointer)
  82. {
  83. TCHAR szGlossEntry[MAXLINE] = TEXT("");
  84. WORD iCurrent = 0;
  85. LONG lFPointer = -1;
  86. FILE *pFile = NULL;
  87. pFile = OpenGlossary( gProj.szGlo, 'r');
  88. if ( pFile == NULL )
  89. {
  90. return( 1);
  91. }
  92. // Glossaries some times have this bogus header at the begining.
  93. // which we want to skip if it exists
  94. if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
  95. {
  96. // Error during first read from the glossary.
  97. fclose( pFile);
  98. return( 1);
  99. }
  100. lFPointer = ftell( pFile);
  101. // check for glossary header
  102. if ( lstrlen( szGlossEntry) >= 7 )
  103. {
  104. // lstrcpy( (TCHAR *)szDHW, szGlossEntry);
  105. // szDHW[ MEMSIZE( 7)] = szDHW[ MEMSIZE( 7) + 1] = '\0';
  106. // CharLower( (TCHAR *)szDHW);
  107. //
  108. // if ( lstrcmp( (TCHAR *)szDHW, TEXT("english")) == 0 )
  109. if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  110. SORT_STRINGSORT | NORM_IGNORECASE,
  111. szGlossEntry,
  112. 7,
  113. TEXT("ENGLISH"),
  114. 7) == 2 )
  115. {
  116. lFPointer = ftell (pFile);
  117. if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
  118. {
  119. fclose( pFile);
  120. return (1);
  121. }
  122. }
  123. }
  124. // now assume we are at the correct location in glossary
  125. // file to begin generating the index, we want to save
  126. // this location
  127. lFilePointer[0] = lFPointer;
  128. // glossary file is sorted so, any non letter items
  129. // in the glossary would be first. Index into this location
  130. // using the 1st position
  131. // 1st lets make sure we have non letters items in
  132. // the glossary
  133. // now skip ( if any ) the non letter entries in the glossary
  134. while( (WORD) szGlossEntry[0] < (WORD) TEXT('A' ) )
  135. {
  136. if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
  137. {
  138. fclose( pFile);
  139. return( 1);
  140. }
  141. }
  142. // now position at alpha characters
  143. iCurrent = NormalizeIndex( szGlossEntry[0] );
  144. // now we read through the remaining glossary entries
  145. // and save the offsets for each index as we go
  146. do
  147. {
  148. if ( NormalizeIndex( szGlossEntry[0] ) > iCurrent )
  149. {
  150. // we passed the region for our current index
  151. // so save the location, and move to the next index.
  152. // note we may be skiping indexs,
  153. lFilePointer[ iCurrent] = lFPointer;
  154. iCurrent = NormalizeIndex( szGlossEntry[0] );
  155. }
  156. lFPointer = ftell( pFile );
  157. // otherwise the current index is valied for this
  158. // section of the glossary indexes, so just continue
  159. } while ( MyGetGlossStr( szGlossEntry, MAXLINE, pFile) );
  160. fclose( pFile);
  161. return( 0);
  162. }
  163. /**
  164. *
  165. *
  166. * Function: TransString
  167. * Builds a circular linked list containing all translations of a string.
  168. * The first entry in the list is the untranslated string.
  169. *
  170. * Arguments:
  171. * fpGlossFile, handle to open glossary file
  172. * szKeyText, string with the text to build translation table
  173. * szCurrentText, text currently in the box.
  174. * ppTransList, pointer to a pointer to a node in a circular linked list
  175. * lFilePointer, pointer to index table for glossary file
  176. *
  177. * Returns:
  178. * number of nodes in list
  179. *
  180. * Errors Codes:
  181. *
  182. * History:
  183. * Recoded by SteveBl, 3/92
  184. *
  185. **/
  186. /* Translate the string, if possible. */
  187. int TransString(
  188. TCHAR *szKeyText,
  189. TCHAR *szCurrentText,
  190. TRANSLIST **ppTransList,
  191. LONG *lFilePointer)
  192. {
  193. int n = 0;
  194. long lFileIndex;
  195. TRANSLIST **ppCurrentPointer;
  196. static TCHAR szGlossEntry[MAXLINE];
  197. static TCHAR szEngText[260];
  198. static TCHAR szIntlText[260];
  199. TCHAR *szCurText = NULL;
  200. TCHAR cEngHotKey = TEXT('\0');
  201. TCHAR cIntlHotKey = TEXT('\0');
  202. TCHAR cCurHotKey = TEXT('\0');
  203. FILE *fpGlossFile = NULL;
  204. // *Is* there a glossary file?
  205. if ( (fpGlossFile = OpenGlossary( gProj.szGlo, 'r')) == NULL )
  206. {
  207. return( 0);
  208. }
  209. // FIRST let's erase the list
  210. if ( *ppTransList )
  211. {
  212. (*ppTransList)->pPrev->pNext = NULL; // so we can find the end of the list
  213. }
  214. while ( *ppTransList )
  215. {
  216. TRANSLIST *pTemp;
  217. pTemp = *ppTransList;
  218. *ppTransList = pTemp->pNext;
  219. RLFREE( pTemp->sz);
  220. RLFREE( pTemp);
  221. }
  222. ppCurrentPointer = ppTransList;
  223. // DONE removing the list
  224. // Now make the first node (which is the untranslated string)
  225. {
  226. TCHAR * psz;
  227. psz = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szCurrentText) + 1));
  228. lstrcpy( psz,szCurrentText);
  229. *ppTransList = ( TRANSLIST *)FALLOC( sizeof( TRANSLIST));
  230. (*ppTransList)->pPrev = (*ppTransList)->pNext = *ppTransList;
  231. (*ppTransList)->sz = psz;
  232. ppCurrentPointer = ppTransList;
  233. n++;
  234. }
  235. szCurText = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szKeyText) + 1) );
  236. ParseBufToTextHotKey( szCurText, &cCurHotKey, szKeyText);
  237. lFileIndex = GetGlossaryIndex( fpGlossFile, szCurText[0], lFilePointer);
  238. fseek (fpGlossFile, lFileIndex, SEEK_SET);
  239. while ( TRUE)
  240. {
  241. if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, fpGlossFile) )
  242. {
  243. // Reached end of glossary file
  244. RLFREE( szCurText);
  245. fclose( fpGlossFile);
  246. return n;
  247. }
  248. ParseGlossEntry( szGlossEntry,
  249. szEngText,
  250. &cEngHotKey,
  251. szIntlText,
  252. &cIntlHotKey);
  253. // make comparision, using text, and hot keys
  254. // if ( ( ! lstrcmp( szCurText, szEngText )) && cCurHotKey == cEngHotKey )
  255. if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  256. SORT_STRINGSORT,
  257. szCurText,
  258. -1,
  259. szEngText,
  260. -1) == 2
  261. && cCurHotKey == cEngHotKey )
  262. {
  263. TCHAR * psz;
  264. static TCHAR szTemp[ MAXINPUTBUFFER];
  265. // we have a match, put translated text into token
  266. if ( cIntlHotKey )
  267. {
  268. ParseTextHotKeyToBuf( szIntlText, cIntlHotKey, szTemp);
  269. }
  270. else
  271. {
  272. lstrcpy( szTemp, szIntlText);
  273. }
  274. if ( NotAMember( *ppTransList, szTemp) )
  275. {
  276. // add matched glossary text to circular list of matches
  277. psz = (TCHAR *) FALLOC( MEMSIZE( lstrlen( szTemp) + 1));
  278. lstrcpy( psz,szTemp);
  279. (*ppCurrentPointer)->pNext = (TRANSLIST *)
  280. FALLOC( sizeof( TRANSLIST));
  281. ((*ppCurrentPointer)->pNext)->pPrev = *ppCurrentPointer;
  282. ppCurrentPointer = (TRANSLIST **)&((*ppCurrentPointer)->pNext);
  283. (*ppCurrentPointer)->pPrev->pNext = *ppCurrentPointer;
  284. (*ppCurrentPointer)->pNext = *ppTransList;
  285. (*ppTransList)->pPrev = *ppCurrentPointer;
  286. (*ppCurrentPointer)->sz = psz;
  287. ++n;
  288. }
  289. }
  290. else
  291. {
  292. // can we terminate search?
  293. // if( lstrcmpi( szEngText, szCurText ) > 0 )
  294. if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  295. SORT_STRINGSORT,
  296. szEngText,
  297. -1,
  298. szCurText,
  299. -1) == 3 )
  300. {
  301. // went past index section
  302. RLFREE( szCurText);
  303. fclose( fpGlossFile);
  304. return( n);
  305. }
  306. }
  307. }
  308. RLFREE( szCurText);
  309. fclose( fpGlossFile);
  310. return( n);
  311. } // TransString
  312. /**
  313. *
  314. *
  315. * Function: NormalizeIndex
  316. *
  317. *
  318. * Arguments:
  319. *
  320. * Returns:
  321. *
  322. * Errors Codes:
  323. *
  324. * History:
  325. *
  326. *
  327. **/
  328. static WORD NormalizeIndex( TCHAR chIndex )
  329. {
  330. TCHAR chTmp = chIndex;
  331. CharLowerBuff( &chTmp, 1);
  332. return( (chTmp != TEXT('"') && chTmp >= TEXT('a') && chTmp <= TEXT('z'))
  333. ? chTmp - TEXT('a') + 1
  334. : 0);
  335. }
  336. /*
  337. * Function:NotAMember
  338. *
  339. * Arguments:
  340. * pList, pointer to a TRANSLIST node
  341. * sz, string to find
  342. *
  343. * Returns:
  344. * TRUE if not found in the list else FALSE
  345. *
  346. * History:
  347. * 3/92, implemented SteveBl
  348. **/
  349. static BOOL NotAMember( TRANSLIST *pList, TCHAR *sz)
  350. {
  351. TRANSLIST *pCurrent = pList;
  352. if ( ! pList )
  353. {
  354. return( TRUE); // empty list
  355. }
  356. do
  357. {
  358. // if ( lstrcmp( sz, pCurrent->sz) == 0 )
  359. if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  360. SORT_STRINGSORT,
  361. sz,
  362. -1,
  363. pCurrent->sz,
  364. -1) == 2 )
  365. {
  366. return( FALSE); // found in list
  367. }
  368. pCurrent = pCurrent->pNext;
  369. }while ( pList != pCurrent );
  370. return( TRUE); // not found
  371. }
  372. /**
  373. *
  374. *
  375. * Function:
  376. *
  377. *
  378. * Arguments:
  379. *
  380. * Returns:
  381. *
  382. * Errors Codes:
  383. *
  384. * History:
  385. *
  386. *
  387. **/
  388. static void ParseGlossEntry(
  389. TCHAR szGlossEntry[],
  390. TCHAR szEngText[],
  391. TCHAR cEngHotKey[1],
  392. TCHAR szIntlText[],
  393. TCHAR cIntlHotKey[1])
  394. {
  395. WORD wIndex, wIndex2;
  396. // format is:
  397. // <eng text><tab><eng hot key><tab><loc text><tab><loc hot key>
  398. // Any field could be null and if there aren't the right amount of
  399. // tabs we'll just assume that the remaining fields are empty.
  400. wIndex=wIndex2=0;
  401. // first get the english text
  402. while ( szGlossEntry[wIndex2] != TEXT('\t')
  403. && szGlossEntry[wIndex2] != TEXT('\0') )
  404. {
  405. szEngText[ wIndex++] = szGlossEntry[ wIndex2++];
  406. }
  407. szEngText[wIndex]=TEXT('\0');
  408. if ( szGlossEntry[ wIndex2] == TEXT('\t') )
  409. {
  410. ++wIndex2; // skip the tab
  411. }
  412. // now get the eng hot key
  413. if ( szGlossEntry[wIndex2] != TEXT('\t')
  414. && szGlossEntry[wIndex2] != TEXT('\0') )
  415. {
  416. *cEngHotKey = szGlossEntry[wIndex2++];
  417. }
  418. else
  419. {
  420. *cEngHotKey = TEXT('\0');
  421. }
  422. while ( szGlossEntry[ wIndex2] != TEXT('\t')
  423. && szGlossEntry[ wIndex2] != TEXT('\0') )
  424. {
  425. ++wIndex2; // make sure the hot key field doesn't hold more than one char
  426. }
  427. if ( szGlossEntry[ wIndex2] == TEXT('\t') )
  428. {
  429. ++wIndex2; // skip the tab
  430. }
  431. wIndex = 0;
  432. // now get the intl text
  433. while ( szGlossEntry[ wIndex2] != TEXT('\t')
  434. && szGlossEntry[ wIndex2] != TEXT('\0') )
  435. {
  436. szIntlText[wIndex++]=szGlossEntry[wIndex2++];
  437. }
  438. szIntlText[wIndex]='\0';
  439. if ( szGlossEntry[ wIndex2] == TEXT('\t') )
  440. {
  441. ++wIndex2; // skip the tab
  442. }
  443. // now get the intl hot key
  444. if ( szGlossEntry[ wIndex2] != TEXT('\t')
  445. && szGlossEntry[ wIndex2] != TEXT('\0') )
  446. {
  447. *cIntlHotKey = szGlossEntry[ wIndex2++];
  448. }
  449. else
  450. {
  451. *cIntlHotKey = TEXT('\0');
  452. }
  453. }
  454. /**
  455. *
  456. *
  457. * Function:
  458. *
  459. *
  460. * Arguments:
  461. *
  462. * Returns:
  463. *
  464. * Errors Codes:
  465. *
  466. * History:
  467. *
  468. *
  469. **/
  470. static void ParseBufToTextHotKey(
  471. TCHAR *szText,
  472. TCHAR cHotKey[1],
  473. TCHAR *szBuf)
  474. {
  475. WORD wIndexBuf = 0;
  476. WORD wIndexText = 0;
  477. *cHotKey = TEXT('\0');
  478. while( szBuf[ wIndexBuf] )
  479. {
  480. if ( szBuf[ wIndexBuf ] == TEXT('&') )
  481. {
  482. *cHotKey = szBuf[ ++wIndexBuf];
  483. }
  484. else
  485. {
  486. szText[ wIndexText++] = szBuf[ wIndexBuf++];
  487. }
  488. }
  489. szText[ wIndexText] = TEXT('\0');
  490. }
  491. /**
  492. *
  493. *
  494. * Function:
  495. *
  496. *
  497. * Arguments:
  498. *
  499. * Returns:
  500. *
  501. * Errors Codes:
  502. *
  503. * History:
  504. *
  505. *
  506. **/
  507. static void ParseTextHotKeyToBuf(
  508. TCHAR *szText,
  509. TCHAR cHotKey,
  510. TCHAR *szBuf )
  511. {
  512. WORD wIndexBuf = 0;
  513. WORD wIndexText = 0;
  514. // TCHAR cTmp;
  515. while ( szText[ wIndexText] )
  516. {
  517. // cTmp = szText[ wIndexText];
  518. //
  519. // CharUpperBuff( &cTmp, 1);
  520. //
  521. // if ( cTmp == cHotKey )
  522. if ( szText[ wIndexText] == cHotKey )
  523. {
  524. szBuf[ wIndexBuf++] = TEXT('&');
  525. szBuf[ wIndexBuf++] = szText[ wIndexText++];
  526. break;
  527. }
  528. else
  529. {
  530. szBuf[ wIndexBuf++] = szText[ wIndexText++];
  531. }
  532. }
  533. // copy remaining string
  534. while( szText[ wIndexText] )
  535. {
  536. szBuf[ wIndexBuf++] = szText[ wIndexText++];
  537. }
  538. szBuf[ wIndexBuf] = TEXT('\0');
  539. }
  540. static long GetGlossaryIndex(
  541. FILE *fpGlossFile,
  542. TCHAR c,
  543. long *lGlossaryIndex )
  544. {
  545. int i = 0;
  546. TCHAR cTmp = c;
  547. CharLowerBuff( &cTmp, 1);
  548. if ( cTmp >= TEXT('a')
  549. && cTmp <= TEXT('z') )
  550. {
  551. i = NormalizeIndex( c );
  552. return( lGlossaryIndex[ i > 0 ? i - 1 : 0]);
  553. }
  554. else
  555. {
  556. return( 0);
  557. }
  558. }
  559. /*******************************************************************************
  560. * PROCEDURE: BuildGlossEntry
  561. * Builds a glossary entry line.
  562. *
  563. * Parameters:
  564. * sz, line buffer
  565. * sz1, untranslated text
  566. * c1, untranslated hot key (or 0 if no hot key)
  567. * sz2, translated text
  568. * c2, translated hot key (or 0 if no hot key)
  569. *
  570. * Returns:
  571. * nothing. sz contains the line. (assumes there is room in the buffer)
  572. *
  573. * History:
  574. * 3/93 - initial implementation - SteveBl
  575. *******************************************************************************/
  576. static void BuildGlossEntry(
  577. TCHAR *sz,
  578. TCHAR *sz1,
  579. TCHAR c1,
  580. TCHAR *sz2,
  581. TCHAR c2)
  582. {
  583. *sz = TEXT('\0');
  584. wsprintf( sz, TEXT("%s\t%c\t%s\t%c"), sz1, c1, sz2, c2);
  585. }
  586. /******************************************************************************
  587. * PROCEDURE: AddTranslation
  588. * Adds a translation to a glossary file.
  589. *
  590. * PARAMETERS:
  591. * szGlossFile, path to the glossary
  592. * szKey, untranslated text
  593. * szTranslation, translated text
  594. * lFilePointer, pointer to index hash table for glossary
  595. *
  596. * RETURNS:
  597. * nothing. Key is added to glossary if no errors are encountered else
  598. * file is left unchanged.
  599. *
  600. * COMMENTS:
  601. * rebuilds the global pointer list lFilePointer
  602. *
  603. * HISTORY: *
  604. * 3/92 - initial implementation - SteveBl
  605. ******************************************************************************/
  606. void AddTranslation(
  607. TCHAR *szKey,
  608. TCHAR *szTranslation,
  609. LONG *lFilePointer)
  610. {
  611. // DBCS begin
  612. TCHAR szCurText [520];
  613. TCHAR szTransText [520];
  614. // DBCS end
  615. TCHAR cTransHot = TEXT('\0');
  616. TCHAR cCurHotKey = TEXT('\0');
  617. CHAR szTempFileName [255];
  618. FILE *fTemp = NULL;
  619. FILE *fpGlossFile = NULL;
  620. TCHAR szTempText [MAXLINE];
  621. // DBCS begin
  622. TCHAR szNewText [MAXLINE * 2];
  623. // DBCS end
  624. TCHAR *r = NULL;
  625. TCHAR chTmp = TEXT('\0');
  626. MyGetTempFileName( 0, "", 0, szTempFileName);
  627. if ( (fTemp = OpenGlossary( szTempFileName, 'w')) != NULL )
  628. {
  629. if ( fUnicodeGlossary )
  630. {
  631. fprintf( fTemp, "%hu", 0xfeff); // Mark new one as Unicode
  632. }
  633. ParseBufToTextHotKey( szCurText, &cCurHotKey, szKey);
  634. ParseBufToTextHotKey( szTransText, &cTransHot, szTranslation);
  635. BuildGlossEntry( szNewText,
  636. szCurText,
  637. cCurHotKey,
  638. szTransText,
  639. cTransHot);
  640. // If the glossary file exists, get its first
  641. // line. If it doesn't exist, we'll create it
  642. // (via CopyFile) at the end of this function.
  643. if ( (fpGlossFile = OpenGlossary( gProj.szGlo, 'r')) != NULL )
  644. {
  645. if ( (r = MyGetGlossStr( szTempText,
  646. TCHARSIN( sizeof( szTempText)),
  647. fpGlossFile)) )
  648. {
  649. // lstrcpy( (TCHAR *)szDHW, szTempText);
  650. // szDHW[ MEMSIZE( 7)] = szDHW[ MEMSIZE( 7) + 1] = '\0';
  651. // CharLower( (TCHAR *)szDHW);
  652. //
  653. // if ( lstrcmpi( (TCHAR *)szDHW, TEXT("ENGLISH")) == 0 )
  654. if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  655. SORT_STRINGSORT | NORM_IGNORECASE,
  656. szTempText,
  657. 7,
  658. TEXT("ENGLISH"),
  659. 7) == 2 )
  660. {
  661. // skip first line
  662. MyPutGlossStr( szTempText, fTemp);
  663. r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
  664. }
  665. }
  666. }
  667. else
  668. {
  669. r = NULL;
  670. }
  671. // if ( r )
  672. // {
  673. // chTmp = szTempText[0];
  674. // CharLowerBuff( &chTmp, 1);
  675. // }
  676. // else
  677. // {
  678. // chTmp = szTempText[0] = TEXT('\0');
  679. // }
  680. // // Does the new text begin with a letter?
  681. //
  682. // if ( chTmp >= TEXT('a') )
  683. // {
  684. // // begins with a letter, we need to find where to put it
  685. //
  686. // while ( r && chTmp < TEXT('a') )
  687. while ( r && CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
  688. SORT_STRINGSORT,
  689. szTempText,
  690. -1,
  691. szNewText,
  692. -1) == 1 )
  693. {
  694. // skip the non letter section
  695. MyPutGlossStr( szTempText, fTemp);
  696. r = MyGetGlossStr( szTempText,
  697. TCHARSIN( sizeof( szTempText)),
  698. fpGlossFile);
  699. // if ( (r = MyGetGlossStr( szTempText,
  700. // TCHARSIN( sizeof( szTempText)),
  701. // fpGlossFile)) )
  702. // {
  703. // chTmp = szTempText[0];
  704. // CharLowerBuff( &chTmp, 1);
  705. // }
  706. }
  707. // while ( r && _tcsicmp( szTempText, szNewText) < 0 )
  708. // {
  709. // // skip anything smaller than me
  710. //
  711. // MyPutGlossStr( szTempText, fTemp);
  712. // r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
  713. // }
  714. // }
  715. // else
  716. // {
  717. // // doesn't begin with a letter, we need to insert it before
  718. // // the letter sections begin but it still must be sorted
  719. //
  720. // while ( r
  721. // && chTmp < TEXT('a')
  722. // && _tcsicmp( szTempText, szNewText) < 0 )
  723. // {
  724. // MyPutGlossStr( szTempText, fTemp);
  725. //
  726. // if ( (r = MyGetGlossStr( szTempText,
  727. // TCHARSIN( sizeof( szTempText)),
  728. // fpGlossFile)) )
  729. // {
  730. // chTmp = szTempText[0];
  731. // CharLowerBuff( &chTmp, 1);
  732. // }
  733. // }
  734. // }
  735. MyPutGlossStr( szNewText, fTemp);
  736. while ( r )
  737. {
  738. MyPutGlossStr( szTempText,fTemp);
  739. r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
  740. }
  741. fclose( fTemp);
  742. if ( fpGlossFile )
  743. {
  744. fclose( fpGlossFile);
  745. }
  746. // This call will create the glossary file
  747. // if it didn't already exist.
  748. if ( ! CopyFileA( szTempFileName, gProj.szGlo, FALSE) )
  749. {
  750. QuitA( IDS_COPYFILE_FAILED, szTempFileName, gProj.szGlo);
  751. }
  752. remove( szTempFileName);
  753. MakeGlossIndex( lFilePointer);
  754. }
  755. else
  756. {
  757. QuitA( IDS_NO_TMP_GLOSS, szTempFileName, NULL);
  758. }
  759. }
  760. /**
  761. *
  762. *
  763. * Function: MyGetGlossStr
  764. * Replaces C runtime fgets function.
  765. *
  766. * History:
  767. * 5/92, Implemented. TerryRu.
  768. *
  769. *
  770. **/
  771. static TCHAR *MyGetGlossStr( TCHAR * ptszStr, int nCount, FILE * fIn)
  772. {
  773. int i = 0;
  774. #ifdef RLRES32
  775. // It this a Unicode glossary file?
  776. TCHAR tCh = TEXT('\0');
  777. if ( fUnicodeGlossary )
  778. {
  779. do // Yes
  780. {
  781. tCh = ptszStr[ i++] = (TCHAR)GetWord( fIn, NULL);
  782. } while ( i < nCount && tCh != TEXT('\n') );
  783. if ( tCh == TEXT('\0') || feof( fIn) )
  784. {
  785. return( NULL);
  786. }
  787. ptszStr[i] = TEXT('\0');
  788. StripNewLineW( ptszStr);
  789. }
  790. else // No, it's an ANSI glossary file
  791. {
  792. if ( fgets( szDHW, DHWSIZE, fIn) != NULL )
  793. {
  794. StripNewLineA( szDHW);
  795. _MBSTOWCS( ptszStr, szDHW, nCount, (UINT)-1);
  796. }
  797. else
  798. {
  799. return( NULL);
  800. }
  801. }
  802. return( ptszStr);
  803. #else //RLRES32
  804. if ( fgets( ptszStr, nCount, fIn) )
  805. {
  806. StripNewLineA( ptszStr);
  807. }
  808. else
  809. {
  810. return( NULL);
  811. }
  812. #endif //RLRES32
  813. }
  814. /**
  815. *
  816. *
  817. * Function: MyPutGlossStr
  818. * Replaces C runtime fputs function.
  819. * History:
  820. * 6/92, Implemented. TerryRu.
  821. *
  822. *
  823. **/
  824. static int MyPutGlossStr( TCHAR * ptszStr, FILE * fOut)
  825. {
  826. #ifdef RLRES32
  827. int i = 0;
  828. // It this a Unicode glossary file?
  829. if ( fUnicodeGlossary )
  830. {
  831. do // Yes
  832. {
  833. PutWord( fOut, ptszStr[i], NULL);
  834. } while ( ptszStr[ i++] );
  835. PutWord( fOut, TEXT('\r'), NULL);
  836. PutWord( fOut, TEXT('\n'), NULL);
  837. i += 2;
  838. }
  839. else // No, it's an ANSI glossary file
  840. {
  841. _WCSTOMBS( szDHW, ptszStr, DHWSIZE, lstrlen( ptszStr) + 1);
  842. i = fputs( szDHW, fOut);
  843. fputs( "\n", fOut);
  844. }
  845. #else //RLRES32
  846. i = fputs( ptszStr, fOut);
  847. fputs( "\n", fOut);
  848. #endif //RLRES32
  849. return(i);
  850. }