parsems.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 604 行 · 第 1/2 页

C
604
字号
// read in microsoft linker commands
{
    char    hmm;
    bool    sameprompt;
    bool    gottoken;
    int     prompt;
    char *  sect;

    sameprompt = TRUE;
    gottoken = FALSE;
    prompt = 0;                     // object files.
    while( CmdFile->where != ENDOFCMD ) {
        switch( CmdFile->where ) {
        case MIDST:
            EatWhite();
            hmm = *CmdFile->current;
            switch( hmm ) {
            case '\0':
                if( CmdFile->how == BUFFERED ) {
                    CmdFile->where = ENDOFFILE;
                    sameprompt = TRUE;
                    break;
                } else if( CmdFile->how == NONBUFFERED ){
                    CmdFile->where = ENDOFLINE;
                    sameprompt = TRUE;
                    break;
                }             // note the possible fall through.
            case '\n':
                if( CmdFile->how == BUFFERED ) {
                    CmdFile->current++;
                } else {
                    CmdFile->where = ENDOFLINE;
                }
                if( !sameprompt ) {
                    NextPrompt( &prompt );
                }
                sameprompt = FALSE;
                gottoken = FALSE;
                break;
            case '@':
                CmdFile->current++;
                if( !MakeToken( SEP_NO, TRUE ) ) {
                    Error( "file name not recognized" );
                }
                StartNewFile( ToString() );
                break;
            case '+':
                CmdFile->current++;
                if( !gottoken ) {
                    Warning( "unexpected + sign found ... ignoring", prompt );
                } else {
                    sameprompt = TRUE;
                }
                gottoken = FALSE;
                break;
            case ',':
                CmdFile->current++;
                if( prompt >= 5 ) {
                    Warning( "unexpected comma found ... ignoring", prompt );
                } else {
                    NextPrompt( &prompt );
                }
                gottoken = FALSE;
                break;
            case ';':
                CmdFile->where = ENDOFCMD;
                break;
            case '/':
                CmdFile->current++;
                if( !ProcessOptions() ) {
                    DirectiveError();
                }
                gottoken = TRUE;
                break;
            case '(':
                CmdFile->current++;
                if( prompt != 0 ) {
                    Warning( "can only overlay object files", prompt );
                    break;
                }
                if( OverlayLevel > 0 ) {
                    Warning( "overlay nesting ignored since it's not allowed by Microsoft",
                                                                         OVERLAY_SLOT );
                } else {     // need a section keyword.
                    sect = MemAlloc( 8 );
                    memcpy( sect, "section", 8 );
                    AddCommand( sect , OVERLAY_SLOT, TRUE );
                }
                OverlayLevel++;       // so spurious errors not produced.
                break;
            case ')':
                CmdFile->current++;
                if( prompt == 0 ) {       // warning already printed otherwise.
                    if( OverlayLevel <= 0 ){
                        Warning("unexpected ) found ... ignoring",OVERLAY_SLOT);
                     } else {
                        OverlayLevel--;
                    }
                }
                break;
            default:          // must be a file name
                ProcessFileName( prompt );
                gottoken = TRUE;
                sameprompt = FALSE;
                break;
            }
            break;
        case ENDOFLINE:
            GetNewLine( prompt );
            break;
        case ENDOFFILE:
            RestoreCmdLine();
            break;
        }
    }
    ProcessDefFile();
}

extern bool MakeToken( sep_type separator, bool include_fn )
/**********************************************************/
// include_fn == TRUE if '.' and ':' are allowed to be part of the token
// (include filename).
{
    int     quit;
    char    hmm;
    char    matchchar;
    int     len;
    bool    forcematch;
    bool    hitmatch;

    EatWhite();
    hmm = *CmdFile->current;
    CmdFile->token = CmdFile->current;
    if( hmm == '\0' || hmm == '\n' ) {
        CmdFile->len = 0;
        return( FALSE );
    }
    CmdFile->len = 1;                 // for error reporting.
    switch( separator ){
    case SEP_QUOTE:
        if( hmm != '\'' && hmm != '"' ) {
            return( FALSE );
        }
        matchchar = hmm;
        break;
    case SEP_AT:
        if( hmm != '@' ) {
            return( FALSE );
        }
        break;
    case SEP_COLON:
        if( hmm != ':' ) {
            return( FALSE );
        }
        break;
    case SEP_EQUALS:
        if( hmm != '=' ) {
            return( FALSE );
        }
        break;
    case SEP_PERIOD:
        if( hmm != '.' ) {
            return( FALSE );
        }
        break;
    default:
        CmdFile->current--;        // no separator wanted.
    }
    CmdFile->current++;     // skip separator.
    CmdFile->token = CmdFile->current;
    hmm = *CmdFile->current;
    if( hmm == '\0' || hmm == '\n' ) {
        CmdFile->len = 0;
        return( FALSE );
    }
    len = 0;
    quit = FALSE;
    forcematch = (separator == SEP_QUOTE );
    hitmatch = FALSE;
    while( !quit ) {
        len++;
        CmdFile->current++;
        hmm = *CmdFile->current;
        switch( hmm ) {
        case '\'':
        case '"':
            if( separator == SEP_QUOTE && hmm == matchchar ) {
                CmdFile->current++;    // don't include end quote in next token.
                hitmatch = TRUE;
                quit = TRUE;
            }
            break;
        case '+':              // break a token on any of these.
        case ',':
        case ';':
        case '=':
        case '@':
        case '(':
        case ')':
            if( separator == SEP_SPACE ) break;   // NOTE: possible fall through
        case '/':
        case ' ':
        case '\t':
            if( !forcematch ) {
                quit = TRUE;
            }
            break;
        case '.':
        case ':':
            if( !forcematch && !include_fn ) {
                quit = TRUE;
            }
            break;
        case '\0':
        case '\r':
        case '\n':
            quit = TRUE;
            break;
        }
    }
    CmdFile->len = len;
    if( forcematch && !hitmatch ) {
        return( FALSE );
    }
    return( TRUE );
}

extern bool GetNumber( unsigned long * pnt )
/******************************************/
{
    char *          p;
    int             len;
    unsigned long   value;
    unsigned        radix;
    bool            isvalid;
    bool            isdig;
    char            ch;

    p = CmdFile->token;
    len = CmdFile->len;
    value = 0ul;
    radix = 10;
    if( *p == '0' ) {
        --len;
        radix = 8;
        if( tolower(*++p) == 'x') {
            radix = 16;
            ++p;
            --len;
        }
    }
    for( ; len != 0; --len ) {
        ch = tolower( *p++ );
        if( ch == 'k' ) {         // constant of the form 64k
            if( len > 1 ) {
                return( FALSE );
            } else {
                value <<= 10;        // value = value * 1024;
            }
        } else {
            isdig = isdigit( ch );
            if( radix == 10 ) {
                isvalid = isdig;
            } else if( radix == 8 ) {
                if( ch == '8' || ch == '9' || !isdig ) {
                    isvalid = FALSE;
                } else {
                    isvalid = TRUE;
                }
            } else {
                isvalid = isxdigit( ch );
            }
            if( !isvalid ) {
                return( FALSE );
            }
            value *= radix;
            if( isdig ) {
                value += ch - '0';
            } else {
                value += ch - 'a' + 10;
            }
        }
    }
    *pnt = value;
    return( TRUE );
}

extern char * ToString( void )
/****************************/
{
    char *          src;
    int             len;
    char *          str;

    src = CmdFile->token;
    len = CmdFile->len;
    str = MemAlloc( len + 1 );
    memcpy( str, src, len );
    str[ len ] = '\0';
    return( str );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?