srcfile.c

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

C
2,229
字号
void SrcFileSetCreatePCHeader(  // MARK SRCFILE TO CREATE PCHDR WHEN #include FINISHES
    void )
{
    srcFile->pch_create = TRUE;
}

void SrcFileNotAFile(           // LABEL SRCFILE AS A DEVICE
    SRCFILE sf )                // - the device source file
{
    if( sf != NULL ) {
        sf->assume_file = FALSE;
    }
}

SRCFILE SrcFileOpen(            // OPEN NEW SOURCE FILE
    void *fp,                   // - system file control
    char *name )                // - file name
{
    SRCFILE new_src;            // - new source file
    OPEN_FILE *new_act;         // - open-file information (new)

    new_src = srcFileAlloc( fp, FNameAdd( name ) );
    new_act = activeSrc();
    if( ( new_act->buff == NULL ) && ( fp != NULL ) ) {
        // need room for '\0' to signal end of buffer
        // may need room for three ';' in PCH source files
        new_act->buff = CMemAlloc( PRODUCTION_BUFFER_SIZE + 1 + 3 );
    }
    if( fp == NULL ) {
        setGuardState( GUARD_IFNDEF );
    } else {
        SRCFILE old = srcFileAddUnique( new_src );
        if( old == NULL ) {
            new_src->time_stamp = SysFileTime( fp );
            setJustOpenedGuardState();
        } else {
            new_src->time_stamp = old->time_stamp;
            _FIND_ACTUAL( old );
            setReOpenedGuardState( old->guard_state );
        }
    }
    CurrChar = '\n';
    return( new_src );
}


void SrcFileAlias(              // SET UP ALIAS FOR SOURCE FILE
    char *name,                 // - alias name
    LINE_NO line,               // - line no. (used in #line)
    int adjust )                // - amount to adjust line no. before setting
{
    SRCFILE curr;               // - current entry
    SRCFILE alias;              // - alias entry

    name = FNameAdd( name );
    if( CompFlags.cpp_output ) {
        EmitLine( line, name );
    }
    line += adjust;
    alias = NULL;
    RingIterBeg( srcFile->sister, curr ) {
        if( name == curr->name ) {
            alias = curr;
            break;
        }
    } RingIterEnd( curr )
    if( alias == NULL ) {
        alias = CarveAlloc( carveSrcFile );
        *alias = *srcFile;
        alias->name = name;
        alias->parent = srcFile->parent;
        alias->sister = srcFile->sister;
        alias->alias = TRUE;
        srcFile->sister = alias;
    }
    set_srcFile( alias );
    activeSrc()->line = line;
}

static void popSrcFile( SRCFILE srcfile, OPEN_FILE *act )
{
    RingPush( &freeFiles, act );
    srcfile->active = NULL;
    set_srcFile( srcfile->parent );
}

boolean SrcFileClose(           // CLOSE A SOURCE FILE
    boolean shutdown )          // - shutdown in progress
{
    SRCFILE tmp_src;            // - extra SRCFILE
    SRCFILE old_src;            // - SRCFILE being closed
    OPEN_FILE *act;             // - open-file information
    LINE_NO lines_read;         // - number of lines read from file
    boolean retn;               // - return: TRUE ==> not EOF
    boolean browsed;            // - TRUE ==> file was browsed

    if( CompFlags.scanning_c_comment ) {
        SrcFileCurrentLocation();
        CErr1( ERR_INCOMPLETE_COMMENT );
    }
    old_src = srcFile;
    browsed = FALSE;
    act = old_src->active;
    if( NULL != act->fp ) {
        SrcFileFClose( act->fp );
        act->fp = NULL;
        browsed = TRUE;
    }
    {
        SRCFILE actual;

        actual = old_src;
        _FIND_ACTUAL( actual );
        switch( actual->guard_state ) {
        case GUARD_BOT:
            if( actual->ifndef_name != NULL ) {
                actual->guard_state = GUARD_IFNDEF;
            } else {
                actual->guard_state = GUARD_IF;
            }
            break;
        case GUARD_IF:
        case GUARD_INCLUDE:
            break;
        default:
            actual->guard_state = GUARD_INCLUDE;
        }
    }
    if( old_src->cmdline ) {
        popSrcFile( old_src, act );
        CurrChar = LCHR_EOF;
        retn = FALSE;
    } else {
        lines_read = act->line - 1;
        if( old_src->parent == NULL ) {
            if( shutdown ) {
                popSrcFile( old_src, act );
                browsed = FALSE;
            }
            SrcLineCount += lines_read;
            CurrChar = LCHR_EOF;
            retn = FALSE;
        } else {
            popSrcFile( old_src, act );
            act = activeSrc();
            IncLineCount += lines_read;
            CurrChar = act->currc;
            if( CompFlags.cpp_output ) {
                if( IsSrcFilePrimary( srcFile )
                 && act->line == 0
                 && act->column == 0 ) {
                    // just completed -fi inclusion file
                    PpStartFile();
                    act->line = 0;
                }
                EmitLineNL( old_src->parent_locn, srcFile->name );
            }
            retn = TRUE;
        }
    }
    if( browsed ) {
        BrinfCloseSource( old_src );
    }
    if( srcFile != NULL && srcFile->pch_create ) {
        // turn off before pchdr is created!
        tmp_src = srcFile->pch_child;
        srcFile->pch_child = NULL;
        srcFile->pch_create = FALSE;
        SrcFileCurrentLocation();
        PCHeaderCreate( tmp_src->name );
    }
    return retn;
}


