srcfile.c

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

C
2,229
字号
boolean SrcFileProcessOnce(     // CHECK WHETHER WE HAVE TO OPEN THE FILE
    char *name )
{
    SRCFILE old;                // - existing SRCFILE

    old = srcFileGetUnique( name );
    if( old != NULL ) {
        if( old->once_only ) {
            return( TRUE );
        }
        if( old->guard_state == GUARD_IFNDEF ) {
            if( MacroExists( old->ifndef_name, old->ifndef_len ) ) {
                return( TRUE );
            }
        }
    }
    return( FALSE );
}


//---------------------------------------------------------------------------
// The following routines permit the standard SrcFile interface to be
// employed while scanning characters from a command-line buffer.
//---------------------------------------------------------------------------


void SrcFileCmdLnDummyOpen(     // OPEN DUMMY FILE FOR COMMAND LINE
    void )
{
    SRCFILE cmd_file;           // - command file

    cmd_file = srcFileAlloc( NULL, NULL );
    cmd_file->cmdline = TRUE;
    setGuardState( GUARD_IFNDEF );
}


void SrcFileCmdLnDummyClose(    // CLOSE DUMMY FILE FOR COMMAND LINE
    void )
{
    SRCFILE cmd_file;           // - command file

    cmd_file = srcFile;
    SrcFileClose( FALSE );
//  CarveFree( carveSrcFile, cmd_file );
}


int SrcFileCmdLnGetChar(        // GET NEXT CHARACTER FOR CMD-LINE FILE
    void )
{
    int return_eol;             // - TRUE => return end of line
    int next_char;              // - next character
    SRCFILE sf;                 // - source file for command line

    sf = srcFile;
    if( sf->cmdlneof ) {
        next_char = LCHR_EOF;
    } else if( sf->cmdlneol ) {
        next_char = '\n';
        sf->cmdlneof = TRUE;
    } else {
        if( sf->ignore_swend ) {
            return_eol = CmdScanBufferEnd();
        } else {
            return_eol = CmdScanSwEnd();
        }
        if( return_eol ) {
            sf->cmdlneol = TRUE;
            next_char = '\r';
        } else {
            next_char = CmdScanChar();
        }
    }
    CurrChar = next_char;
    return next_char;
}


void SrcFileTraceBack(          // INDICATE SRCFILE USED IN TRACE-BACK
    SRCFILE sf )                // - source-file in message
{
    traced_back = sf;
}


boolean SrcFileTraceBackReqd(   // DETERMINE IF MSG TRACE-BACK REQ'D
    SRCFILE sf )                // - source-file in message
{
    return (sf != NULL ) && ( sf != traced_back );
}


SRCFILE SrcFileTraceBackFile(   // GET SRCFILE TRACED BACK
    void )
{
    return traced_back;
}

boolean SrcFileSame(            // ARE THESE SRC FILES THE SAME FILE?
    SRCFILE f1,                 // - src-file 1
    SRCFILE f2 )                // - src-file 2
{
    _FIND_ACTUAL( f1 );
    _FIND_ACTUAL( f2 );
    return( f1 == f2 );
}


unsigned SrcFileIndex(          // GET INDEX OF THIS SRCFILE
    SRCFILE sf )                // - the source file
{
    return sf->index;
}


static boolean srcFileCacheClose( boolean close_all_ok )
{
    SRCFILE curr;
    SRCFILE last;
    SRCFILE multiple_cached;
    OPEN_FILE *uncache;
    OPEN_FILE *active;

    multiple_cached = NULL;
    last = NULL;
    for( curr = srcFile; curr != NULL; curr = curr->parent ) {
        if( curr->uncached ) {
            continue;
        }
        active = curr->active;
        if( active == NULL ) {
            continue;
        }
        if( active->fp == stdin ) {
            continue;
        }
        multiple_cached = last;
        last = curr;
    }
    if( last == NULL ) {
        return( FALSE );
    }
    if( multiple_cached == NULL && !close_all_ok ) {
        return( FALSE );
    }
    _FIND_ACTUAL( last );
    last->uncached = TRUE;
    uncache = last->active;
    uncache->pos = SysTell( fileno( uncache->fp ) );
    SrcFileFClose( uncache->fp );
    uncache->fp = NULL;
    return( TRUE );
}


