home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1991-1997 Microsoft Corporation
-
- Module Name:
-
- mcparse.c
-
- Abstract:
-
- This file contains the parse logic for the Win32 Message Compiler (MC)
-
-
- --*/
-
- #include "mc.h"
-
- BOOLEAN
- McParseFile( void )
- {
- unsigned int t;
- BOOLEAN FirstMessageDefinition = TRUE;
- PNAME_INFO p;
-
- if (!McOpenInputFile()) {
- fprintf( stderr, "MC: Unable to open %s for input\n", MessageFileName );
- return( FALSE );
- }
-
- fprintf( stderr, "MC: Compiling %s\n", MessageFileName );
- while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) {
- switch (t) {
- case MCTOK_MSGIDTYPE_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_NAME) {
- MessageIdTypeName = McMakeString( TokenCharValue );
- }
- else {
- McInputError( "Symbol name must follow %s=", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_SEVNAMES_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) {
- if (!McParseNameList( &SeverityNames, FALSE, 0x3L )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_FACILITYNAMES_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) {
- if (!McParseNameList( &FacilityNames, FALSE, 0xFFFL )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_LANGNAMES_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) {
- if (!McParseNameList( &LanguageNames, TRUE, 0xFFFFL )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_MESSAGEID_KEYWORD:
- McUnGetToken();
- if (FirstMessageDefinition) {
- FirstMessageDefinition = FALSE;
- McFlushComments();
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Values are 32 bit values layed out as follows:\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\r\n" );
- fprintf( HeaderFile, "// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\r\n" );
- fprintf( HeaderFile, "// +---+-+-+-----------------------+-------------------------------+\r\n" );
- fprintf( HeaderFile, "// |Sev|C|R| Facility | Code |\r\n" );
- fprintf( HeaderFile, "// +---+-+-+-----------------------+-------------------------------+\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// where\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Sev - is the severity code\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// 00 - Success\r\n" );
- fprintf( HeaderFile, "// 01 - Informational\r\n" );
- fprintf( HeaderFile, "// 10 - Warning\r\n" );
- fprintf( HeaderFile, "// 11 - Error\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// C - is the Customer code flag\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// R - is a reserved bit\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Facility - is the facility code\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Code - is the facility's status code\r\n" );
- fprintf( HeaderFile, "//\r\n" );
-
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Define the facility codes\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- p = FacilityNames;
- while( p ) {
- if (p->Value) {
- fprintf( HeaderFile, GenerateDecimalValues ?
- "#define %-32s %ld\r\n" :
- "#define %-32s 0x%lX\r\n",
- p->Value, p->Id
- );
- }
-
- p = p->Next;
- }
- fprintf( HeaderFile, "\r\n" );
- fprintf( HeaderFile, "\r\n" );
-
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// Define the severity codes\r\n" );
- fprintf( HeaderFile, "//\r\n" );
- p = SeverityNames;
- while( p ) {
- if (p->Value) {
- fprintf( HeaderFile, GenerateDecimalValues ?
- "#define %-32s %ld\r\n" :
- "#define %-32s 0x%lX\r\n",
- p->Value, p->Id
- );
- }
-
- p = p->Next;
- }
- fprintf( HeaderFile, "\r\n" );
- fprintf( HeaderFile, "\r\n" );
- }
-
- if (!McParseMessageDefinition()) {
- return( FALSE );
- }
- break;
-
- default:
- McInputError( "Invalid message file token - '%s'", TRUE, TokenCharValue );
- return( FALSE );
- break;
- }
- }
-
- McFlushComments();
- return( TRUE );
- }
-
-
- BOOLEAN
- McParseMessageDefinition( void )
- {
- unsigned int t;
- PMESSAGE_INFO MessageInfo;
- BOOLEAN MessageIdSeen;
- PMESSAGE_INFO MessageInfoTemp;
-
- McFlushComments();
-
- MessageInfo = malloc( sizeof( *MessageInfo ) );
- MessageInfo->Next = NULL;
- MessageInfo->Id = 0;
- MessageInfo->Method = MSG_PLUS_ONE;
- MessageInfo->SymbolicName = NULL;
- MessageInfo->EndOfLineComment = NULL;
- MessageInfo->MessageText = NULL;
- MessageIdSeen = FALSE;
-
- while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) {
- switch (t) {
- case MCTOK_MESSAGEID_KEYWORD:
- if (MessageIdSeen) {
- McInputError( "Invalid message definition - text missing.", TRUE, NULL );
- return( FALSE );
- }
-
- MessageIdSeen = TRUE;
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) {
- MessageInfo->Id = TokenNumericValue;
- MessageInfo->Method = MSG_ABSOLUTE;
- }
- else
- if (t == MCTOK_PLUS) {
- if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) {
- MessageInfo->Id = TokenNumericValue;
- MessageInfo->Method = MSG_PLUS_VALUE;
- }
- else {
- McInputError( "Number must follow %s=+", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McUnGetToken();
- }
-
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_SEVERITY_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if (!McParseName( SeverityNames, &CurrentSeverityName )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_FACILITY_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if (!McParseName( FacilityNames, &CurrentFacilityName )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
- case MCTOK_SYMBOLNAME_KEYWORD:
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_NAME) {
- MessageInfo->SymbolicName = McMakeString( TokenCharValue );
- }
- else {
- McInputError( "Symbol name must follow %s=+", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- break;
-
-
- case MCTOK_END_OF_LINE_COMMENT:
- MessageInfo->EndOfLineComment = McMakeString( TokenCharValue );
- break;
-
- case MCTOK_LANGUAGE_KEYWORD:
- McUnGetToken();
-
-
- if (MessageInfo->Method == MSG_PLUS_ONE) {
- MessageInfo->Id = CurrentFacilityName->LastId + 1;
- }
- else
- if (MessageInfo->Method == MSG_PLUS_VALUE) {
- MessageInfo->Id = CurrentFacilityName->LastId + MessageInfo->Id;
- }
-
- if (MessageInfo->Id > 0xFFFFL) {
- McInputError( "Message Id value (%lx) too large", TRUE, (PVOID)MessageInfo->Id );
- return( FALSE );
- }
-
- MessageInfo->Id |= (CurrentSeverityName->Id << 30) |
- CustomerMsgIdBit |
- (CurrentFacilityName->Id << 16);
-
- fprintf( HeaderFile, "//\r\n" );
- if (MessageInfo->SymbolicName) {
- fprintf( HeaderFile, "// MessageId: %s\r\n",
- MessageInfo->SymbolicName
- );
- }
- else {
- fprintf( HeaderFile, "// MessageId: 0x%08lXL (No symbolic name defined)\r\n",
- MessageInfo->Id
- );
- }
-
- fprintf( HeaderFile, "//\r\n" );
- fprintf( HeaderFile, "// MessageText:\r\n" );
- fprintf( HeaderFile, "//\r\n" );
-
- if (McParseMessageText( MessageInfo )) {
- fprintf( HeaderFile, "//\r\n" );
- if (MessageInfo->SymbolicName) {
-
- if (MessageIdTypeName != NULL) {
- fprintf( HeaderFile, GenerateDecimalValues ?
- "#define %-32s ((%s)%ldL)" :
- "#define %-32s ((%s)0x%08lXL)",
- MessageInfo->SymbolicName,
- MessageIdTypeName,
- MessageInfo->Id
- );
- }
- else {
- fprintf( HeaderFile, GenerateDecimalValues ?
- "#define %-32s %ldL" :
- "#define %-32s 0x%08lXL",
- MessageInfo->SymbolicName,
- MessageInfo->Id
- );
- }
- }
-
- if (MessageInfo->EndOfLineComment) {
- fprintf( HeaderFile, " %s", MessageInfo->EndOfLineComment );
- }
- else {
- fprintf( HeaderFile, "\r\n" );
- }
- fprintf( HeaderFile, "\r\n" );
-
- if (Messages == NULL) {
- Messages = MessageInfo;
- }
- else {
- MessageInfoTemp = Messages;
-
- //
- // Scan the existing messages to see if this message
- // exists in the message file.
- //
- // If it does, generate and error for the user.
- //
-
- while (MessageInfoTemp != NULL) {
-
- if (MessageInfoTemp->Id == MessageInfo->Id) {
- McInputError( "Duplicate message ID - 0x%lx", FALSE, (PVOID)MessageInfo->Id );
- }
-
- MessageInfoTemp = MessageInfoTemp->Next;
- }
-
- CurrentMessage->Next = MessageInfo;
- }
-
- CurrentMessage = MessageInfo;
- CurrentFacilityName->LastId = MessageInfo->Id & 0xFFFF;
- return( TRUE );
- }
- else {
- return( FALSE );
- }
-
- default:
- McInputError( "Invalid message definition token - '%s'", TRUE, TokenCharValue );
- return( FALSE );
- }
- }
-
- return( FALSE );
- }
-
-
- char MessageTextBuffer[ 8192 ];
-
- BOOLEAN
- McParseMessageText(
- PMESSAGE_INFO MessageInfo
- )
- {
- PLANGUAGE_INFO MessageText, *pp;
- char *src, *dst;
- unsigned int t, n;
- BOOLEAN FirstLanguageProcessed;
-
- pp = &MessageInfo->MessageText;
-
- FirstLanguageProcessed = FALSE;
- while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) {
- if (t == MCTOK_LANGUAGE_KEYWORD) {
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if (!McParseName( LanguageNames, &CurrentLanguageName )) {
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name );
- return( FALSE );
- }
- }
- else {
- McUnGetToken();
- break;
- }
-
- MessageText = malloc( sizeof( *MessageText ) );
- MessageText->Next = NULL;
- MessageText->Id = CurrentLanguageName->Id;
- MessageText->Length = 0;
- MessageText->Text = NULL;
-
- dst = MessageTextBuffer;
- while (src = McGetLine()) {
- if (!strcmp( src, ".\r\n" )) {
- if (MessageText->Length == 0) {
- if (MessageInfo->SymbolicName) {
- strcpy( dst, MessageInfo->SymbolicName );
- }
- else {
- sprintf( dst, "No symbolic name defined for0x%08lXL" );
- }
-
- strcat( dst, "\r\n" );
- if (!FirstLanguageProcessed) {
- fprintf( HeaderFile, "// %s", dst );
- }
-
- n = strlen( dst );
- dst += n;
- MessageText->Length += n;
- }
-
- McSkipLine();
- break;
- }
- else
- if (!strnicmp( src, "LanguageId=", 11 ) ||
- !strnicmp( src, "MessageId=", 10 )
- ) {
- McInputError( "Unterminated message definition", TRUE, NULL );
- return( FALSE );
- }
-
- if (!FirstLanguageProcessed) {
- fprintf( HeaderFile, "// %s", src );
- }
-
- n = strlen( src );
- if (MessageText->Length + n > sizeof( MessageTextBuffer )) {
- McInputError( "Message text too long - > %ld", TRUE,
- (PVOID)(ULONG)sizeof( MessageTextBuffer )
- );
- return( FALSE );
- }
-
- strcpy( dst, src );
- dst += n;
- MessageText->Length += n;
- }
- *dst = '\0';
-
- n = ((USHORT)MessageText->Length)+1;
- MessageText->Text = malloc( n );
- memcpy( MessageText->Text, MessageTextBuffer, n );
- *pp = MessageText;
- pp = &MessageText->Next;
- FirstLanguageProcessed = TRUE;
- }
-
- return( TRUE );
- }
-
-
- BOOLEAN
- McParseNameList(
- PNAME_INFO *NameListHead,
- BOOLEAN ValueRequired,
- ULONG MaximumValue
- )
- {
- unsigned int t;
- PNAME_INFO p;
- char *Name;
- ULONG Id;
- PVOID Value;
-
- while ((t = McGetToken( FALSE )) != MCTOK_END_OF_FILE) {
- if (t == MCTOK_RIGHT_PAREN) {
- return( TRUE );
- }
-
- if (t == MCTOK_NAME) {
- Name = McMakeString( TokenCharValue );
- Id = 0;
- Value = NULL;
- if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) {
- if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) {
- Id = TokenNumericValue;
- if ((t = McGetToken( FALSE )) == MCTOK_COLON) {
- if ((t = McGetToken( FALSE )) == MCTOK_NAME) {
- Value = McMakeString( TokenCharValue );
- }
- else {
- McInputError( "File name must follow =%ld:", TRUE, (PVOID)Id );
- return( FALSE );
- }
- }
- else {
- if (ValueRequired) {
- McInputError( "Colon must follow =%ld", TRUE, (PVOID)Id );
- return( FALSE );
- }
-
- McUnGetToken();
- }
- }
- else {
- McInputError( "Number must follow %s=", TRUE, Name );
- return( FALSE );
- }
- }
- else {
- McInputError( "Equal sign name must follow %s", TRUE, Name );
- return( FALSE );
- }
-
- if (Id > MaximumValue) {
- McInputError( "Value is too large (> %lx)", TRUE, (PVOID)MaximumValue );
- return( FALSE );
- }
-
- p = McAddName( NameListHead, Name, Id, Value );
- free( Name );
- }
- }
-
- return( FALSE );
- }
-
- BOOLEAN
- McParseName(
- PNAME_INFO NameListHead,
- PNAME_INFO *Result
- )
- {
- unsigned int t;
- PNAME_INFO p;
-
- if ((t = McGetToken( FALSE )) == MCTOK_NAME) {
- p = McFindName( NameListHead, TokenCharValue );
- if (p != NULL) {
- *Result = p;
- return( TRUE );
- }
- else {
- McInputError( "Invalid name - %s", TRUE, TokenCharValue );
- }
- }
- else {
- McInputError( "Missing name after %s=", TRUE, TokenKeyword->Name );
- }
-
- return( FALSE );
- }
-