char *SrcFileName(              // GET NAME OF SOURCE FILE
    SRCFILE sf )                // - source file
{
    char *name;                 // - name

    if( sf == NULL ) {
        if( srcFile == NULL ) {
            name = NULL;
        } else {
            name = srcFile->name;
        }
    } else {
        name = sf->name;
    }
    return name;
}

char *SrcFileFullName(          // GET FULL PATH NAME OF SOURCE FILE
    SRCFILE sf )                // - source file
{
    char *p;
    auto char buff[_MAX_PATH];

    if( sf->full_name != NULL ) {
        return( sf->full_name );
    }
    p = IoSuppFullPath( SrcFileName( sf ), buff, _MAX_PATH );
    sf->full_name = FNameAdd( p );
    return( sf->full_name );
}


char *SrcFileNameCurrent(       // GET NAME OF CURRENT SOURCE FILE
    void )
{
    return SrcFileName( srcFile );
}


LINE_NO SrcFileLine(            // GET CURRENT SOURCE LINE
    void )
{
    return activeSrc()->line;
}


void SrcFileSetErrLoc(          // SET TEMPORARY ERROR LOCATION TO CURRENT POS
    void )
{
    OPEN_FILE *act;
    auto TOKEN_LOCN tmp_locn;

    act = activeSrc();
    tmp_locn.src_file = srcFile;
    tmp_locn.line = act->line;
    tmp_locn.column = act->column;
    SetErrLoc( &tmp_locn );
}


void SrcFileCurrentLocation(    // SET LOCATION FOR CURRENT SOURCE FILE
    void )
{
    OPEN_FILE *act;

    act = activeSrc();
    TokenLine = act->line;
    TokenColumn = act->column;
}


