1018 lines
24 KiB
C
1018 lines
24 KiB
C
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <tchar.h>
|
|
|
|
#ifdef RLDOS
|
|
#include "dosdefs.h"
|
|
#else
|
|
#include "windefs.h"
|
|
#endif
|
|
|
|
#include "restok.h"
|
|
#include "resread.h"
|
|
#include "toklist.h"
|
|
#include "commbase.h"
|
|
|
|
|
|
#define MAXLINE 1024
|
|
#define MAXTERM 512
|
|
|
|
|
|
extern UCHAR szDHW[];
|
|
extern PROJDATA gProj;
|
|
extern MSTRDATA gMstr;
|
|
|
|
#ifdef WIN32
|
|
extern HINSTANCE hInst; // Instance of the main window
|
|
#else
|
|
extern HWND hInst; // Instance of the main window
|
|
#endif
|
|
|
|
static fUnicodeGlossary = FALSE;
|
|
|
|
|
|
static long GetGlossaryIndex( FILE *, TCHAR, long []);
|
|
static void ParseGlossEntry( TCHAR *, TCHAR *, TCHAR[], TCHAR *, TCHAR[]);
|
|
static void ParseTextHotKeyToBuf( TCHAR *, TCHAR, TCHAR *);
|
|
static void ParseBufToTextHotKey( TCHAR *, TCHAR[], TCHAR *);
|
|
static WORD NormalizeIndex( TCHAR);
|
|
static int MyPutGlossStr( TCHAR *, FILE *);
|
|
static TCHAR *MyGetGlossStr( TCHAR *, int, FILE *);
|
|
static void BuildGlossEntry( TCHAR *, TCHAR *, TCHAR, TCHAR *, TCHAR);
|
|
static BOOL NotAMember( TRANSLIST *, TCHAR *);
|
|
|
|
|
|
|
|
|
|
FILE * OpenGlossary( CHAR *szGlossFile, CHAR chAccessType)
|
|
{
|
|
CHAR * szRW[4] = {"rb", "rt", "wb", "wt"};
|
|
int nRW = 0; // assume access type is 'r' (read)
|
|
FILE *fpRC = NULL;
|
|
|
|
if ( chAccessType == 'w' ) // is access type 'w' (write)?
|
|
{
|
|
nRW = fUnicodeGlossary ? 2 : 3; // yes (Unicode file or not?)
|
|
}
|
|
fpRC = fopen( szGlossFile, szRW[ nRW]);
|
|
|
|
if ( fpRC && chAccessType == 'r' )
|
|
{
|
|
USHORT usMark = GetWord( fpRC, NULL);
|
|
|
|
if ( usMark == 0xfeff )
|
|
{
|
|
fUnicodeGlossary = TRUE; // it's a Unicode text file
|
|
}
|
|
else if ( usMark == 0xfffe )
|
|
{
|
|
QuitA( IDS_WRONGENDIAN, szGlossFile, NULL);
|
|
}
|
|
else
|
|
{
|
|
fclose( fpRC);
|
|
fpRC = fopen( szGlossFile, szRW[ ++nRW]); // it's an ANSI text file
|
|
}
|
|
}
|
|
return( fpRC);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function:
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
*
|
|
*
|
|
**/
|
|
|
|
int MakeGlossIndex( LONG * lFilePointer)
|
|
{
|
|
TCHAR szGlossEntry[MAXLINE] = TEXT("");
|
|
WORD iCurrent = 0;
|
|
LONG lFPointer = -1;
|
|
FILE *pFile = NULL;
|
|
|
|
|
|
pFile = OpenGlossary( gProj.szGlo, 'r');
|
|
|
|
if ( pFile == NULL )
|
|
{
|
|
return( 1);
|
|
}
|
|
|
|
// Glossaries some times have this bogus header at the begining.
|
|
// which we want to skip if it exists
|
|
|
|
|
|
if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
|
|
{
|
|
// Error during first read from the glossary.
|
|
fclose( pFile);
|
|
return( 1);
|
|
}
|
|
lFPointer = ftell( pFile);
|
|
|
|
// check for glossary header
|
|
|
|
if ( lstrlen( szGlossEntry) >= 7 )
|
|
{
|
|
// lstrcpy( (TCHAR *)szDHW, szGlossEntry);
|
|
// szDHW[ MEMSIZE( 7)] = szDHW[ MEMSIZE( 7) + 1] = '\0';
|
|
// CharLower( (TCHAR *)szDHW);
|
|
//
|
|
// if ( lstrcmp( (TCHAR *)szDHW, TEXT("english")) == 0 )
|
|
if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT | NORM_IGNORECASE,
|
|
szGlossEntry,
|
|
7,
|
|
TEXT("ENGLISH"),
|
|
7) == 2 )
|
|
{
|
|
lFPointer = ftell (pFile);
|
|
|
|
if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
|
|
{
|
|
fclose( pFile);
|
|
return (1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// now assume we are at the correct location in glossary
|
|
// file to begin generating the index, we want to save
|
|
// this location
|
|
|
|
lFilePointer[0] = lFPointer;
|
|
|
|
// glossary file is sorted so, any non letter items
|
|
// in the glossary would be first. Index into this location
|
|
// using the 1st position
|
|
|
|
// 1st lets make sure we have non letters items in
|
|
// the glossary
|
|
|
|
// now skip ( if any ) the non letter entries in the glossary
|
|
|
|
|
|
while( (WORD) szGlossEntry[0] < (WORD) TEXT('A' ) )
|
|
{
|
|
if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, pFile) )
|
|
{
|
|
fclose( pFile);
|
|
return( 1);
|
|
}
|
|
}
|
|
|
|
// now position at alpha characters
|
|
|
|
iCurrent = NormalizeIndex( szGlossEntry[0] );
|
|
|
|
// now we read through the remaining glossary entries
|
|
// and save the offsets for each index as we go
|
|
|
|
do
|
|
{
|
|
if ( NormalizeIndex( szGlossEntry[0] ) > iCurrent )
|
|
{
|
|
// we passed the region for our current index
|
|
// so save the location, and move to the next index.
|
|
// note we may be skiping indexs,
|
|
|
|
lFilePointer[ iCurrent] = lFPointer;
|
|
iCurrent = NormalizeIndex( szGlossEntry[0] );
|
|
}
|
|
|
|
lFPointer = ftell( pFile );
|
|
// otherwise the current index is valied for this
|
|
// section of the glossary indexes, so just continue
|
|
|
|
} while ( MyGetGlossStr( szGlossEntry, MAXLINE, pFile) );
|
|
|
|
fclose( pFile);
|
|
return( 0);
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function: TransString
|
|
* Builds a circular linked list containing all translations of a string.
|
|
* The first entry in the list is the untranslated string.
|
|
*
|
|
* Arguments:
|
|
* fpGlossFile, handle to open glossary file
|
|
* szKeyText, string with the text to build translation table
|
|
* szCurrentText, text currently in the box.
|
|
* ppTransList, pointer to a pointer to a node in a circular linked list
|
|
* lFilePointer, pointer to index table for glossary file
|
|
*
|
|
* Returns:
|
|
* number of nodes in list
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
* Recoded by SteveBl, 3/92
|
|
*
|
|
**/
|
|
|
|
/* Translate the string, if possible. */
|
|
|
|
int TransString(
|
|
|
|
TCHAR *szKeyText,
|
|
TCHAR *szCurrentText,
|
|
TRANSLIST **ppTransList,
|
|
LONG *lFilePointer)
|
|
{
|
|
int n = 0;
|
|
long lFileIndex;
|
|
TRANSLIST **ppCurrentPointer;
|
|
static TCHAR szGlossEntry[MAXLINE];
|
|
static TCHAR szEngText[260];
|
|
static TCHAR szIntlText[260];
|
|
TCHAR *szCurText = NULL;
|
|
TCHAR cEngHotKey = TEXT('\0');
|
|
TCHAR cIntlHotKey = TEXT('\0');
|
|
TCHAR cCurHotKey = TEXT('\0');
|
|
FILE *fpGlossFile = NULL;
|
|
|
|
// *Is* there a glossary file?
|
|
|
|
if ( (fpGlossFile = OpenGlossary( gProj.szGlo, 'r')) == NULL )
|
|
{
|
|
return( 0);
|
|
}
|
|
|
|
// FIRST let's erase the list
|
|
if ( *ppTransList )
|
|
{
|
|
(*ppTransList)->pPrev->pNext = NULL; // so we can find the end of the list
|
|
}
|
|
|
|
while ( *ppTransList )
|
|
{
|
|
TRANSLIST *pTemp;
|
|
|
|
pTemp = *ppTransList;
|
|
*ppTransList = pTemp->pNext;
|
|
RLFREE( pTemp->sz);
|
|
RLFREE( pTemp);
|
|
}
|
|
ppCurrentPointer = ppTransList;
|
|
|
|
// DONE removing the list
|
|
// Now make the first node (which is the untranslated string)
|
|
{
|
|
TCHAR * psz;
|
|
psz = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szCurrentText) + 1));
|
|
|
|
|
|
lstrcpy( psz,szCurrentText);
|
|
*ppTransList = ( TRANSLIST *)FALLOC( sizeof( TRANSLIST));
|
|
(*ppTransList)->pPrev = (*ppTransList)->pNext = *ppTransList;
|
|
(*ppTransList)->sz = psz;
|
|
ppCurrentPointer = ppTransList;
|
|
n++;
|
|
}
|
|
szCurText = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szKeyText) + 1) );
|
|
|
|
ParseBufToTextHotKey( szCurText, &cCurHotKey, szKeyText);
|
|
|
|
lFileIndex = GetGlossaryIndex( fpGlossFile, szCurText[0], lFilePointer);
|
|
|
|
fseek (fpGlossFile, lFileIndex, SEEK_SET);
|
|
|
|
while ( TRUE)
|
|
{
|
|
if ( ! MyGetGlossStr( szGlossEntry, MAXLINE, fpGlossFile) )
|
|
{
|
|
// Reached end of glossary file
|
|
RLFREE( szCurText);
|
|
fclose( fpGlossFile);
|
|
return n;
|
|
}
|
|
ParseGlossEntry( szGlossEntry,
|
|
szEngText,
|
|
&cEngHotKey,
|
|
szIntlText,
|
|
&cIntlHotKey);
|
|
|
|
// make comparision, using text, and hot keys
|
|
|
|
// if ( ( ! lstrcmp( szCurText, szEngText )) && cCurHotKey == cEngHotKey )
|
|
if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT,
|
|
szCurText,
|
|
-1,
|
|
szEngText,
|
|
-1) == 2
|
|
&& cCurHotKey == cEngHotKey )
|
|
{
|
|
TCHAR * psz;
|
|
static TCHAR szTemp[ MAXINPUTBUFFER];
|
|
|
|
// we have a match, put translated text into token
|
|
if ( cIntlHotKey )
|
|
{
|
|
ParseTextHotKeyToBuf( szIntlText, cIntlHotKey, szTemp);
|
|
}
|
|
else
|
|
{
|
|
lstrcpy( szTemp, szIntlText);
|
|
}
|
|
|
|
if ( NotAMember( *ppTransList, szTemp) )
|
|
{
|
|
// add matched glossary text to circular list of matches
|
|
|
|
psz = (TCHAR *) FALLOC( MEMSIZE( lstrlen( szTemp) + 1));
|
|
|
|
lstrcpy( psz,szTemp);
|
|
|
|
(*ppCurrentPointer)->pNext = (TRANSLIST *)
|
|
FALLOC( sizeof( TRANSLIST));
|
|
|
|
((*ppCurrentPointer)->pNext)->pPrev = *ppCurrentPointer;
|
|
ppCurrentPointer = (TRANSLIST **)&((*ppCurrentPointer)->pNext);
|
|
(*ppCurrentPointer)->pPrev->pNext = *ppCurrentPointer;
|
|
(*ppCurrentPointer)->pNext = *ppTransList;
|
|
(*ppTransList)->pPrev = *ppCurrentPointer;
|
|
(*ppCurrentPointer)->sz = psz;
|
|
++n;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// can we terminate search?
|
|
// if( lstrcmpi( szEngText, szCurText ) > 0 )
|
|
if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT,
|
|
szEngText,
|
|
-1,
|
|
szCurText,
|
|
-1) == 3 )
|
|
{
|
|
// went past index section
|
|
RLFREE( szCurText);
|
|
fclose( fpGlossFile);
|
|
return( n);
|
|
}
|
|
}
|
|
}
|
|
RLFREE( szCurText);
|
|
fclose( fpGlossFile);
|
|
|
|
return( n);
|
|
} // TransString
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function: NormalizeIndex
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
*
|
|
*
|
|
**/
|
|
|
|
|
|
static WORD NormalizeIndex( TCHAR chIndex )
|
|
{
|
|
TCHAR chTmp = chIndex;
|
|
|
|
CharLowerBuff( &chTmp, 1);
|
|
|
|
return( (chTmp != TEXT('"') && chTmp >= TEXT('a') && chTmp <= TEXT('z'))
|
|
? chTmp - TEXT('a') + 1
|
|
: 0);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Function:NotAMember
|
|
*
|
|
* Arguments:
|
|
* pList, pointer to a TRANSLIST node
|
|
* sz, string to find
|
|
*
|
|
* Returns:
|
|
* TRUE if not found in the list else FALSE
|
|
*
|
|
* History:
|
|
* 3/92, implemented SteveBl
|
|
**/
|
|
|
|
static BOOL NotAMember( TRANSLIST *pList, TCHAR *sz)
|
|
{
|
|
TRANSLIST *pCurrent = pList;
|
|
|
|
if ( ! pList )
|
|
{
|
|
return( TRUE); // empty list
|
|
}
|
|
|
|
do
|
|
{
|
|
// if ( lstrcmp( sz, pCurrent->sz) == 0 )
|
|
if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT,
|
|
sz,
|
|
-1,
|
|
pCurrent->sz,
|
|
-1) == 2 )
|
|
{
|
|
return( FALSE); // found in list
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
|
|
}while ( pList != pCurrent );
|
|
|
|
return( TRUE); // not found
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function:
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
*
|
|
*
|
|
**/
|
|
|
|
static void ParseGlossEntry(
|
|
|
|
TCHAR szGlossEntry[],
|
|
TCHAR szEngText[],
|
|
TCHAR cEngHotKey[1],
|
|
TCHAR szIntlText[],
|
|
TCHAR cIntlHotKey[1])
|
|
{
|
|
|
|
WORD wIndex, wIndex2;
|
|
|
|
// format is:
|
|
// <eng text><tab><eng hot key><tab><loc text><tab><loc hot key>
|
|
// Any field could be null and if there aren't the right amount of
|
|
// tabs we'll just assume that the remaining fields are empty.
|
|
|
|
wIndex=wIndex2=0;
|
|
|
|
// first get the english text
|
|
while ( szGlossEntry[wIndex2] != TEXT('\t')
|
|
&& szGlossEntry[wIndex2] != TEXT('\0') )
|
|
{
|
|
szEngText[ wIndex++] = szGlossEntry[ wIndex2++];
|
|
}
|
|
szEngText[wIndex]=TEXT('\0');
|
|
|
|
if ( szGlossEntry[ wIndex2] == TEXT('\t') )
|
|
{
|
|
++wIndex2; // skip the tab
|
|
}
|
|
// now get the eng hot key
|
|
if ( szGlossEntry[wIndex2] != TEXT('\t')
|
|
&& szGlossEntry[wIndex2] != TEXT('\0') )
|
|
{
|
|
*cEngHotKey = szGlossEntry[wIndex2++];
|
|
}
|
|
else
|
|
{
|
|
*cEngHotKey = TEXT('\0');
|
|
}
|
|
|
|
while ( szGlossEntry[ wIndex2] != TEXT('\t')
|
|
&& szGlossEntry[ wIndex2] != TEXT('\0') )
|
|
{
|
|
++wIndex2; // make sure the hot key field doesn't hold more than one char
|
|
}
|
|
|
|
if ( szGlossEntry[ wIndex2] == TEXT('\t') )
|
|
{
|
|
++wIndex2; // skip the tab
|
|
}
|
|
wIndex = 0;
|
|
|
|
// now get the intl text
|
|
while ( szGlossEntry[ wIndex2] != TEXT('\t')
|
|
&& szGlossEntry[ wIndex2] != TEXT('\0') )
|
|
{
|
|
szIntlText[wIndex++]=szGlossEntry[wIndex2++];
|
|
}
|
|
szIntlText[wIndex]='\0';
|
|
|
|
if ( szGlossEntry[ wIndex2] == TEXT('\t') )
|
|
{
|
|
++wIndex2; // skip the tab
|
|
}
|
|
|
|
// now get the intl hot key
|
|
if ( szGlossEntry[ wIndex2] != TEXT('\t')
|
|
&& szGlossEntry[ wIndex2] != TEXT('\0') )
|
|
{
|
|
*cIntlHotKey = szGlossEntry[ wIndex2++];
|
|
}
|
|
else
|
|
{
|
|
*cIntlHotKey = TEXT('\0');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function:
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
*
|
|
*
|
|
**/
|
|
|
|
static void ParseBufToTextHotKey(
|
|
|
|
TCHAR *szText,
|
|
TCHAR cHotKey[1],
|
|
TCHAR *szBuf)
|
|
{
|
|
|
|
WORD wIndexBuf = 0;
|
|
WORD wIndexText = 0;
|
|
|
|
*cHotKey = TEXT('\0');
|
|
|
|
while( szBuf[ wIndexBuf] )
|
|
{
|
|
if ( szBuf[ wIndexBuf ] == TEXT('&') )
|
|
{
|
|
*cHotKey = szBuf[ ++wIndexBuf];
|
|
}
|
|
else
|
|
{
|
|
szText[ wIndexText++] = szBuf[ wIndexBuf++];
|
|
}
|
|
}
|
|
szText[ wIndexText] = TEXT('\0');
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function:
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Errors Codes:
|
|
*
|
|
* History:
|
|
*
|
|
*
|
|
**/
|
|
|
|
static void ParseTextHotKeyToBuf(
|
|
|
|
TCHAR *szText,
|
|
TCHAR cHotKey,
|
|
TCHAR *szBuf )
|
|
{
|
|
WORD wIndexBuf = 0;
|
|
WORD wIndexText = 0;
|
|
// TCHAR cTmp;
|
|
|
|
|
|
while ( szText[ wIndexText] )
|
|
{
|
|
// cTmp = szText[ wIndexText];
|
|
//
|
|
// CharUpperBuff( &cTmp, 1);
|
|
//
|
|
// if ( cTmp == cHotKey )
|
|
if ( szText[ wIndexText] == cHotKey )
|
|
{
|
|
szBuf[ wIndexBuf++] = TEXT('&');
|
|
szBuf[ wIndexBuf++] = szText[ wIndexText++];
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
szBuf[ wIndexBuf++] = szText[ wIndexText++];
|
|
}
|
|
}
|
|
|
|
// copy remaining string
|
|
|
|
while( szText[ wIndexText] )
|
|
{
|
|
szBuf[ wIndexBuf++] = szText[ wIndexText++];
|
|
}
|
|
szBuf[ wIndexBuf] = TEXT('\0');
|
|
}
|
|
|
|
|
|
static long GetGlossaryIndex(
|
|
|
|
FILE *fpGlossFile,
|
|
TCHAR c,
|
|
long *lGlossaryIndex )
|
|
{
|
|
int i = 0;
|
|
TCHAR cTmp = c;
|
|
|
|
CharLowerBuff( &cTmp, 1);
|
|
|
|
if ( cTmp >= TEXT('a')
|
|
&& cTmp <= TEXT('z') )
|
|
{
|
|
i = NormalizeIndex( c );
|
|
return( lGlossaryIndex[ i > 0 ? i - 1 : 0]);
|
|
}
|
|
else
|
|
{
|
|
return( 0);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* PROCEDURE: BuildGlossEntry
|
|
* Builds a glossary entry line.
|
|
*
|
|
* Parameters:
|
|
* sz, line buffer
|
|
* sz1, untranslated text
|
|
* c1, untranslated hot key (or 0 if no hot key)
|
|
* sz2, translated text
|
|
* c2, translated hot key (or 0 if no hot key)
|
|
*
|
|
* Returns:
|
|
* nothing. sz contains the line. (assumes there is room in the buffer)
|
|
*
|
|
* History:
|
|
* 3/93 - initial implementation - SteveBl
|
|
*******************************************************************************/
|
|
|
|
static void BuildGlossEntry(
|
|
|
|
TCHAR *sz,
|
|
TCHAR *sz1,
|
|
TCHAR c1,
|
|
TCHAR *sz2,
|
|
TCHAR c2)
|
|
{
|
|
*sz = TEXT('\0');
|
|
wsprintf( sz, TEXT("%s\t%c\t%s\t%c"), sz1, c1, sz2, c2);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* PROCEDURE: AddTranslation
|
|
* Adds a translation to a glossary file.
|
|
*
|
|
* PARAMETERS:
|
|
* szGlossFile, path to the glossary
|
|
* szKey, untranslated text
|
|
* szTranslation, translated text
|
|
* lFilePointer, pointer to index hash table for glossary
|
|
*
|
|
* RETURNS:
|
|
* nothing. Key is added to glossary if no errors are encountered else
|
|
* file is left unchanged.
|
|
*
|
|
* COMMENTS:
|
|
* rebuilds the global pointer list lFilePointer
|
|
*
|
|
* HISTORY: *
|
|
* 3/92 - initial implementation - SteveBl
|
|
******************************************************************************/
|
|
|
|
void AddTranslation(
|
|
|
|
TCHAR *szKey,
|
|
TCHAR *szTranslation,
|
|
LONG *lFilePointer)
|
|
{
|
|
|
|
// DBCS begin
|
|
TCHAR szCurText [520];
|
|
TCHAR szTransText [520];
|
|
// DBCS end
|
|
TCHAR cTransHot = TEXT('\0');
|
|
TCHAR cCurHotKey = TEXT('\0');
|
|
CHAR szTempFileName [255];
|
|
FILE *fTemp = NULL;
|
|
FILE *fpGlossFile = NULL;
|
|
TCHAR szTempText [MAXLINE];
|
|
// DBCS begin
|
|
TCHAR szNewText [MAXLINE * 2];
|
|
// DBCS end
|
|
TCHAR *r = NULL;
|
|
TCHAR chTmp = TEXT('\0');
|
|
|
|
MyGetTempFileName( 0, "", 0, szTempFileName);
|
|
|
|
if ( (fTemp = OpenGlossary( szTempFileName, 'w')) != NULL )
|
|
{
|
|
if ( fUnicodeGlossary )
|
|
{
|
|
fprintf( fTemp, "%hu", 0xfeff); // Mark new one as Unicode
|
|
}
|
|
|
|
ParseBufToTextHotKey( szCurText, &cCurHotKey, szKey);
|
|
ParseBufToTextHotKey( szTransText, &cTransHot, szTranslation);
|
|
|
|
BuildGlossEntry( szNewText,
|
|
szCurText,
|
|
cCurHotKey,
|
|
szTransText,
|
|
cTransHot);
|
|
|
|
// If the glossary file exists, get its first
|
|
// line. If it doesn't exist, we'll create it
|
|
// (via CopyFile) at the end of this function.
|
|
|
|
if ( (fpGlossFile = OpenGlossary( gProj.szGlo, 'r')) != NULL )
|
|
{
|
|
if ( (r = MyGetGlossStr( szTempText,
|
|
TCHARSIN( sizeof( szTempText)),
|
|
fpGlossFile)) )
|
|
{
|
|
// lstrcpy( (TCHAR *)szDHW, szTempText);
|
|
// szDHW[ MEMSIZE( 7)] = szDHW[ MEMSIZE( 7) + 1] = '\0';
|
|
// CharLower( (TCHAR *)szDHW);
|
|
//
|
|
// if ( lstrcmpi( (TCHAR *)szDHW, TEXT("ENGLISH")) == 0 )
|
|
|
|
if ( CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT | NORM_IGNORECASE,
|
|
szTempText,
|
|
7,
|
|
TEXT("ENGLISH"),
|
|
7) == 2 )
|
|
{
|
|
// skip first line
|
|
|
|
MyPutGlossStr( szTempText, fTemp);
|
|
r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
r = NULL;
|
|
}
|
|
|
|
// if ( r )
|
|
// {
|
|
// chTmp = szTempText[0];
|
|
// CharLowerBuff( &chTmp, 1);
|
|
// }
|
|
// else
|
|
// {
|
|
// chTmp = szTempText[0] = TEXT('\0');
|
|
// }
|
|
// // Does the new text begin with a letter?
|
|
//
|
|
// if ( chTmp >= TEXT('a') )
|
|
// {
|
|
// // begins with a letter, we need to find where to put it
|
|
//
|
|
// while ( r && chTmp < TEXT('a') )
|
|
while ( r && CompareStringW( MAKELCID( gMstr.wLanguageID, SORT_DEFAULT),
|
|
SORT_STRINGSORT,
|
|
szTempText,
|
|
-1,
|
|
szNewText,
|
|
-1) == 1 )
|
|
{
|
|
// skip the non letter section
|
|
MyPutGlossStr( szTempText, fTemp);
|
|
|
|
r = MyGetGlossStr( szTempText,
|
|
TCHARSIN( sizeof( szTempText)),
|
|
fpGlossFile);
|
|
// if ( (r = MyGetGlossStr( szTempText,
|
|
// TCHARSIN( sizeof( szTempText)),
|
|
// fpGlossFile)) )
|
|
// {
|
|
// chTmp = szTempText[0];
|
|
// CharLowerBuff( &chTmp, 1);
|
|
// }
|
|
}
|
|
|
|
// while ( r && _tcsicmp( szTempText, szNewText) < 0 )
|
|
// {
|
|
// // skip anything smaller than me
|
|
//
|
|
// MyPutGlossStr( szTempText, fTemp);
|
|
// r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// // doesn't begin with a letter, we need to insert it before
|
|
// // the letter sections begin but it still must be sorted
|
|
//
|
|
// while ( r
|
|
// && chTmp < TEXT('a')
|
|
// && _tcsicmp( szTempText, szNewText) < 0 )
|
|
// {
|
|
// MyPutGlossStr( szTempText, fTemp);
|
|
//
|
|
// if ( (r = MyGetGlossStr( szTempText,
|
|
// TCHARSIN( sizeof( szTempText)),
|
|
// fpGlossFile)) )
|
|
// {
|
|
// chTmp = szTempText[0];
|
|
// CharLowerBuff( &chTmp, 1);
|
|
// }
|
|
// }
|
|
// }
|
|
MyPutGlossStr( szNewText, fTemp);
|
|
|
|
while ( r )
|
|
{
|
|
MyPutGlossStr( szTempText,fTemp);
|
|
r = MyGetGlossStr( szTempText, TCHARSIN( sizeof( szTempText)), fpGlossFile);
|
|
}
|
|
fclose( fTemp);
|
|
|
|
if ( fpGlossFile )
|
|
{
|
|
fclose( fpGlossFile);
|
|
}
|
|
// This call will create the glossary file
|
|
// if it didn't already exist.
|
|
|
|
if ( ! CopyFileA( szTempFileName, gProj.szGlo, FALSE) )
|
|
{
|
|
QuitA( IDS_COPYFILE_FAILED, szTempFileName, gProj.szGlo);
|
|
}
|
|
remove( szTempFileName);
|
|
|
|
MakeGlossIndex( lFilePointer);
|
|
}
|
|
else
|
|
{
|
|
QuitA( IDS_NO_TMP_GLOSS, szTempFileName, NULL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function: MyGetGlossStr
|
|
* Replaces C runtime fgets function.
|
|
*
|
|
* History:
|
|
* 5/92, Implemented. TerryRu.
|
|
*
|
|
*
|
|
**/
|
|
|
|
static TCHAR *MyGetGlossStr( TCHAR * ptszStr, int nCount, FILE * fIn)
|
|
{
|
|
int i = 0;
|
|
|
|
#ifdef RLRES32
|
|
// It this a Unicode glossary file?
|
|
TCHAR tCh = TEXT('\0');
|
|
|
|
if ( fUnicodeGlossary )
|
|
{
|
|
do // Yes
|
|
{
|
|
tCh = ptszStr[ i++] = (TCHAR)GetWord( fIn, NULL);
|
|
|
|
} while ( i < nCount && tCh != TEXT('\n') );
|
|
|
|
if ( tCh == TEXT('\0') || feof( fIn) )
|
|
{
|
|
return( NULL);
|
|
}
|
|
ptszStr[i] = TEXT('\0');
|
|
|
|
StripNewLineW( ptszStr);
|
|
}
|
|
else // No, it's an ANSI glossary file
|
|
{
|
|
if ( fgets( szDHW, DHWSIZE, fIn) != NULL )
|
|
{
|
|
StripNewLineA( szDHW);
|
|
_MBSTOWCS( ptszStr, szDHW, nCount, (UINT)-1);
|
|
}
|
|
else
|
|
{
|
|
return( NULL);
|
|
}
|
|
}
|
|
return( ptszStr);
|
|
|
|
#else //RLRES32
|
|
|
|
if ( fgets( ptszStr, nCount, fIn) )
|
|
{
|
|
StripNewLineA( ptszStr);
|
|
}
|
|
else
|
|
{
|
|
return( NULL);
|
|
}
|
|
|
|
#endif //RLRES32
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* Function: MyPutGlossStr
|
|
* Replaces C runtime fputs function.
|
|
|
|
* History:
|
|
* 6/92, Implemented. TerryRu.
|
|
*
|
|
*
|
|
**/
|
|
static int MyPutGlossStr( TCHAR * ptszStr, FILE * fOut)
|
|
{
|
|
|
|
#ifdef RLRES32
|
|
|
|
int i = 0;
|
|
|
|
// It this a Unicode glossary file?
|
|
if ( fUnicodeGlossary )
|
|
{
|
|
do // Yes
|
|
{
|
|
PutWord( fOut, ptszStr[i], NULL);
|
|
|
|
} while ( ptszStr[ i++] );
|
|
|
|
PutWord( fOut, TEXT('\r'), NULL);
|
|
PutWord( fOut, TEXT('\n'), NULL);
|
|
i += 2;
|
|
}
|
|
else // No, it's an ANSI glossary file
|
|
{
|
|
_WCSTOMBS( szDHW, ptszStr, DHWSIZE, lstrlen( ptszStr) + 1);
|
|
i = fputs( szDHW, fOut);
|
|
fputs( "\n", fOut);
|
|
}
|
|
|
|
#else //RLRES32
|
|
|
|
i = fputs( ptszStr, fOut);
|
|
fputs( "\n", fOut);
|
|
|
|
#endif //RLRES32
|
|
|
|
return(i);
|
|
}
|