static boolean recursiveIncludeDetected( char *name )
{
    SRCFILE curr;

    for( curr = srcFile; curr != NULL; curr = curr->parent ) {
        if( ! MacroStateMatchesCurrent( &(curr->macro_state) ) ) {
            /* any open before this will never match */
            break;
        }
        if( strcmp( name, curr->name ) == 0 ) {
            CErr2p( ERR_RECURSIVE_FILE_INCLUDE, name );
            return( TRUE );
        }
    }
    return( FALSE );
}


FILE *SrcFileFOpen( char *name, src_file_open kind )
{
    FILE *fp;
    char *mode;
    static char *file_kind[] = { "rb", "r", "rb", "w", "wb" };

    mode = file_kind[ kind ];
    for(;;) {
        fp = fopen( name, mode );
        if( fp != NULL ) {
            if( recursiveIncludeDetected( name ) ) {
                fclose( fp );
                fp = NULL;
            }
            break;
        }
        if( errno != ENOMEM && errno != ENFILE && errno != EMFILE ) break;
        if( ! srcFileCacheClose( kind == SFO_SOURCE_FILE ) ) break;
    }
    return( fp );
}

int SrcFileFClose( FILE *fp )
{
    if( fp == stdin ) return( 0 );
    return( fclose( fp ) );
}

static void markFreeSrcFile( void *p )
{
    SRCFILE s = p;

    s->free = TRUE;
}

static void saveSrcFile( void *e, carve_walk_base *d )
{
    SRCFILE sister_save;
    SRCFILE parent_save;
    SRCFILE unique_save;
    OPEN_FILE *active_save;
    char *name_save;
    char *ifndef_save;
    size_t name_len;
    size_t ifndef_len;
    SRCFILE s = e;

    if( s->free ) {
        return;
    }
    sister_save = s->sister;
    s->sister = SrcFileGetIndex( sister_save );
    parent_save = s->parent;
    s->parent = SrcFileGetIndex( parent_save );
    unique_save = s->unique;
    s->unique = SrcFileGetIndex( unique_save );
    active_save = s->active;
    s->active = NULL;
    name_save = s->name;
    ifndef_save = s->ifndef_name;
    name_len = 0;
    if( name_save != NULL ) {
        name_len = strlen( name_save ) + 1;
    }
    s->name = (char *) name_len;
    ifndef_len = 0;
    if( ifndef_save != NULL ) {
        ifndef_len = s->ifndef_len + 1;
    }
    s->ifndef_name = (char *) ifndef_len;
    PCHWriteCVIndex( d->index );
    PCHWrite( s, sizeof( *s ) );
    if( name_len != 0 ) {
        PCHWrite( name_save, name_len );
    }
    if( ifndef_len != 0 ) {
        PCHWrite( ifndef_save, ifndef_len );
    }
    s->sister = sister_save;
    s->parent = parent_save;
    s->unique = unique_save;
    s->active = active_save;
    s->name = name_save;
    s->ifndef_name = ifndef_save;
}

static void writeRoDirs( void )
{
    DIR_LIST *curr;
    unsigned len;

    RingIterBeg( roDirs, curr ) {
        len = strlen( curr->name ) + 1;
        PCHWriteUInt( len );
        PCHWrite( curr->name, len );
    } RingIterEnd( curr );
    PCHWriteUInt( 0 );
}

pch_status PCHWriteSrcFiles( void )
{
    SRCFILE unique_srcfiles;
    cv_index terminator = CARVE_NULL_INDEX;
    auto carve_walk_base dsrc;

    unique_srcfiles = SrcFileGetIndex( srcFilesUnique );
    PCHWrite( &unique_srcfiles, sizeof( unique_srcfiles ) );
    CarveWalkAllFree( carveSrcFile, markFreeSrcFile );
    CarveWalkAll( carveSrcFile, saveSrcFile, &dsrc );
    PCHWriteCVIndex( terminator );
    writeRoDirs();
    return( PCHCB_OK );
}

static void readRoDirs( void )
{
    unsigned len;
    char *dirname;
    auto char buff[_MAX_PATH];

    for(;;) {
        len = PCHReadUInt();
        if( len == 0 ) break;
        dirname = PCHReadLocate( buff, len );
        addRoDir( dirname );
    }
}