static boolean readBuffer(      // READ NEXT BUFFER
    boolean close_top_file )    // - TRUE ==> close top file
{
    OPEN_FILE *act;             // - open file
    SRCFILE src_file;           // - unaliased source file
    int amt_read;               // - amount read

    act = activeSrc();
    for(;;) {
        src_file = srcFile;
        _FIND_ACTUAL( src_file );
        if( src_file->uncached ) {
            act->fp = SrcFileFOpen( src_file->name, SFO_SOURCE_FILE );
            src_file->uncached = FALSE;
            if( act->fp == NULL ) {
                CErr( ERR_IO_ERR, src_file->name, strerror( errno ) );
            } else {
                SysSeek( fileno( act->fp ), act->pos );
            }
        }
        if( act->fp != NULL ) {
            if( close_top_file ) {
                close_top_file = FALSE;
            } else {
                act->nextc = &act->buff[0];
                if( src_file->found_eof ) {
                    src_file->found_eof = FALSE;
                    amt_read = 0;
                    DbgAssert( !( SysRead( fileno( act->fp )
                                        , act->nextc
                                        , PRODUCTION_BUFFER_SIZE ) > 0 ) );
                } else {
                    amt_read = SysRead( fileno( act->fp )
                                        , act->nextc
                                        , PRODUCTION_BUFFER_SIZE );
                }
                if( amt_read > 0 ) {
                    if( amt_read < PRODUCTION_BUFFER_SIZE ) {
                        if( src_file->assume_file ) {
                            src_file->found_eof = TRUE;
                        }
                    }
                    // mark end of buffer
                    act->lastc = &act->buff[ amt_read ];
                    *(act->lastc) = '\0';
                    /* CurrChar not set; must read buffer */
                    return( FALSE );
                }
                if( amt_read == 0 ) {
                    // we're at the end of the file
                    if( src_file->pch_kludge ) {
                        // only do this once
                        src_file->pch_kludge = FALSE;
                        if( src_file->assume_file ) {
                            // make sure next time we return EOF
                            src_file->found_eof = TRUE;
                        }
                        // these three ';'s form the end of the pre-compiled
                        // header file so that the parser will be in a good
                        // state.  REWRITE.C caused a problem when a template
                        // was at the end of the header file and it tried to
                        // read one more token to make sure it had all of the
                        // tokens for the template definition.
                        // NYI: we should verify the parser is in a good state
                        // in case people try to pre-compile header files that
                        // split declarations across multiple files (rare)
                        act->buff[0] = ';';
                        act->buff[1] = ';';
                        act->buff[2] = ';';
                        act->buff[3] = '\0';
                        act->lastc = &act->buff[3];
                        if( CurrChar != '\n' ) {
                            // terminate the last line (if necessary)
                            CurrChar = '\n';
                            return( TRUE );
                        }
                        /* CurrChar not set; must read buffer */
                        return( FALSE );
                    }
                    if( CurrChar != '\n' ) {
                        // file didn't end with a new-line
                        if( src_file->assume_file ) {
                            // make sure next time we return EOF
                            src_file->found_eof = TRUE;
                        }
                        act->buff[0] = '\0';
                        act->lastc = &act->buff[0];
                        CurrChar = '\n';
                        return( TRUE );
                    }
                } else if( amt_read == -1 ) {
                    CErr( ERR_IO_ERR, src_file->name, strerror( errno ) );
                }
            }
        }
        if( ! SrcFileClose( FALSE ) ) {
            /* CurrChar set to LCHR_EOF */
            return( TRUE );
        }
        act = activeSrc();
        if( act->nextc < act->lastc ) {
            /* CurrChar set to ->lastc */
            return( TRUE );
        }
        if( act->nextc == act->lastc ) {
            /* CurrChar not set; must read buffer ('\0' will be the char) */
            return( FALSE );
        }
    }
}

static int getTestCharFromFile( OPEN_FILE **pact )
{
    OPEN_FILE *act;
    int c;

    DbgAssert( *pact == activeSrc() );  // NYI: is always true we can optimize
    for(;;) {
        act = activeSrc();
        c = *act->nextc++;
        if( c != '\0' ) {
            break;
        }
        // '\0' in the middle of the buffer must be processed as a char
        if( act->nextc != ( act->lastc + 1 ) ) break;
        if( readBuffer( getGuardState() == GUARD_IFNDEF ) ) {
            c = CurrChar;
            break;
        }
    }
    *pact = activeSrc();
    return( c );
}

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

    act = activeSrc();
    c = getTestCharFromFile( &act );
    // should we do this for a multi-byte char?
    act->column++;
    NextChar = GetNextChar;
    CurrChar = c;
    return( c );
}

static int getCharCheck( OPEN_FILE *act, int c );

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

    // column for 'lastChar' has not been set yet
    act = activeSrc();
    NextChar = GetNextChar;
    c = lastChar;
    if( c == '?' ) {
        act->column++;
        CurrChar = c;
        return( c );
    }
    return( getCharCheck( act, c ) );
}

static int doFlushWS( void )
{
    char c;

    // columns for whitespace have not been set yet
    c = '\0';
    if( numBlanks1 != 0 ) {
        --numBlanks1;
        c = ' ';
    } else if( numTABs != 0 ) {
        --numTABs;
        c = '\t';
    } else if( numBlanks2 != 0 ) {
        --numBlanks2;
        c = ' ';
    }
    return( c );
}

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

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

static int getCharAfterTwoQuestion( void )

⌨️ 快捷键说明

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