Annotation of mstools/samples/sdktools/mc/mclex.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1991  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     mclex.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file contains the input lexer for the Win32 Message Compiler (MC)
                     12: 
                     13: --*/
                     14: 
                     15: 
                     16: #include "mc.h"
                     17: 
                     18: char LineBuffer[ 256 ];
                     19: char *CurrentChar;
                     20: BOOLEAN ReturnCurrentToken;
                     21: 
                     22: PNAME_INFO KeywordNames;
                     23: 
                     24: typedef struct _COMMENT_INFO {
                     25:     struct _COMMENT_INFO *Next;
                     26:     char Text[ 1 ];
                     27: } COMMENT_INFO, *PCOMMENT_INFO;
                     28: 
                     29: PCOMMENT_INFO Comments, CurrentComment;
                     30: 
                     31: /*++
                     32: 
                     33: Routine Description:
                     34: 
                     35:     This fills in the Key words associated with the Message file format
                     36: 
                     37: Return Value:
                     38: 
                     39:     TRUE
                     40: 
                     41: --*/
                     42: 
                     43: 
                     44: 
                     45: BOOLEAN
                     46: McInitLexer( void )
                     47: {
                     48:     ReturnCurrentToken = FALSE;
                     49:     McAddName( &KeywordNames, "MessageIdTypedef",   MCTOK_MSGIDTYPE_KEYWORD,  NULL );
                     50:     McAddName( &KeywordNames, "SeverityNames",      MCTOK_SEVNAMES_KEYWORD,   NULL );
                     51:     McAddName( &KeywordNames, "FacilityNames",      MCTOK_FACILITYNAMES_KEYWORD,  NULL );
                     52:     McAddName( &KeywordNames, "LanguageNames",      MCTOK_LANGNAMES_KEYWORD,  NULL );
                     53:     McAddName( &KeywordNames, "MessageId",          MCTOK_MESSAGEID_KEYWORD,  NULL );
                     54:     McAddName( &KeywordNames, "Severity",           MCTOK_SEVERITY_KEYWORD,   NULL );
                     55:     McAddName( &KeywordNames, "Facility",           MCTOK_FACILITY_KEYWORD,   NULL );
                     56:     McAddName( &KeywordNames, "SymbolicName",       MCTOK_SYMBOLNAME_KEYWORD, NULL );
                     57:     McAddName( &KeywordNames, "Language",           MCTOK_LANGUAGE_KEYWORD,   NULL );
                     58:     return( TRUE );
                     59: }
                     60: 
                     61: 
                     62: 
                     63: BOOLEAN
                     64: McOpenInputFile( void )
                     65: {
                     66:     char SavedChar, *s, *FileName;
                     67:     BOOLEAN Result;
                     68: 
                     69:     s = MessageFileName;
                     70:     FileName = s;
                     71:     SavedChar = '\0';
                     72:     while (*s) {
                     73:         if (*s == '.') {
                     74:             SavedChar = '.';
                     75:             *s = '\0';
                     76:             break;
                     77:             }
                     78: 
                     79:         if (*s == ':' || *s == '\\' || *s == '/') {
                     80:             FileName = s+1;
                     81:             }
                     82: 
                     83:         s++;
                     84:         }
                     85: 
                     86:     strcat( HeaderFileName, FileName );
                     87:     strcat( HeaderFileName, ".h" );
                     88:     strcat( RcInclFileName, FileName );
                     89:     strcat( RcInclFileName, ".rc" );
                     90: 
                     91:     if (SavedChar == '\0') {
                     92:         strcpy( s, ".mc" );
                     93:         }
                     94:     else {
                     95:         *s = SavedChar;
                     96:         }
                     97: 
                     98:     Result = FALSE;
                     99:     MessageFileLineNumber = 0;
                    100:     LineBuffer[ 0 ] = '\0';
                    101:     CurrentChar = NULL;
                    102: 
                    103:     MessageFile = fopen( MessageFileName, "rb" );
                    104:     if (MessageFile == NULL) {
                    105:         McInputError( "unable to open input file", TRUE, NULL );
                    106:         }
                    107:     else {
                    108:         HeaderFile = fopen( HeaderFileName, "wb" );
                    109:         if (HeaderFile == NULL) {
                    110:             McInputError( "unable to open output file - %s", TRUE, HeaderFileName );
                    111:             }
                    112:         else {
                    113:             RcInclFile = fopen( RcInclFileName, "wb" );
                    114:             if (RcInclFile == NULL) {
                    115:                 McInputError( "unable to open output file - %s", TRUE, RcInclFileName );
                    116:                 }
                    117:             else {
                    118:                 Result = TRUE;
                    119:                 }
                    120:             }
                    121:         }
                    122: 
                    123:     if (!Result) {
                    124:         McCloseInputFile();
                    125:         McCloseOutputFiles();
                    126:         }
                    127:     else {
                    128:         return( TRUE );
                    129:         }
                    130: }
                    131: 
                    132: 
                    133: 
                    134: void
                    135: McCloseInputFile( void )
                    136: {
                    137:     if (MessageFile != NULL) {
                    138:         fclose( MessageFile );
                    139:         MessageFile = NULL;
                    140:         CurrentChar = NULL;
                    141:         LineBuffer[ 0 ] = '\0';
                    142:         }
                    143: }
                    144: 
                    145: 
                    146: 
                    147: void
                    148: McCloseOutputFiles( void )
                    149: {
                    150:     if (HeaderFile != NULL) {
                    151:         fclose( HeaderFile );
                    152:         }
                    153: 
                    154:     if (RcInclFile != NULL) {
                    155:         fclose( RcInclFile );
                    156:         }
                    157: }
                    158: 
                    159: 
                    160: void
                    161: McInputError(
                    162:     char *Message,
                    163:     BOOLEAN Error,
                    164:     PVOID Argument
                    165:     )
                    166: {
                    167:     fprintf( stderr,
                    168:              "%s (%d) : %s: ",
                    169:              MessageFileName,
                    170:              MessageFileLineNumber,
                    171:              Error ? "Error" : "Warning"
                    172:            );
                    173: 
                    174:     fprintf( stderr, Message, Argument );
                    175:     fprintf( stderr, "\n" );
                    176: }
                    177: 
                    178: 
                    179: /*++
                    180: 
                    181: Routine Description:
                    182: 
                    183:    This retrieves the current line then moves down to the
                    184:    next line in the message file.
                    185: 
                    186: Return Value:
                    187: 
                    188:    Returns the current line of in the file.
                    189: 
                    190: --*/
                    191: 
                    192: 
                    193: char *
                    194: McGetLine( void )
                    195: {
                    196:     char *s;
                    197: 
                    198:     if (MessageFile == NULL || feof( MessageFile )) {
                    199:         return( NULL );
                    200:         }
                    201: 
                    202:     if (fgets( LineBuffer, sizeof( LineBuffer ), MessageFile ) == NULL) {
                    203:         return( NULL );
                    204:         }
                    205: 
                    206:     s = LineBuffer + strlen( LineBuffer );
                    207:     if (s > LineBuffer && *--s == '\n') {
                    208:         if (s > LineBuffer && *--s != '\r') {
                    209:             *++s = '\r';
                    210:             *++s = '\n';
                    211:             *++s = '\0';
                    212:             }
                    213:         }
                    214: 
                    215:     MessageFileLineNumber++;
                    216:     return( CurrentChar = LineBuffer );
                    217: }
                    218: 
                    219: 
                    220: void
                    221: McSkipLine( void )
                    222: {
                    223:     CurrentChar = NULL;
                    224: }
                    225: 
                    226: 
                    227: /*++
                    228: 
                    229: Routine Description:
                    230: 
                    231:    This retrieves the character at the current position of the line
                    232:    buffer then advances to the next position. If the end of the line
                    233:    is reached another line is retrieve. If the end of the file is reached
                    234:    this returns with a NULL character. One is optionally able to flush
                    235:    the white space from the line.
                    236: 
                    237: Arguments:
                    238: 
                    239:    A boolean specifying whether whitespace should be consider significant.
                    240: 
                    241: Return Value:
                    242: 
                    243:    Returns the character in the current line.
                    244: 
                    245: --*/
                    246: 
                    247: 
                    248: 
                    249: 
                    250: char
                    251: McGetChar(
                    252:     BOOLEAN SkipWhiteSpace
                    253:     )
                    254: {
                    255:     BOOLEAN SawWhiteSpace;
                    256:     BOOLEAN SawNewLine;
                    257:     PCOMMENT_INFO p;
                    258: 
                    259:     SawWhiteSpace = FALSE;
                    260: 
                    261: tryagain:
                    262:     SawNewLine = FALSE;
                    263:     if (CurrentChar == NULL) {
                    264:         McGetLine();
                    265:         if (CurrentChar == NULL) {
                    266:             return( '\0' );
                    267:             }
                    268: 
                    269:         SawNewLine = TRUE;
                    270:         }
                    271: 
                    272:     if (SkipWhiteSpace) {
                    273:         while (*CurrentChar <= ' ') {
                    274:             SawWhiteSpace = TRUE;
                    275:             if (!*CurrentChar++) {
                    276:                 CurrentChar = NULL;
                    277:                 break;
                    278:                 }
                    279:             }
                    280:         }
                    281: 
                    282:     if (SawNewLine) {
                    283:         if (CurrentChar != NULL && *CurrentChar == MCCHAR_END_OF_LINE_COMMENT) {
                    284:             p = malloc( sizeof( *p ) + strlen( ++CurrentChar ) );
                    285:             p->Next = NULL;
                    286:             strcpy( p->Text, CurrentChar );
                    287:             if (CurrentComment == NULL) {
                    288:                 Comments = p;
                    289:                 }
                    290:             else {
                    291:                 CurrentComment->Next = p;
                    292:                 }
                    293:             CurrentComment = p;
                    294: 
                    295:             CurrentChar = NULL;
                    296:             }
                    297:         }
                    298: 
                    299:     if (CurrentChar == NULL && SkipWhiteSpace) {
                    300:         goto tryagain;
                    301:         }
                    302: 
                    303:     if (SawWhiteSpace) {
                    304:         return( ' ' );
                    305:         }
                    306:     else {
                    307:         return( *CurrentChar++ );
                    308:         }
                    309: }
                    310: 
                    311: 
                    312: void
                    313: McFlushComments( void )
                    314: {
                    315:     PCOMMENT_INFO p;
                    316: 
                    317:     while (p = Comments) {
                    318:         fprintf( HeaderFile, "%s", p->Text );
                    319: 
                    320:         Comments = Comments->Next;
                    321:         free( p );
                    322:         }
                    323:     Comments = NULL;
                    324:     CurrentComment = NULL;
                    325: 
                    326:     fflush( HeaderFile );
                    327:     return;
                    328: }
                    329: 
                    330: 
                    331: void
                    332: McUnGetChar(
                    333:     char c
                    334:     )
                    335: {
                    336:     if (CurrentChar > LineBuffer) {
                    337:         *--CurrentChar = c;
                    338:         }
                    339:     else {
                    340:         LineBuffer[ 0 ] = c;
                    341:         LineBuffer[ 1 ] = '\0';
                    342:         CurrentChar = LineBuffer;
                    343:         }
                    344: }
                    345: 
                    346: 
                    347: /*++
                    348: 
                    349: Routine Description:
                    350: 
                    351:     Breaks input line into "tokens values" as defined in MC.H.
                    352: 
                    353: Arguments:
                    354: 
                    355:     A boolean designating whether keywords are required.
                    356: 
                    357: Return Value:
                    358: 
                    359:    Returns the the token corresponding to the "token value" For example
                    360:    with a token of type MCTOK_NUMBER the value would be a string
                    361:    representation of an integer.
                    362: 
                    363: --*/
                    364: 
                    365: 
                    366: unsigned int
                    367: McGetToken(
                    368:     BOOLEAN KeywordExpected
                    369:     )
                    370: {
                    371:     char c, *dst;
                    372: 
                    373:     if (ReturnCurrentToken) {
                    374:         ReturnCurrentToken = FALSE;
                    375:         if (Token == MCTOK_NAME && KeywordExpected) {
                    376:             TokenKeyword = McFindName( KeywordNames, TokenCharValue );
                    377:             if (TokenKeyword == NULL) {
                    378:                 McInputError( "expected keyword - %s", TRUE, TokenCharValue );
                    379:                 Token = MCTOK_END_OF_FILE;
                    380:                 }
                    381:             else {
                    382:                 Token = (unsigned int)TokenKeyword->Id;
                    383:                 }
                    384:             }
                    385: 
                    386:         return( Token );
                    387:         }
                    388: 
                    389:     Token = MCTOK_END_OF_FILE;
                    390:     dst = TokenCharValue;
                    391:     *dst = '\0';
                    392:     TokenNumericValue = 0L;
                    393: 
                    394:     while (TRUE) {
                    395:         c = McGetChar( (BOOLEAN)(Token == MCTOK_END_OF_FILE) );
                    396:         if (Token == MCTOK_NUMBER) {
                    397:             if (isdigit( c ) ||
                    398:                 c == 'x' ||
                    399:                 (c >= 'a' && c <= 'f') ||
                    400:                 (c >= 'A' && c <= 'F')
                    401:                ) {
                    402:                 *dst++ = c;
                    403:                 }
                    404:             else {
                    405:                 McUnGetChar( c );
                    406:                 *dst = '\0';
                    407: 
                    408:                 if (!McCharToInteger( TokenCharValue, 0, &TokenNumericValue )) {
                    409:                     McInputError( "invalid number - %s", TRUE, TokenCharValue );
                    410:                     Token = MCTOK_END_OF_FILE;
                    411:                     }
                    412:                 else {
                    413:                     return( Token );
                    414:                     }
                    415:                 }
                    416:             }
                    417:         else
                    418:         if (Token == MCTOK_NAME) {
                    419:             if (iscsym( c )) {
                    420:                 *dst++ = c;
                    421:                 }
                    422:             else {
                    423:                 McUnGetChar( c );
                    424:                 *dst = '\0';
                    425: 
                    426:                 if (KeywordExpected) {
                    427:                     TokenKeyword = McFindName( KeywordNames, TokenCharValue );
                    428:                     if (TokenKeyword == NULL) {
                    429:                         McInputError( "expected keyword - %s", TRUE, TokenCharValue );
                    430:                         Token = MCTOK_END_OF_FILE;
                    431:                         }
                    432:                     else {
                    433:                         Token = (unsigned int)TokenKeyword->Id;
                    434:                         }
                    435:                     }
                    436:                 return( Token );
                    437:                 }
                    438:             }
                    439:         else
                    440:         if (isdigit( c )) {
                    441:             *dst++ = c;
                    442:             Token = MCTOK_NUMBER;
                    443:             }
                    444:         else
                    445:         if (iscsymf( c )) {
                    446:             *dst++ = c;
                    447:             Token = MCTOK_NAME;
                    448:             }
                    449:         else
                    450:         if (c == '=') {
                    451:             *dst++ = c;
                    452:             *dst = '\0';
                    453:             Token = MCTOK_EQUAL;
                    454:             return( Token );
                    455:             }
                    456:         else
                    457:         if (c == '(') {
                    458:             *dst++ = c;
                    459:             *dst = '\0';
                    460:             Token = MCTOK_LEFT_PAREN;
                    461:             return( Token );
                    462:             }
                    463:         else
                    464:         if (c == ')') {
                    465:             *dst++ = c;
                    466:             *dst = '\0';
                    467:             Token = MCTOK_RIGHT_PAREN;
                    468:             return( Token );
                    469:             }
                    470:         else
                    471:         if (c == ':') {
                    472:             *dst++ = c;
                    473:             *dst = '\0';
                    474:             Token = MCTOK_COLON;
                    475:             return( Token );
                    476:             }
                    477:         else
                    478:         if (c == '+') {
                    479:             *dst++ = c;
                    480:             *dst = '\0';
                    481:             Token = MCTOK_PLUS;
                    482:             return( Token );
                    483:             }
                    484:         else
                    485:         if (c == ' ') {
                    486:             }
                    487:         else
                    488:         if (c == MCCHAR_END_OF_LINE_COMMENT) {
                    489:             Token = MCTOK_END_OF_LINE_COMMENT;
                    490:             strcpy( TokenCharValue, CurrentChar );
                    491:             CurrentChar = NULL;
                    492:             return( Token );
                    493:             }
                    494:         else
                    495:         if (c == '\0') {
                    496:             return( Token );
                    497:             }
                    498:         else {
                    499:             McInputError( "invalid character '%c'", TRUE, (PVOID)(ULONG)(UCHAR)c );
                    500:             }
                    501:         }
                    502: }
                    503: 
                    504: 
                    505: void
                    506: McUnGetToken( void )
                    507: {
                    508:     ReturnCurrentToken = TRUE;
                    509: }
                    510: 
                    511: char *
                    512: McSkipWhiteSpace(
                    513:     char *s
                    514:     )
                    515: {
                    516:     while (*s <= ' ') {
                    517:         if (!*s++) {
                    518:             s = NULL;
                    519:             break;
                    520:             }
                    521:         }
                    522: 
                    523:     return( s );
                    524: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.