srcfile.c

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

C
2,229
字号
{
    OPEN_FILE *act;

    act = activeSrc();
    act->column++;
    CurrChar = '?';
    NextChar = getCharAfterOneQuestion;
    return( CurrChar );
}

static void outputTrigraphWarning( char c ) {
    if( ! CompFlags.extensions_enabled ) {
        // probably know about trigraphs if they are using -za
        return;
    }
    if( NestLevel != SkipLevel ) {
        // we are in an excluded #if region
        return;
    }
    if( CompFlags.scanning_c_comment ) {
        // do one cares about this in comments
        return;
    }
    if( CompFlags.scanning_cpp_comment ) {
        // do one cares about this in comments
        return;
    }
    SrcFileCurrentLocation();
    CErr2( WARN_EXPANDED_TRIGRAPH, c );
}

static char translateTriGraph( char c )
{
    struct tri_graph *p;

    for( p = triGraphs; p->tri != '\0'; ++p ) {
        if( c == p->tri ) {
            outputTrigraphWarning( p->new );
            return( p->new );
        }
    }
    return( c );
}

static int tryTrigraphStart( void )
{
    int c;
    OPEN_FILE *act;

    act = activeSrc();
    c = doFlushWS();
    if( c != '\0' ) {
        return( getCharCheck( act, c ) );
    }
    NextChar = GetNextChar;
    return( getCharCheck( act, '?' ) );
}

static int tryBackSlashNewLine( OPEN_FILE *act )
{
    boolean skipped_ws = FALSE;
    int nc;

    // CurrChar is '\\' and act->column is up to date
    numBlanks1 = 0;
    numTABs = 0;
    numBlanks2 = 0;
    nc = getTestCharFromFile( &act );
    if( CompFlags.extensions_enabled ) {
        while( nc == ' ' ) {
            ++numBlanks1;
            skipped_ws = TRUE;
            nc = getTestCharFromFile( &act );
        }
        while( nc == '\t' ) {
            skipped_ws = TRUE;
            ++numTABs;
            nc = getTestCharFromFile( &act );
        }
        while( nc == ' ' ) {
            skipped_ws = TRUE;
            ++numBlanks2;
            nc = getTestCharFromFile( &act );
        }
    }
    if( nc == '\r' ) {
        nc = getTestCharFromFile( &act );
    }
    switch( nc ) {
    case '\n':
        if( skipped_ws ) {
            SrcFileCurrentLocation();
            CErr1( WARN_WHITE_AFTER_SPLICE );
        }
        if( CompFlags.scanning_cpp_comment ) {
            if( NestLevel == SkipLevel ) {
                SrcFileCurrentLocation();
                CErr1( WARN_SPLICE_IN_CPP_COMMENT );
            }
        }
        if( CompFlags.cpp_output ) {
            if( CompFlags.in_pragma ) {
                PrtChar( '\\' );
                PrtChar( '\n' );
            } else if( CompFlags.cpp_line_wanted ) {
                PrtChar( '\n' );
            }
        }
        act->line++;
        act->column = 0;
        return( GetNextChar() );
    case '?':
        NextChar = tryTrigraphStart;
        break;
    default:
        lastChar = nc;
        NextChar = flushWSgetCharAfterOneQuestion;
    }
    return( '\\' );
}

static int tryTrigraphAgain( void )
{
    OPEN_FILE *act;
    int c;
    int xc;

    act = activeSrc();
    act->column++;
    c = getTestCharFromFile( &act );
    if( c != '?' ) {
        xc = translateTriGraph( c );
        if( c != xc ) {
            act->column += 2;
            CurrChar = xc;
            NextChar = GetNextChar;
            if( xc == '\\' ) {
                return( tryBackSlashNewLine( act ) );
            }
            return( xc );
        }
        lastChar = c;
        CurrChar = '?';
        NextChar = getCharAfterTwoQuestion;
        return( '?' );
    }
    CurrChar = c;
    /* leave NextChar set here because it could still be a trigraph */
    return( c );
}

static int getCharCheck( OPEN_FILE *act, int c )
{
    int xc;
    int nc;
    int nnc;

    // column has not being changed for 'c' yet
    if( c != '?' ) {
        switch( c ) {
        case '\0':
            // '\0' in the middle of the buffer must be processed as a char
            if( act->nextc == ( act->lastc + 1 ) ) {
                if( ! readBuffer( getGuardState() == GUARD_IFNDEF ) ) {
                    return( GetNextChar() );
                }
                return( CurrChar );
            }
            CurrChar = c;
            return( CurrChar );
        case '\n':
            act->line++;
            act->column = 0;
            break;
        case '\t':
            act->column = ( act->column + tabWidth ) & - tabWidth;
            break;
        case '\\':
            act->column++;
            CurrChar = c;
            return( tryBackSlashNewLine( act ) );
        case '\r':
            break;
        default:
            act->column++;
            if( c > 0x7f && CharSet[c] & C_DB ) {
                // we should not process the second byte through
                // normal channels since its value is meaningless
                // out of context
                NextChar = getSecondMultiByte;
            }
        }
        CurrChar = c;
        return( c );
    }
    /* we have one '?' */
    act->column++;
    nc = getTestCharFromFile( &act );
    if( nc != '?' ) {
        lastChar = nc;
        CurrChar = c;
        NextChar = getCharAfterOneQuestion;
        return( c );
    }
    /* we have two '?'s */
    nnc = getTestCharFromFile( &act );
    xc = translateTriGraph( nnc );
    if( nnc != xc ) {
        act->column += 2;
        CurrChar = xc;
        if( xc == '\\' ) {
            return( tryBackSlashNewLine( act ) );
        }
        return( xc );
    }
    lastChar = nnc;
    CurrChar = c;
    if( nnc == '?' ) {
        /* the next char after this may be a valid trigraph! */
        NextChar = tryTrigraphAgain;
        return( c );
    }
    NextChar = getCharAfterTwoQuestion;
    return( c );
}

