home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / mc / mcout.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  7KB  |  256 lines

  1. /*++
  2.  
  3. Copyright (c) 1991-1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     mcout.c
  8.  
  9. Abstract:
  10.  
  11.     This file contains the output functions of the Win32 Message Compiler (MC)
  12.  
  13. --*/
  14.  
  15. #include "mc.h"
  16.  
  17. PMESSAGE_BLOCK MessageBlocks = NULL;
  18. int NumberOfBlocks = 0;
  19.  
  20. /*++
  21.  
  22. Routine Description:
  23.  
  24. Arguments:
  25.  
  26.  
  27. Return Value:
  28.  
  29.  
  30. --*/
  31.  
  32.  
  33. BOOLEAN
  34. McBlockMessages( void )
  35. {
  36.     PMESSAGE_BLOCK p, *pp;
  37.     PMESSAGE_INFO MessageInfo;
  38.  
  39.     pp = &MessageBlocks;
  40.     p = NULL;
  41.  
  42.     MessageInfo = Messages;
  43.     while (MessageInfo) {
  44.         if (p) {
  45.             if (p->HighId+1 == MessageInfo->Id) {
  46.                 p->HighId += 1;
  47.                 }
  48.             else {
  49.                 pp = &p->Next;
  50.                 }
  51.             }
  52.  
  53.         if (!*pp) {
  54.             NumberOfBlocks += 1;
  55.             p = malloc( sizeof( *p ) );
  56.             p->Next = NULL;
  57.             p->LowId = MessageInfo->Id;
  58.             p->HighId = MessageInfo->Id;
  59.             p->LowInfo = MessageInfo;
  60.             *pp = p;
  61.             }
  62.  
  63.         MessageInfo = MessageInfo->Next;
  64.         }
  65.  
  66.     return( TRUE );
  67. }
  68.  
  69. /*++
  70.  
  71. Routine Description:
  72.  
  73. Arguments:
  74.  
  75.  
  76. Return Value:
  77.  
  78.  
  79. --*/
  80.  
  81.  
  82. BOOLEAN
  83. McWriteBinaryFiles( void )
  84. {
  85.     PNAME_INFO LanguageName, *pp;
  86.     PLANGUAGE_INFO LanguageInfo;
  87.     PMESSAGE_INFO MessageInfo;
  88.     PMESSAGE_BLOCK BlockInfo;
  89.     char *FileName;
  90.     ULONG cb;
  91.     ULONG MessageOffset;
  92.     MESSAGE_RESOURCE_ENTRY MessageEntry;
  93.     MESSAGE_RESOURCE_BLOCK MessageBlock;
  94.     MESSAGE_RESOURCE_DATA  MessageData;
  95.     ULONG Zeroes = 0;
  96.     ULONG NumberOfMessages;
  97.  
  98.     FileName = BinaryMessageFileName;
  99.     FileName += strlen( FileName );
  100.  
  101.     pp = &LanguageNames;
  102.     while (LanguageName = *pp) {
  103.         pp = &LanguageName->Next;
  104.         if (!LanguageName->Used) {
  105.             continue;
  106.             }
  107.  
  108.         strcpy( FileName, LanguageName->Value );
  109.         strcat( FileName, ".bin" );
  110.         if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
  111.             McInputError( "unable to open output file - %s", TRUE, BinaryMessageFileName );
  112.             return( FALSE );
  113.             }
  114.  
  115.         if (VerboseOutput) {
  116.             fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
  117.             }
  118.  
  119.         fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
  120.                              PRIMARYLANGID( LanguageName->Id ),
  121.                              SUBLANGID( LanguageName->Id )
  122.                );
  123.  
  124.         fprintf( RcInclFile, "1 11 %s\r\n", FileName );
  125.  
  126.         NumberOfMessages = 0L;
  127.  
  128.         MessageData.NumberOfBlocks = NumberOfBlocks;
  129.         MessageOffset = fwrite( &MessageData,
  130.                                 1,
  131.                                 (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
  132.                                                       Blocks[ 0 ]
  133.                                                     ),
  134.                                 BinaryMessageFile
  135.                               );
  136.         MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
  137.  
  138.         BlockInfo = MessageBlocks;
  139.         while (BlockInfo) {
  140.             MessageBlock.LowId = BlockInfo->LowId;
  141.             MessageBlock.HighId = BlockInfo->HighId;
  142.             MessageBlock.OffsetToEntries = MessageOffset;
  143.             fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
  144.  
  145.             BlockInfo->InfoLength = 0;
  146.             MessageInfo = BlockInfo->LowInfo;
  147.             while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  148.                 LanguageInfo = MessageInfo->MessageText;
  149.                 while (LanguageInfo) {
  150.                     if (LanguageInfo->Id == LanguageName->Id) {
  151.                         break;
  152.                         }
  153.                     else {
  154.                         LanguageInfo = LanguageInfo->Next;
  155.                         }
  156.                     }
  157.  
  158.                 if (LanguageInfo != NULL) {
  159.                     cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  160.                          LanguageInfo->Length + 1;
  161.  
  162.                     cb = (cb + 3) & ~3;
  163.                     BlockInfo->InfoLength += cb;
  164.                     }
  165.                 else {
  166.                     fprintf( stderr,
  167.                              "MC: No %s language text for %s\n",
  168.                              LanguageName->Name,
  169.                              MessageInfo->SymbolicName
  170.                            );
  171.                     fclose( BinaryMessageFile );
  172.                     return( FALSE );
  173.                     }
  174.  
  175.                 MessageInfo = MessageInfo->Next;
  176.                 }
  177.  
  178.             if (VerboseOutput) {
  179.                 fprintf( stderr, "    [%08lx .. %08lx] - %lu bytes\n",
  180.                          BlockInfo->LowId,
  181.                          BlockInfo->HighId,
  182.                          BlockInfo->InfoLength
  183.                        );
  184.                 }
  185.  
  186.             MessageOffset += BlockInfo->InfoLength;
  187.             BlockInfo = BlockInfo->Next;
  188.             }
  189.  
  190.         BlockInfo = MessageBlocks;
  191.         while (BlockInfo) {
  192.             MessageInfo = BlockInfo->LowInfo;
  193.             while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  194.                 LanguageInfo = MessageInfo->MessageText;
  195.                 while (LanguageInfo) {
  196.                     if (LanguageInfo->Id == LanguageName->Id) {
  197.                         break;
  198.                         }
  199.                     else {
  200.                         LanguageInfo = LanguageInfo->Next;
  201.                         }
  202.                     }
  203.  
  204.                 if (LanguageInfo != NULL) {
  205.                     cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  206.                          LanguageInfo->Length + 1;
  207.  
  208.                     cb = (cb + 3) & ~3;
  209.  
  210.                     MessageEntry.Length = (USHORT)cb;
  211.                     MessageEntry.Flags = 0;
  212.  
  213.                     cb = fwrite( &MessageEntry,
  214.                                  1,
  215.                                  (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
  216.                                                        Text[ 0 ]
  217.                                                      ),
  218.                                  BinaryMessageFile
  219.                                );
  220.                     cb += fwrite( LanguageInfo->Text,
  221.                                   1,
  222.                                   (size_t)LanguageInfo->Length,
  223.                                   BinaryMessageFile
  224.                                 );
  225.  
  226.                     NumberOfMessages++;
  227.  
  228.                     cb = MessageEntry.Length - cb;
  229.                     if (cb) {
  230.                         fwrite( &Zeroes,
  231.                                 1,
  232.                                 (size_t)cb,
  233.                                 BinaryMessageFile
  234.                               );
  235.                         }
  236.                     }
  237.  
  238.                 MessageInfo = MessageInfo->Next;
  239.                 }
  240.  
  241.             BlockInfo = BlockInfo->Next;
  242.             }
  243.  
  244.         if (VerboseOutput) {
  245.             fprintf( stderr, "    Total of %lu messages, %lu bytes\n",
  246.                              NumberOfMessages,
  247.                              ftell( BinaryMessageFile )
  248.                    );
  249.             }
  250.  
  251.         fclose( BinaryMessageFile );
  252.         }
  253.  
  254.     return( TRUE );
  255. }
  256.