|
|
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.