static int regetUngotCharAfterOneQuestion( void )
{
    int c;

    // column for 'lastChar' has been set
    NextChar = GetNextChar;
    c = lastChar;
    CurrChar = c;
    return( c );
}

static int regetUngotCharAfterTwoQuestion( void )
{
    int c;

    NextChar = regetUngotCharAfterOneQuestion;
    c = '?';
    CurrChar = c;
    return( c );
}

static int restartDetectOneQuestion( void )
{
    int c;

    NextChar = regetUngotCharAfterOneQuestion;
    c = '?';
    CurrChar = c;
    return( c );
}

static int restartDetectTwoQuestion( void )
{
    int c;

    NextChar = regetUngotCharAfterTwoQuestion;
    c = '?';
    CurrChar = c;
    return( c );
}

static int restartBackSlashWhiteSpace( void )
{
    int c;

    NextChar = flushWSgetCharAfterOneQuestion;
    c = '\\';
    CurrChar = c;
    return( c );
}

static int restartBackSlashWhiteSpaceQuestion( void )
{
    int c;

    NextChar = tryTrigraphStart;
    c = '\\';
    CurrChar = c;
    return( c );
}

void GetNextCharUndo( int c )
{
    if( NextChar == GetNextChar ) {
        // will return 'lastChar' and reset back to 'GetNextChar'
        NextChar = regetUngotCharAfterOneQuestion;
        lastChar = c;
        return;
    }
    if( NextChar == getCharAfterOneQuestion ) {
        // lastChar already has character saved in it
        // c should be '?'
        DbgAssert( c == '?' );
        NextChar = restartDetectOneQuestion;
        return;
    }
    if( NextChar == getCharAfterTwoQuestion ) {
        // lastChar already has character saved in it
        // c should be '?'
        DbgAssert( c == '?' );
        NextChar = restartDetectTwoQuestion;
        return;
    }
    if( NextChar == flushWSgetCharAfterOneQuestion ) {
        // lastChar already has character saved in it
        // c should be '\\'
        DbgAssert( c == '\\' );
        NextChar = restartBackSlashWhiteSpace;
        return;
    }
    if( NextChar == tryTrigraphStart ) {
        // c should be '\\'
        // no need to set lastChar
        // tryTrigraphStart will eventually return '?'
        DbgAssert( c == '\\' );
        NextChar = restartBackSlashWhiteSpaceQuestion;
        return;
    }
#ifndef NDEBUG
    CFatal( "more than one GetNextCharUndo executed" );
#endif
}

int GetNextChar( void )
{
    OPEN_FILE *act;
    int c;

    act = activeSrc();
    c = *act->nextc++;
    if(( CharSet[c] & C_EX ) == 0 ) {
        act->column++;
        CurrChar = c;
        return( c );
    }
    return( getCharCheck( act, c ) );
}

void SrcFileScanName( int e )   // CALLED FROM CSCAN TO SCAN AN IDENTIFIER
{
    unsigned    len;
    char        *p;
    OPEN_FILE   *act;

    len = TokenLen - 1;
    if( CharSet[e] & (C_AL|C_DI) ) {
        ++len;
        if( NextChar == GetNextChar ) {
            union {
                int c;
                char ch;
            } u;

            for(;;) {
                // codegen can't do this optimization so we have to
                u.c = 0;
                act = activeSrc();
                p = act->nextc;
                for(;;) {
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    u.ch = *p++;
                    if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                    Buffer[len] = u.ch;
                    ++len;
                    if( len > BUF_SIZE ) {
                        len = BUF_SIZE;
                    }
                }
                act->column += p - act->nextc;
                act->nextc = p;
                if(( CharSet[u.c] & C_EX ) == 0 ) break;
                // act->column is one too many at this point
                --act->column;
                u.c = getCharCheck( act, u.c );
                if(( CharSet[u.c] & (C_AL|C_DI) ) == 0 ) break;
                Buffer[len] = u.ch;
                ++len;
            }
            CurrChar = u.c;
        } else {
            int c;

            // it should be impossible to get here
            // but we'll just be safe rather than sorry...
            for(;;) {
                c = NextChar();
                if(( CharSet[c] & (C_AL|C_DI) ) == 0 ) break;
                Buffer[len] = c;
                ++len;
                if( len > BUF_SIZE ) {
                    len = BUF_SIZE;
                }
            }
        }
    }
    if( len >= BUF_SIZE - 2 ) {
        if( NestLevel == SkipLevel ) {
            CErr1( ERR_TOKEN_TRUNCATED );
        }
        len = BUF_SIZE - 2;
    }
    Buffer[len] = '\0';
    TokenLen = len;
}

int SrcFileScanWhiteSpace( int expanding )
{
    char        *p;
    OPEN_FILE   *act;

    expanding = expanding;
    if( NextChar == GetNextChar ) {
        union {

⌨️ 快捷键说明

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