pch_status PCHReadSrcFiles( void )
{
    SRCFILE unique_srcfiles;
    char *buff;
    size_t buff_len;
    SRCFILE s;
    SRCFILE n;
    cv_index si;
    size_t name_len;
    size_t ifndef_len;
    auto cvinit_t data;

    // primarySrcFile will already be set properly so it is unaffected by PCH
    PCHRead( &unique_srcfiles, sizeof( unique_srcfiles ) );
    unique_srcfiles = SrcFileMapIndex( unique_srcfiles );
    buff_len = 80;
    buff = CMemAlloc( buff_len );
    CarveInitStart( carveSrcFile, &data );
    for(;;) {
        si = PCHReadCVIndex();
        if( si == CARVE_NULL_INDEX ) break;
        s = CarveInitElement( &data, si );
        PCHRead( s, sizeof( *s ) );
        s->sister = SrcFileMapIndex( s->sister );
        s->parent = SrcFileMapIndex( s->parent );
        s->unique = SrcFileMapIndex( s->unique );
        s->active = NULL;
        s->full_name = NULL;
        MacroStateClear( &(s->macro_state) );
        name_len = (size_t) s->name;
        if( name_len != 0 ) {
            if( name_len > buff_len ) {
                CMemFree( buff );
                buff_len = name_len;
                buff = CMemAlloc( buff_len );
            }
            PCHRead( buff, name_len );
            s->name = FNameAdd( buff );
        } else {
            s->name = NULL;
        }
        ifndef_len = (size_t) s->ifndef_name;
        if( ifndef_len != 0 ) {
            if( ifndef_len > buff_len ) {
                CMemFree( buff );
                buff_len = ifndef_len;
                buff = CMemAlloc( buff_len );
            }
            PCHRead( buff, ifndef_len );
            s->ifndef_name = strpermsave( buff );
        } else {
            s->ifndef_name = NULL;
        }
    }
    for( s = unique_srcfiles; s != NULL; s = n ) {
        n = s->unique;
        if( ! IsSrcFilePrimary( s ) ) {
            srcFileAddUnique( s );
        }
    }
    CMemFree( buff );
    readRoDirs();
    return( PCHCB_OK );
}

SRCFILE SrcFileGetIndex( SRCFILE e )
{
    return( CarveGetIndex( carveSrcFile, e ) );
}

SRCFILE SrcFileMapIndex( SRCFILE e )
{
    return( CarveMapIndex( carveSrcFile, e ) );
}

pch_status PCHInitSrcFiles( boolean writing )
{
    cv_index n;

    if( writing ) {
        n = CarveLastValidIndex( carveSrcFile );
        PCHWriteCVIndex( n );
    } else {
        alternateCarveSrcFile = carveSrcFile;
        carveSrcFile = CarveCreate( sizeof( *srcFile ), BLOCK_SRCFILE );
        n = PCHReadCVIndex();
        CarveMapOptimize( carveSrcFile, n );
    }
    return( PCHCB_OK );
}

pch_status PCHFiniSrcFiles( boolean writing )
{
    if( !writing ) {
        carve_t tmp;

        tmp = carveSrcFile;
        carveSrcFile = alternateCarveSrcFile;
        CarveMapUnoptimize( tmp );
        alternateCarveSrcFile = tmp;
    }
    return( PCHCB_OK );
}

void SrcFileSetTab( unsigned tab )
{
    switch( tab ) {
    case 1:
    case 2:
    case 4:
    case 8:
    case 16:
        tabWidth = tab;
        break;
    }
}

void SrcFileOnceOnly(           // CURRENT SRCFILE CAN BE SKIPPED IF #INCLUDE AGAIN
    void )
{
    SRCFILE srcfile;            // - current source file

    srcfile = srcFile;
    if( srcfile != NULL ) {
        srcfile->once_only = TRUE;
    }
}

void SrcFileSetSwEnd(           // SET CURRENT SRCFILE IGNORE CMDLINE SW END STATUS
    boolean val )               // - value to use to set status
{
    SRCFILE srcfile;            // - current source file

    srcfile = srcFile;
    if( srcfile != NULL && srcfile->cmdline ) {
        if( val ) {
            srcfile->ignore_swend = TRUE;
        } else {
            srcfile->ignore_swend = FALSE;
        }
    }
}

⌨️ 快捷键说明

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