|
|
#include <ctype.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#ifdef RLDOS
#include "dosdefs.h"
#else
#include <windows.h>
#include "windefs.h"
#endif
#include "restok.h"
#include "commbase.h"
#include "resread.h"
extern UCHAR szDHW[];
//
// The syssetup.dll, that has been contained Windows NT 4.00, has the largest
// message strings than ever. So, we have to expand buffer size(to 20480).
//
#define MAX_OUT_BUFFER 20480
CHAR gt_szTextBuffer[ MAX_OUT_BUFFER]; TCHAR pt_szOutBuffer[MAX_OUT_BUFFER];
/**
* * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * * **/
/*---------------------------------------------------------
* Function: GetToken * Input: fpInFile File pointer, points to the token to be read. * tToken Pointer to a token. * * * Output: fpInFile File pointer after read operation. * points to the next token in the file. * tToken The token read in from the file. Memory will have been * allocated for the token text, unless no token was read in. * * Return code: * 0 = Read token, every thing OK * 1 = Empty line or line started with # (Comment) * -1 = End of FILE * -2 = Error reading from file. * * History: * 01/93 Re-written to read in long token text strings. MHotchin * *----------------------------------------------------------*/
int GetToken(
FILE *fpInFile, //... File to get token from.
TOKEN *pToken) //... Buffer for token.
{ int chNextChar = 0; int cTextLen = 0; int rc = 0;
// Read token from file.
// we will want to use MyGetStr, when
// tokens are in UNICODE
// Strip off leading whitespace, and check
// for blank lines.
chNextChar = fgetc( fpInFile);
while ( (chNextChar == ' ') || (chNextChar == '\t') ) { chNextChar = fgetc( fpInFile); }
if ( chNextChar == EOF ) { return ( -1); } else if ( chNextChar == '\n' ) { return ( 1); }
// Now we have the first non-white space
// character.
// Check for a comment line, and strip out the
// remainder of the line if it is.
else if ( chNextChar == '#' ) { fscanf( fpInFile, "%*[^\n]"); chNextChar = fgetc( fpInFile);
if ( chNextChar == EOF ) { return ( -1); } else { return ( 1); } }
// Now we are positioned at the first
// non-whitespace character. Check it, and
// read in the numbers...
else if ( chNextChar != '[' ) { // Bad format?
return ( -2); }
if ( fscanf( fpInFile, "[%hu|%hu|%hu|%hu|%hu", &pToken->wType, &pToken->wName, &pToken->wID, &pToken->wFlag, &pToken->wReserved) != 5 ) { QuitA( IDS_ENGERR_12, (LPSTR)IDS_BADTOKID, NULL); }
// Now that we have all the numbers, we can
// look for the name of the token.
if ( (pToken->wName == IDFLAG) || (pToken->wType == ID_RT_ERRTABLE) ) { static char szName[ TOKENSTRINGBUFFER]; int nRC = 0;
nRC = fscanf( fpInFile, "|\"%[^\"]", szName); if ( nRC == EOF ) { QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL); }
#ifndef UNITOK
#ifdef RLRES32
if (nRC) _MBSTOWCS( (TCHAR *)pToken->szName, szName, TOKENSTRINGBUFFER, lstrlenA( szName) + 1); else _MBSTOWCS( (TCHAR *)pToken->szName, "", TOKENSTRINGBUFFER, lstrlenA( szName) + 1); #else
if (nRC) strcpy( pToken->szName, szName); else *pToken->szName = '\0'; #endif
#else
if (nRC) strcpy( pToken->szName, szName); else *pToken->szName = '\0'; #endif
} else { if ( fscanf( fpInFile, "|\"%*[^\"]") != 0 ) { QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOSKIPNAME, NULL); } pToken->szName[0] = '\0'; }
// Now the name has been read, and we are
// positioned at the last '"' in the text
// stream. Allocate memory for the token
// text, and read it in.
fgets( gt_szTextBuffer, sizeof(gt_szTextBuffer), fpInFile);
// Now that the token text is read in,
// convert it to whatever character type
// we are expecting. First strip the newline!
StripNewLineA( gt_szTextBuffer); cTextLen = lstrlenA( gt_szTextBuffer);
if ( cTextLen < 4 ) { // Must be more than "\"]]=" in szTextBuffer
return ( -2); } pToken->szText = (TCHAR *)FALLOC( MEMSIZE( cTextLen - 3));
#ifndef UNITOK
#ifdef RLRES32
_MBSTOWCS( pToken->szText, gt_szTextBuffer+4, cTextLen - 3, cTextLen - 3); #else
strcpy( pToken->szText, gt_szTextBuffer+4); #endif // RLRES32
#else // UNITOK
strcpy( pToken->szText, gt_szTextBuffer+4); #endif // UNITOK
return ( 0); }
/**
* * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * 01/93 Added new character count field. MHotchin * **/
int PutToken(
FILE *fpOutFile, //... Token file to write to
TOKEN *tToken) //... Token to be writen to the token file
{ WORD rc = 0; PCHAR pszBuf = NULL;
ParseTokToBuf( pt_szOutBuffer, tToken); // RLFREE( tToken->szText);
#ifdef RLRES32
if ( ! _WCSTOMBS( szDHW, pt_szOutBuffer, DHWSIZE, lstrlen( pt_szOutBuffer) + 1) ) { QuitT( IDS_ENGERR_26, pt_szOutBuffer, NULL); } pszBuf = szDHW;
#else
pszBuf = pt_szOutBuffer;
#endif
return fprintf( fpOutFile, "%s\n", pszBuf); }
/**
* Function: FindToken * Finds a token whose status bits match only where the mask is set. * * Arguments: * fpSearchFile -- search file * psTok -- pointer to the token * uMask -- status bit mask * * Returns: * string and status of found token * * Errors Codes: * 0 - token not found * 1 - token found * * History: * 01/93 Added support for var length token text strings. Previous token text * is de-allocated! MHotchin * **/
int FindToken( FILE *fpSearchFile, TOKEN *psTok, WORD wMask) { BOOL fFound = FALSE; BOOL fStartOver = TRUE; int error; int nTokensRead = 0; long lStartFilePos, lFilePos; TOKEN cTok;
//... Remember where we are starting
lFilePos = lStartFilePos = ftell(fpSearchFile);
do { long lType11Pos = 0;
do { lType11Pos = ftell( fpSearchFile);
error = GetToken( fpSearchFile, &cTok);
if ( error == 0 ) { //... Is this the token we are looking for?
fFound = ((cTok.wType == psTok->wType) && (cTok.wName == psTok->wName) && (cTok.wID == psTok->wID) && (cTok.wFlag == psTok->wFlag) && ((WORD)(cTok.wReserved & wMask) == psTok->wReserved) && (_tcscmp( (TCHAR *)cTok.szName, (TCHAR *)psTok->szName) == 0)); }
if ( ! fFound ) { //... If we were looking for another segment to
//... an NT Msg Table entry, move back to the
//... token we just read and quit (speedup).
if ( psTok->wType == ID_RT_ERRTABLE && psTok->wFlag > 0 && error == 0 ) { if ( cTok.wType != psTok->wType || cTok.wName != psTok->wName || cTok.wID != psTok->wID || cTok.wFlag > psTok->wFlag ) { fseek( fpSearchFile, lType11Pos, SEEK_SET); RLFREE( cTok.szText); return ( FALSE); } } else if ( error >= 0 ) { lFilePos = ftell(fpSearchFile);
if (error == 0) { RLFREE(cTok.szText); } } else if (error == -2) { return ( FALSE); } }
} while ( ! fFound && (error >= 0) && (fStartOver || (lFilePos < lStartFilePos)) );
if ( ! fFound && (error == -1) && fStartOver ) { rewind(fpSearchFile); lFilePos = 0L; fStartOver = FALSE; }
} while ( ! fFound && (lFilePos < lStartFilePos) );
//... Did we find the desired token?
if ( fFound ) { //... Yes, we found it
psTok->wReserved = cTok.wReserved;
RLFREE( psTok->szText); psTok->szText = cTok.szText; } return ( fFound); }
/**
* * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * 01/93 Added support for new token text count. MHotchin * **/
void ParseBufToTok( TCHAR *szToken, TOKEN *pTok ) { TCHAR *pos; WORD bChars;
if ( _stscanf( szToken, TEXT("[[%hu|%hu|%hu|%hu|%hu"), &pTok->wType, &pTok->wName, &pTok->wID, &pTok->wFlag, &pTok->wReserved) != 5 ) { QuitT( IDS_BADTOK, szToken, NULL); }
if ( pTok->wName == IDFLAG || pTok->wType == ID_RT_ERRTABLE ) { //... Find Names's first char and get it's len
if ( pos = _tcschr( (TCHAR *)szToken, TEXT('"')) ) { TCHAR *pStart;
pStart = ++pos; bChars = 0;
while ( *pos && *pos != TEXT('"') && bChars < TOKENSTRINGBUFFER - 1 ) { bChars++; pos++; } // while
CopyMemory( pTok->szName, pStart, min( TOKENSTRINGBUFFER, bChars) * sizeof( TCHAR)); pTok->szName[ bChars ] = TEXT('\0'); } else { //... No token ID found
QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL); } } else { // Don't forget the zero termination
pTok->szName[0] = TEXT('\0'); }
// now do the token text
pos = _tcschr ((TCHAR *)szToken, TEXT(']'));
if ( pos ) {
// This can be written better now that we know the text length.
bChars = (WORD)lstrlen( pos);
if ( bChars > 3 ) { pos += 3; bChars -= 3; pTok->szText = (TCHAR *)FALLOC( MEMSIZE( bChars + 1)); CopyMemory( pTok->szText, pos, MEMSIZE( bChars + 1)); // Don't forget the zero termination
pTok->szText[ bChars] = TEXT('\0'); } else if ( bChars == 3 ) { //... Empty token text
pTok->szText = (TCHAR *) FALLOC( 0); } else { //... No token ID found
QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKID, NULL); } } else { //... No token ID found
QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOTOKID, NULL); } }
/**
* * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * **/
void ParseTokToBuf( TCHAR *szToken, TOKEN *pTok ) { *szToken = TEXT('\0');
if ( pTok != NULL) { wsprintf( szToken, TEXT("[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]="), pTok->wType, pTok->wName, pTok->wID, pTok->wFlag, pTok->wReserved, pTok->szName); if (pTok->szText) lstrcat(szToken, pTok->szText); } }
/**
* * * Function: TokenToTextSize * This calculates the number of characters needed to hold * the text representation of a token. * * Arguments: * pTok The token to measure. * * Returns: * int The number of characters needed to hold the token, not * including a null terminator. [[%hu|%hu|%hu|%hu|%hu|\"%s\"]]=%s * * Errors Codes: * None. * * History: * 01/18/93 MHotchin Created. * **/ int TokenToTextSize( TOKEN *pTok) { int cTextLen;
cTextLen = (14 + // Separators and terminator ( + 1 extra)
30); // Space for 5 numeric fields (65,535 = 6 chars)
if ( pTok->szText != NULL ) {
// Add space for the Token text
cTextLen += MEMSIZE( lstrlen( pTok->szText) );
}
cTextLen += lstrlen( pTok->szName);
return ( cTextLen); }
|