467 lines
15 KiB
C
467 lines
15 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1991 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
mcout.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains the output functions of the Win32 Message Compiler (MC)
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Steve Wood (stevewo) 22-Aug-1991
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "mc.h"
|
||
|
|
||
|
PMESSAGE_BLOCK MessageBlocks = NULL;
|
||
|
int NumberOfBlocks = 0;
|
||
|
|
||
|
BOOL
|
||
|
McBlockMessages( void )
|
||
|
{
|
||
|
PMESSAGE_BLOCK p, *pp;
|
||
|
PMESSAGE_INFO MessageInfo;
|
||
|
|
||
|
pp = &MessageBlocks;
|
||
|
p = NULL;
|
||
|
|
||
|
MessageInfo = Messages;
|
||
|
while (MessageInfo) {
|
||
|
if (p) {
|
||
|
if (p->HighId+1 == MessageInfo->Id) {
|
||
|
p->HighId += 1;
|
||
|
}
|
||
|
else {
|
||
|
pp = &p->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!*pp) {
|
||
|
NumberOfBlocks += 1;
|
||
|
p = malloc( sizeof( *p ) );
|
||
|
if (!p) {
|
||
|
McInputErrorA( "Out of memory reading messages", TRUE, NULL );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
p->Next = NULL;
|
||
|
p->LowId = MessageInfo->Id;
|
||
|
p->HighId = MessageInfo->Id;
|
||
|
p->LowInfo = MessageInfo;
|
||
|
*pp = p;
|
||
|
}
|
||
|
|
||
|
MessageInfo = MessageInfo->Next;
|
||
|
}
|
||
|
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
McWriteBinaryFilesA( void )
|
||
|
{
|
||
|
PNAME_INFO LanguageName, *pp;
|
||
|
PLANGUAGE_INFO LanguageInfo;
|
||
|
PMESSAGE_INFO MessageInfo;
|
||
|
PMESSAGE_BLOCK BlockInfo;
|
||
|
char *FileName;
|
||
|
ULONG cb, cbNeeded;
|
||
|
ULONG MessageOffset;
|
||
|
MESSAGE_RESOURCE_ENTRY MessageEntry;
|
||
|
MESSAGE_RESOURCE_BLOCK MessageBlock;
|
||
|
MESSAGE_RESOURCE_DATA MessageData;
|
||
|
ULONG Zeroes = 0;
|
||
|
ULONG NumberOfMessages;
|
||
|
LPBYTE lpBuf;
|
||
|
ULONG Size = 256;
|
||
|
|
||
|
|
||
|
FileName = BinaryMessageFileName;
|
||
|
FileName += strlen( FileName );
|
||
|
|
||
|
lpBuf = malloc( Size );
|
||
|
if (!lpBuf) {
|
||
|
McInputErrorA( "Out of memory writing to output file - %s", TRUE, BinaryMessageFileName );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
pp = &LanguageNames;
|
||
|
while (LanguageName = *pp) {
|
||
|
pp = &LanguageName->Next;
|
||
|
if (!LanguageName->Used) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1, FileName,
|
||
|
sizeof( BinaryMessageFileName ) - strlen( FileName ), NULL, NULL );
|
||
|
strcat( FileName, ".bin" );
|
||
|
if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
|
||
|
McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
|
||
|
}
|
||
|
|
||
|
fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
|
||
|
PRIMARYLANGID( LanguageName->Id ),
|
||
|
SUBLANGID( LanguageName->Id )
|
||
|
);
|
||
|
|
||
|
if (fUniqueBinName) {
|
||
|
fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
|
||
|
} else {
|
||
|
fprintf( RcInclFile, "1 11 %s\r\n", FileName );
|
||
|
}
|
||
|
|
||
|
NumberOfMessages = 0L;
|
||
|
|
||
|
MessageData.NumberOfBlocks = NumberOfBlocks;
|
||
|
MessageOffset = fwrite( &MessageData,
|
||
|
1,
|
||
|
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
|
||
|
Blocks[ 0 ]
|
||
|
),
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
|
||
|
|
||
|
BlockInfo = MessageBlocks;
|
||
|
while (BlockInfo) {
|
||
|
MessageBlock.LowId = BlockInfo->LowId;
|
||
|
MessageBlock.HighId = BlockInfo->HighId;
|
||
|
MessageBlock.OffsetToEntries = MessageOffset;
|
||
|
fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
|
||
|
|
||
|
BlockInfo->InfoLength = 0;
|
||
|
MessageInfo = BlockInfo->LowInfo;
|
||
|
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
|
||
|
LanguageInfo = MessageInfo->MessageText;
|
||
|
while (LanguageInfo) {
|
||
|
if (LanguageInfo->Id == LanguageName->Id) {
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
LanguageInfo = LanguageInfo->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LanguageInfo != NULL) {
|
||
|
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
|
||
|
WideCharToMultiByte( LanguageName->CodePage,
|
||
|
0,
|
||
|
LanguageInfo->Text,
|
||
|
LanguageInfo->Length,
|
||
|
NULL, 0, NULL, NULL ) + 1;
|
||
|
|
||
|
cb = (cb + 3) & ~3;
|
||
|
BlockInfo->InfoLength += cb;
|
||
|
}
|
||
|
else {
|
||
|
fprintf( stderr,
|
||
|
"MC: No %ws language text for %ws\n",
|
||
|
LanguageName->Name,
|
||
|
MessageInfo->SymbolicName
|
||
|
);
|
||
|
fclose( BinaryMessageFile );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
MessageInfo = MessageInfo->Next;
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
|
||
|
BlockInfo->LowId,
|
||
|
BlockInfo->HighId,
|
||
|
BlockInfo->InfoLength
|
||
|
);
|
||
|
}
|
||
|
|
||
|
MessageOffset += BlockInfo->InfoLength;
|
||
|
BlockInfo = BlockInfo->Next;
|
||
|
}
|
||
|
|
||
|
BlockInfo = MessageBlocks;
|
||
|
while (BlockInfo) {
|
||
|
MessageInfo = BlockInfo->LowInfo;
|
||
|
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
|
||
|
LanguageInfo = MessageInfo->MessageText;
|
||
|
while (LanguageInfo) {
|
||
|
if (LanguageInfo->Id == LanguageName->Id) {
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
LanguageInfo = LanguageInfo->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LanguageInfo != NULL) {
|
||
|
cbNeeded = WideCharToMultiByte( LanguageName->CodePage,
|
||
|
0,
|
||
|
LanguageInfo->Text,
|
||
|
LanguageInfo->Length,
|
||
|
NULL, 0, NULL, NULL );
|
||
|
|
||
|
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
|
||
|
cbNeeded + 1;
|
||
|
|
||
|
cb = (cb + 3) & ~3;
|
||
|
|
||
|
MessageEntry.Length = (USHORT)cb;
|
||
|
MessageEntry.Flags = 0;
|
||
|
|
||
|
cb = fwrite( &MessageEntry,
|
||
|
1,
|
||
|
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
|
||
|
Text[ 0 ]
|
||
|
),
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
|
||
|
if (Size < cbNeeded ) {
|
||
|
lpBuf = realloc( lpBuf, cbNeeded );
|
||
|
if (!lpBuf) {
|
||
|
McInputErrorA( "Out of memory writing to output file - %s",
|
||
|
TRUE, BinaryMessageFileName );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
Size = cbNeeded;
|
||
|
}
|
||
|
WideCharToMultiByte( LanguageName->CodePage,
|
||
|
0,
|
||
|
LanguageInfo->Text,
|
||
|
LanguageInfo->Length,
|
||
|
lpBuf, cbNeeded, NULL, NULL );
|
||
|
|
||
|
cb += fwrite( lpBuf,
|
||
|
1,
|
||
|
(size_t)cbNeeded,
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
|
||
|
NumberOfMessages++;
|
||
|
|
||
|
cb = MessageEntry.Length - cb;
|
||
|
if (cb) {
|
||
|
fwrite( &Zeroes,
|
||
|
1,
|
||
|
(size_t)cb,
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MessageInfo = MessageInfo->Next;
|
||
|
}
|
||
|
|
||
|
BlockInfo = BlockInfo->Next;
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, " Total of %lu messages, %lu bytes\n",
|
||
|
NumberOfMessages,
|
||
|
ftell( BinaryMessageFile )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
fclose( BinaryMessageFile );
|
||
|
McClearArchiveBit( BinaryMessageFileName );
|
||
|
}
|
||
|
|
||
|
free( lpBuf );
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
McWriteBinaryFilesW( void )
|
||
|
{
|
||
|
PNAME_INFO LanguageName, *pp;
|
||
|
PLANGUAGE_INFO LanguageInfo;
|
||
|
PMESSAGE_INFO MessageInfo;
|
||
|
PMESSAGE_BLOCK BlockInfo;
|
||
|
char *FileName;
|
||
|
ULONG cb;
|
||
|
ULONG MessageOffset;
|
||
|
MESSAGE_RESOURCE_ENTRY MessageEntry;
|
||
|
MESSAGE_RESOURCE_BLOCK MessageBlock;
|
||
|
MESSAGE_RESOURCE_DATA MessageData;
|
||
|
ULONG Zeroes = 0;
|
||
|
ULONG NumberOfMessages;
|
||
|
|
||
|
FileName = BinaryMessageFileName;
|
||
|
FileName += strlen( FileName );
|
||
|
|
||
|
pp = &LanguageNames;
|
||
|
while (LanguageName = *pp) {
|
||
|
pp = &LanguageName->Next;
|
||
|
if (!LanguageName->Used) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1,
|
||
|
FileName, sizeof( BinaryMessageFileName ), NULL, NULL);
|
||
|
strcat( FileName, ".bin" );
|
||
|
if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
|
||
|
McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
|
||
|
}
|
||
|
|
||
|
fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
|
||
|
PRIMARYLANGID( LanguageName->Id ),
|
||
|
SUBLANGID( LanguageName->Id )
|
||
|
);
|
||
|
|
||
|
if (fUniqueBinName) {
|
||
|
fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
|
||
|
} else {
|
||
|
fprintf( RcInclFile, "1 11 %s\r\n", FileName );
|
||
|
}
|
||
|
|
||
|
NumberOfMessages = 0L;
|
||
|
|
||
|
MessageData.NumberOfBlocks = NumberOfBlocks;
|
||
|
MessageOffset = fwrite( &MessageData,
|
||
|
1,
|
||
|
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
|
||
|
Blocks[ 0 ]
|
||
|
),
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
|
||
|
|
||
|
BlockInfo = MessageBlocks;
|
||
|
while (BlockInfo) {
|
||
|
MessageBlock.LowId = BlockInfo->LowId;
|
||
|
MessageBlock.HighId = BlockInfo->HighId;
|
||
|
MessageBlock.OffsetToEntries = MessageOffset;
|
||
|
fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
|
||
|
|
||
|
BlockInfo->InfoLength = 0;
|
||
|
MessageInfo = BlockInfo->LowInfo;
|
||
|
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
|
||
|
LanguageInfo = MessageInfo->MessageText;
|
||
|
while (LanguageInfo) {
|
||
|
if (LanguageInfo->Id == LanguageName->Id) {
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
LanguageInfo = LanguageInfo->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LanguageInfo != NULL) {
|
||
|
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
|
||
|
( LanguageInfo->Length + 1 );
|
||
|
|
||
|
cb = (cb + 3) & ~3;
|
||
|
BlockInfo->InfoLength += cb;
|
||
|
}
|
||
|
else {
|
||
|
fprintf( stderr,
|
||
|
"MC: No %ws language text for %ws\n",
|
||
|
LanguageName->Name,
|
||
|
MessageInfo->SymbolicName
|
||
|
);
|
||
|
fclose( BinaryMessageFile );
|
||
|
_unlink( BinaryMessageFileName );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
MessageInfo = MessageInfo->Next;
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
|
||
|
BlockInfo->LowId,
|
||
|
BlockInfo->HighId,
|
||
|
BlockInfo->InfoLength
|
||
|
);
|
||
|
}
|
||
|
|
||
|
MessageOffset += BlockInfo->InfoLength;
|
||
|
BlockInfo = BlockInfo->Next;
|
||
|
}
|
||
|
|
||
|
BlockInfo = MessageBlocks;
|
||
|
while (BlockInfo) {
|
||
|
MessageInfo = BlockInfo->LowInfo;
|
||
|
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
|
||
|
LanguageInfo = MessageInfo->MessageText;
|
||
|
while (LanguageInfo) {
|
||
|
if (LanguageInfo->Id == LanguageName->Id) {
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
LanguageInfo = LanguageInfo->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LanguageInfo != NULL) {
|
||
|
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
|
||
|
( LanguageInfo->Length + 1 ) ;
|
||
|
|
||
|
cb = (cb + 3) & ~3;
|
||
|
|
||
|
MessageEntry.Length = (USHORT)cb;
|
||
|
MessageEntry.Flags = MESSAGE_RESOURCE_UNICODE;
|
||
|
|
||
|
cb = fwrite( &MessageEntry,
|
||
|
1,
|
||
|
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
|
||
|
Text[ 0 ]
|
||
|
),
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
cb += fwrite( LanguageInfo->Text,
|
||
|
1,
|
||
|
(size_t)( LanguageInfo->Length ),
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
|
||
|
NumberOfMessages++;
|
||
|
|
||
|
cb = MessageEntry.Length - cb;
|
||
|
if (cb) {
|
||
|
fwrite( &Zeroes,
|
||
|
1,
|
||
|
(size_t)cb,
|
||
|
BinaryMessageFile
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MessageInfo = MessageInfo->Next;
|
||
|
}
|
||
|
|
||
|
BlockInfo = BlockInfo->Next;
|
||
|
}
|
||
|
|
||
|
if (VerboseOutput) {
|
||
|
fprintf( stderr, " Total of %lu messages, %lu bytes\n",
|
||
|
NumberOfMessages,
|
||
|
ftell( BinaryMessageFile )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
fclose( BinaryMessageFile );
|
||
|
McClearArchiveBit( BinaryMessageFileName );
|
||
|
}
|
||
|
|
||
|
return( TRUE );
|
||
|
}
|