|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1991 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: mcparse.c ! 8: ! 9: Abstract: ! 10: ! 11: This file contains the parse logic for the Win32 Message Compiler (MC) ! 12: ! 13: ! 14: --*/ ! 15: ! 16: #include "mc.h" ! 17: ! 18: BOOLEAN ! 19: McParseFile( void ) ! 20: { ! 21: unsigned int t; ! 22: BOOLEAN FirstMessageDefinition = TRUE; ! 23: PNAME_INFO p; ! 24: ! 25: if (!McOpenInputFile()) { ! 26: fprintf( stderr, "MC: Unable to open %s for input\n", MessageFileName ); ! 27: return( FALSE ); ! 28: } ! 29: ! 30: fprintf( stderr, "MC: Compiling %s\n", MessageFileName ); ! 31: while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) { ! 32: switch (t) { ! 33: case MCTOK_MSGIDTYPE_KEYWORD: ! 34: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 35: if ((t = McGetToken( FALSE )) == MCTOK_NAME) { ! 36: MessageIdTypeName = McMakeString( TokenCharValue ); ! 37: } ! 38: else { ! 39: McInputError( "Symbol name must follow %s=", TRUE, TokenKeyword->Name ); ! 40: return( FALSE ); ! 41: } ! 42: } ! 43: else { ! 44: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 45: return( FALSE ); ! 46: } ! 47: break; ! 48: ! 49: case MCTOK_SEVNAMES_KEYWORD: ! 50: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 51: if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) { ! 52: if (!McParseNameList( &SeverityNames, FALSE, 0x3L )) { ! 53: return( FALSE ); ! 54: } ! 55: } ! 56: else { ! 57: McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name ); ! 58: return( FALSE ); ! 59: } ! 60: } ! 61: else { ! 62: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 63: return( FALSE ); ! 64: } ! 65: break; ! 66: ! 67: case MCTOK_FACILITYNAMES_KEYWORD: ! 68: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 69: if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) { ! 70: if (!McParseNameList( &FacilityNames, FALSE, 0xFFFL )) { ! 71: return( FALSE ); ! 72: } ! 73: } ! 74: else { ! 75: McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name ); ! 76: return( FALSE ); ! 77: } ! 78: } ! 79: else { ! 80: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 81: return( FALSE ); ! 82: } ! 83: break; ! 84: ! 85: case MCTOK_LANGNAMES_KEYWORD: ! 86: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 87: if ((t = McGetToken( FALSE )) == MCTOK_LEFT_PAREN) { ! 88: if (!McParseNameList( &LanguageNames, TRUE, 0xFFFFL )) { ! 89: return( FALSE ); ! 90: } ! 91: } ! 92: else { ! 93: McInputError( "Left parenthesis name must follow %s=", TRUE, TokenKeyword->Name ); ! 94: return( FALSE ); ! 95: } ! 96: } ! 97: else { ! 98: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 99: return( FALSE ); ! 100: } ! 101: break; ! 102: ! 103: case MCTOK_MESSAGEID_KEYWORD: ! 104: McUnGetToken(); ! 105: if (FirstMessageDefinition) { ! 106: FirstMessageDefinition = FALSE; ! 107: McFlushComments(); ! 108: fprintf( HeaderFile, "//\r\n" ); ! 109: fprintf( HeaderFile, "// Values are 32 bit values layed out as follows:\r\n" ); ! 110: fprintf( HeaderFile, "//\r\n" ); ! 111: 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" ); ! 112: 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" ); ! 113: fprintf( HeaderFile, "// +---+-+-+-----------------------+-------------------------------+\r\n" ); ! 114: fprintf( HeaderFile, "// |Sev|C|R| Facility | Code |\r\n" ); ! 115: fprintf( HeaderFile, "// +---+-+-+-----------------------+-------------------------------+\r\n" ); ! 116: fprintf( HeaderFile, "//\r\n" ); ! 117: fprintf( HeaderFile, "// where\r\n" ); ! 118: fprintf( HeaderFile, "//\r\n" ); ! 119: fprintf( HeaderFile, "// Sev - is the severity code\r\n" ); ! 120: fprintf( HeaderFile, "//\r\n" ); ! 121: fprintf( HeaderFile, "// 00 - Success\r\n" ); ! 122: fprintf( HeaderFile, "// 01 - Informational\r\n" ); ! 123: fprintf( HeaderFile, "// 10 - Warning\r\n" ); ! 124: fprintf( HeaderFile, "// 11 - Error\r\n" ); ! 125: fprintf( HeaderFile, "//\r\n" ); ! 126: fprintf( HeaderFile, "// C - is the Customer code flag\r\n" ); ! 127: fprintf( HeaderFile, "//\r\n" ); ! 128: fprintf( HeaderFile, "// R - is a reserved bit\r\n" ); ! 129: fprintf( HeaderFile, "//\r\n" ); ! 130: fprintf( HeaderFile, "// Facility - is the facility code\r\n" ); ! 131: fprintf( HeaderFile, "//\r\n" ); ! 132: fprintf( HeaderFile, "// Code - is the facility's status code\r\n" ); ! 133: fprintf( HeaderFile, "//\r\n" ); ! 134: ! 135: fprintf( HeaderFile, "//\r\n" ); ! 136: fprintf( HeaderFile, "// Define the facility codes\r\n" ); ! 137: fprintf( HeaderFile, "//\r\n" ); ! 138: p = FacilityNames; ! 139: while( p ) { ! 140: if (p->Value) { ! 141: fprintf( HeaderFile, GenerateDecimalValues ? ! 142: "#define %-32s %ld\r\n" : ! 143: "#define %-32s 0x%lX\r\n", ! 144: p->Value, p->Id ! 145: ); ! 146: } ! 147: ! 148: p = p->Next; ! 149: } ! 150: fprintf( HeaderFile, "\r\n" ); ! 151: fprintf( HeaderFile, "\r\n" ); ! 152: ! 153: fprintf( HeaderFile, "//\r\n" ); ! 154: fprintf( HeaderFile, "// Define the severity codes\r\n" ); ! 155: fprintf( HeaderFile, "//\r\n" ); ! 156: p = SeverityNames; ! 157: while( p ) { ! 158: if (p->Value) { ! 159: fprintf( HeaderFile, GenerateDecimalValues ? ! 160: "#define %-32s %ld\r\n" : ! 161: "#define %-32s 0x%lX\r\n", ! 162: p->Value, p->Id ! 163: ); ! 164: } ! 165: ! 166: p = p->Next; ! 167: } ! 168: fprintf( HeaderFile, "\r\n" ); ! 169: fprintf( HeaderFile, "\r\n" ); ! 170: } ! 171: ! 172: if (!McParseMessageDefinition()) { ! 173: return( FALSE ); ! 174: } ! 175: break; ! 176: ! 177: default: ! 178: McInputError( "Invalid message file token - '%s'", TRUE, TokenCharValue ); ! 179: return( FALSE ); ! 180: break; ! 181: } ! 182: } ! 183: ! 184: McFlushComments(); ! 185: return( TRUE ); ! 186: } ! 187: ! 188: ! 189: BOOLEAN ! 190: McParseMessageDefinition( void ) ! 191: { ! 192: unsigned int t; ! 193: PMESSAGE_INFO MessageInfo; ! 194: BOOLEAN MessageIdSeen; ! 195: PMESSAGE_INFO MessageInfoTemp; ! 196: ! 197: McFlushComments(); ! 198: ! 199: MessageInfo = malloc( sizeof( *MessageInfo ) ); ! 200: MessageInfo->Next = NULL; ! 201: MessageInfo->Id = 0; ! 202: MessageInfo->Method = MSG_PLUS_ONE; ! 203: MessageInfo->SymbolicName = NULL; ! 204: MessageInfo->EndOfLineComment = NULL; ! 205: MessageInfo->MessageText = NULL; ! 206: MessageIdSeen = FALSE; ! 207: ! 208: while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) { ! 209: switch (t) { ! 210: case MCTOK_MESSAGEID_KEYWORD: ! 211: if (MessageIdSeen) { ! 212: McInputError( "Invalid message definition - text missing.", TRUE, NULL ); ! 213: return( FALSE ); ! 214: } ! 215: ! 216: MessageIdSeen = TRUE; ! 217: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 218: if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) { ! 219: MessageInfo->Id = TokenNumericValue; ! 220: MessageInfo->Method = MSG_ABSOLUTE; ! 221: } ! 222: else ! 223: if (t == MCTOK_PLUS) { ! 224: if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) { ! 225: MessageInfo->Id = TokenNumericValue; ! 226: MessageInfo->Method = MSG_PLUS_VALUE; ! 227: } ! 228: else { ! 229: McInputError( "Number must follow %s=+", TRUE, TokenKeyword->Name ); ! 230: return( FALSE ); ! 231: } ! 232: } ! 233: else { ! 234: McUnGetToken(); ! 235: } ! 236: ! 237: } ! 238: else { ! 239: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 240: return( FALSE ); ! 241: } ! 242: break; ! 243: ! 244: case MCTOK_SEVERITY_KEYWORD: ! 245: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 246: if (!McParseName( SeverityNames, &CurrentSeverityName )) { ! 247: return( FALSE ); ! 248: } ! 249: } ! 250: else { ! 251: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 252: return( FALSE ); ! 253: } ! 254: break; ! 255: ! 256: case MCTOK_FACILITY_KEYWORD: ! 257: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 258: if (!McParseName( FacilityNames, &CurrentFacilityName )) { ! 259: return( FALSE ); ! 260: } ! 261: } ! 262: else { ! 263: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 264: return( FALSE ); ! 265: } ! 266: break; ! 267: ! 268: case MCTOK_SYMBOLNAME_KEYWORD: ! 269: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 270: if ((t = McGetToken( FALSE )) == MCTOK_NAME) { ! 271: MessageInfo->SymbolicName = McMakeString( TokenCharValue ); ! 272: } ! 273: else { ! 274: McInputError( "Symbol name must follow %s=+", TRUE, TokenKeyword->Name ); ! 275: return( FALSE ); ! 276: } ! 277: } ! 278: else { ! 279: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 280: return( FALSE ); ! 281: } ! 282: break; ! 283: ! 284: ! 285: case MCTOK_END_OF_LINE_COMMENT: ! 286: MessageInfo->EndOfLineComment = McMakeString( TokenCharValue ); ! 287: break; ! 288: ! 289: case MCTOK_LANGUAGE_KEYWORD: ! 290: McUnGetToken(); ! 291: ! 292: ! 293: if (MessageInfo->Method == MSG_PLUS_ONE) { ! 294: MessageInfo->Id = CurrentFacilityName->LastId + 1; ! 295: } ! 296: else ! 297: if (MessageInfo->Method == MSG_PLUS_VALUE) { ! 298: MessageInfo->Id = CurrentFacilityName->LastId + MessageInfo->Id; ! 299: } ! 300: ! 301: if (MessageInfo->Id > 0xFFFFL) { ! 302: McInputError( "Message Id value (%lx) too large", TRUE, (PVOID)MessageInfo->Id ); ! 303: return( FALSE ); ! 304: } ! 305: ! 306: MessageInfo->Id |= (CurrentSeverityName->Id << 30) | ! 307: CustomerMsgIdBit | ! 308: (CurrentFacilityName->Id << 16); ! 309: ! 310: fprintf( HeaderFile, "//\r\n" ); ! 311: if (MessageInfo->SymbolicName) { ! 312: fprintf( HeaderFile, "// MessageId: %s\r\n", ! 313: MessageInfo->SymbolicName ! 314: ); ! 315: } ! 316: else { ! 317: fprintf( HeaderFile, "// MessageId: 0x%08lXL (No symbolic name defined)\r\n", ! 318: MessageInfo->Id ! 319: ); ! 320: } ! 321: ! 322: fprintf( HeaderFile, "//\r\n" ); ! 323: fprintf( HeaderFile, "// MessageText:\r\n" ); ! 324: fprintf( HeaderFile, "//\r\n" ); ! 325: ! 326: if (McParseMessageText( MessageInfo )) { ! 327: fprintf( HeaderFile, "//\r\n" ); ! 328: if (MessageInfo->SymbolicName) { ! 329: ! 330: if (MessageIdTypeName != NULL) { ! 331: fprintf( HeaderFile, GenerateDecimalValues ? ! 332: "#define %-32s ((%s)%ldL)" : ! 333: "#define %-32s ((%s)0x%08lXL)", ! 334: MessageInfo->SymbolicName, ! 335: MessageIdTypeName, ! 336: MessageInfo->Id ! 337: ); ! 338: } ! 339: else { ! 340: fprintf( HeaderFile, GenerateDecimalValues ? ! 341: "#define %-32s %ldL" : ! 342: "#define %-32s 0x%08lXL", ! 343: MessageInfo->SymbolicName, ! 344: MessageInfo->Id ! 345: ); ! 346: } ! 347: } ! 348: ! 349: if (MessageInfo->EndOfLineComment) { ! 350: fprintf( HeaderFile, " %s", MessageInfo->EndOfLineComment ); ! 351: } ! 352: else { ! 353: fprintf( HeaderFile, "\r\n" ); ! 354: } ! 355: fprintf( HeaderFile, "\r\n" ); ! 356: ! 357: if (Messages == NULL) { ! 358: Messages = MessageInfo; ! 359: } ! 360: else { ! 361: MessageInfoTemp = Messages; ! 362: ! 363: // ! 364: // Scan the existing messages to see if this message ! 365: // exists in the message file. ! 366: // ! 367: // If it does, generate and error for the user. ! 368: // ! 369: ! 370: while (MessageInfoTemp != NULL) { ! 371: ! 372: if (MessageInfoTemp->Id == MessageInfo->Id) { ! 373: McInputError( "Duplicate message ID - 0x%lx", FALSE, (PVOID)MessageInfo->Id ); ! 374: } ! 375: ! 376: MessageInfoTemp = MessageInfoTemp->Next; ! 377: } ! 378: ! 379: CurrentMessage->Next = MessageInfo; ! 380: } ! 381: ! 382: CurrentMessage = MessageInfo; ! 383: CurrentFacilityName->LastId = MessageInfo->Id & 0xFFFF; ! 384: return( TRUE ); ! 385: } ! 386: else { ! 387: return( FALSE ); ! 388: } ! 389: ! 390: default: ! 391: McInputError( "Invalid message definition token - '%s'", TRUE, TokenCharValue ); ! 392: return( FALSE ); ! 393: } ! 394: } ! 395: ! 396: return( FALSE ); ! 397: } ! 398: ! 399: ! 400: char MessageTextBuffer[ 8192 ]; ! 401: ! 402: BOOLEAN ! 403: McParseMessageText( ! 404: PMESSAGE_INFO MessageInfo ! 405: ) ! 406: { ! 407: PLANGUAGE_INFO MessageText, *pp; ! 408: char *src, *dst; ! 409: unsigned int t, n; ! 410: BOOLEAN FirstLanguageProcessed; ! 411: ! 412: pp = &MessageInfo->MessageText; ! 413: ! 414: FirstLanguageProcessed = FALSE; ! 415: while ((t = McGetToken( TRUE )) != MCTOK_END_OF_FILE) { ! 416: if (t == MCTOK_LANGUAGE_KEYWORD) { ! 417: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 418: if (!McParseName( LanguageNames, &CurrentLanguageName )) { ! 419: return( FALSE ); ! 420: } ! 421: } ! 422: else { ! 423: McInputError( "Equal sign must follow %s", TRUE, TokenKeyword->Name ); ! 424: return( FALSE ); ! 425: } ! 426: } ! 427: else { ! 428: McUnGetToken(); ! 429: break; ! 430: } ! 431: ! 432: MessageText = malloc( sizeof( *MessageText ) ); ! 433: MessageText->Next = NULL; ! 434: MessageText->Id = CurrentLanguageName->Id; ! 435: MessageText->Length = 0; ! 436: MessageText->Text = NULL; ! 437: ! 438: dst = MessageTextBuffer; ! 439: while (src = McGetLine()) { ! 440: if (!strcmp( src, ".\r\n" )) { ! 441: if (MessageText->Length == 0) { ! 442: if (MessageInfo->SymbolicName) { ! 443: strcpy( dst, MessageInfo->SymbolicName ); ! 444: } ! 445: else { ! 446: sprintf( dst, "No symbolic name defined for0x%08lXL" ); ! 447: } ! 448: ! 449: strcat( dst, "\r\n" ); ! 450: if (!FirstLanguageProcessed) { ! 451: fprintf( HeaderFile, "// %s", dst ); ! 452: } ! 453: ! 454: n = strlen( dst ); ! 455: dst += n; ! 456: MessageText->Length += n; ! 457: } ! 458: ! 459: McSkipLine(); ! 460: break; ! 461: } ! 462: else ! 463: if (!strnicmp( src, "LanguageId=", 11 ) || ! 464: !strnicmp( src, "MessageId=", 10 ) ! 465: ) { ! 466: McInputError( "Unterminated message definition", TRUE, NULL ); ! 467: return( FALSE ); ! 468: } ! 469: ! 470: if (!FirstLanguageProcessed) { ! 471: fprintf( HeaderFile, "// %s", src ); ! 472: } ! 473: ! 474: n = strlen( src ); ! 475: if (MessageText->Length + n > sizeof( MessageTextBuffer )) { ! 476: McInputError( "Message text too long - > %ld", TRUE, ! 477: (PVOID)(ULONG)sizeof( MessageTextBuffer ) ! 478: ); ! 479: return( FALSE ); ! 480: } ! 481: ! 482: strcpy( dst, src ); ! 483: dst += n; ! 484: MessageText->Length += n; ! 485: } ! 486: *dst = '\0'; ! 487: ! 488: n = ((USHORT)MessageText->Length)+1; ! 489: MessageText->Text = malloc( n ); ! 490: memcpy( MessageText->Text, MessageTextBuffer, n ); ! 491: *pp = MessageText; ! 492: pp = &MessageText->Next; ! 493: FirstLanguageProcessed = TRUE; ! 494: } ! 495: ! 496: return( TRUE ); ! 497: } ! 498: ! 499: ! 500: BOOLEAN ! 501: McParseNameList( ! 502: PNAME_INFO *NameListHead, ! 503: BOOLEAN ValueRequired, ! 504: ULONG MaximumValue ! 505: ) ! 506: { ! 507: unsigned int t; ! 508: PNAME_INFO p; ! 509: char *Name; ! 510: ULONG Id; ! 511: PVOID Value; ! 512: ! 513: while ((t = McGetToken( FALSE )) != MCTOK_END_OF_FILE) { ! 514: if (t == MCTOK_RIGHT_PAREN) { ! 515: return( TRUE ); ! 516: } ! 517: ! 518: if (t == MCTOK_NAME) { ! 519: Name = McMakeString( TokenCharValue ); ! 520: Id = 0; ! 521: Value = NULL; ! 522: if ((t = McGetToken( FALSE )) == MCTOK_EQUAL) { ! 523: if ((t = McGetToken( FALSE )) == MCTOK_NUMBER) { ! 524: Id = TokenNumericValue; ! 525: if ((t = McGetToken( FALSE )) == MCTOK_COLON) { ! 526: if ((t = McGetToken( FALSE )) == MCTOK_NAME) { ! 527: Value = McMakeString( TokenCharValue ); ! 528: } ! 529: else { ! 530: McInputError( "File name must follow =%ld:", TRUE, (PVOID)Id ); ! 531: return( FALSE ); ! 532: } ! 533: } ! 534: else { ! 535: if (ValueRequired) { ! 536: McInputError( "Colon must follow =%ld", TRUE, (PVOID)Id ); ! 537: return( FALSE ); ! 538: } ! 539: ! 540: McUnGetToken(); ! 541: } ! 542: } ! 543: else { ! 544: McInputError( "Number must follow %s=", TRUE, Name ); ! 545: return( FALSE ); ! 546: } ! 547: } ! 548: else { ! 549: McInputError( "Equal sign name must follow %s", TRUE, Name ); ! 550: return( FALSE ); ! 551: } ! 552: ! 553: if (Id > MaximumValue) { ! 554: McInputError( "Value is too large (> %lx)", TRUE, (PVOID)MaximumValue ); ! 555: return( FALSE ); ! 556: } ! 557: ! 558: p = McAddName( NameListHead, Name, Id, Value ); ! 559: free( Name ); ! 560: } ! 561: } ! 562: ! 563: return( FALSE ); ! 564: } ! 565: ! 566: BOOLEAN ! 567: McParseName( ! 568: PNAME_INFO NameListHead, ! 569: PNAME_INFO *Result ! 570: ) ! 571: { ! 572: unsigned int t; ! 573: PNAME_INFO p; ! 574: ! 575: if ((t = McGetToken( FALSE )) == MCTOK_NAME) { ! 576: p = McFindName( NameListHead, TokenCharValue ); ! 577: if (p != NULL) { ! 578: *Result = p; ! 579: return( TRUE ); ! 580: } ! 581: else { ! 582: McInputError( "Invalid name - %s", TRUE, TokenCharValue ); ! 583: } ! 584: } ! 585: else { ! 586: McInputError( "Missing name after %s=", TRUE, TokenKeyword->Name ); ! 587: } ! 588: ! 589: return( FALSE ); ! 590: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.