fcenable.c

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

C
609
字号
            LinkList( &ExcludeList, ExEntry );
            ExcludeState = EX_NONE;
            return( TRUE );     // want a list separator after this.
        }
    }
    return( FALSE );
}

static void ProcessOption( char ***argv )
/***************************************/
{
    char *  item;
    char    option;

    NewOption = TRUE;
    (**argv)++;        // skip the switch character.
    item = **argv;
    option = tolower( *item );
    switch( option ) {
    case 'c':           // class list.
        ProcList( ProcClass, argv );
        break;
    case 's':
        ProcList( ProcSeg, argv );
        break;
    case 'x':
        ProcList( ProcExclude, argv );
        break;
    case 'b':
        MakeBackup = FALSE;
        (*argv)++;
        break;
    default:
        put( "option not recognized: " );
        putlen( item, 1 );
        put( "\n" );
        (*argv)++;
    }
}

static void ProcessFiles( char **argv )
/*************************************/
{
    char *  item;

    while( *argv != NULL ) {
        item = *argv;
        if( *item == '-' || *item == '/' ) {
            ProcessOption( &argv );
        } else {
            put( "Processing file '" );
            put( item );
            put( "'\n" );
            ProcFile( item );
            argv++;
        }
    }
}

static void CloseFiles( void )
/****************************/
{
    if( InFile != NOFILE ) {
        close( InFile );
        InFile = NOFILE;
    }
    if( OutFile != NOFILE ) {
        close( OutFile );
        OutFile = NOFILE;
    }
}

static void ReplaceExt( char * name, char * new_ext, BYTE force )
/***************************************************************/
{
    char        buff[ _MAX_PATH2 ];
    char *      p;
    char *      d;
    char *      n;
    char *      e;

    _splitpath2( name, buff, &d, &p, &n, &e );
    if( force || e[0] == '\0' ) {
        strcpy( e, new_ext );
        _makepath( name, d, p, n, e );
    }
}

static void DoReplace( void )
/***************************/
// this supports concatenated object decks and libraries (PageLen != 0)
{
    FlushBuffer();
    if( PageLen != 0 ) {         // NYI - spawning WLIB every time is
        close( OutFile );       // rather slow. Replace this somehow??
        OutFile = NOFILE;
        if( spawnlp( P_WAIT, "WLIB.EXE", "WLIB.EXE", TEMP_LIB_NAME, "/b",
                                      "+" TEMP_OBJ_NAME, NULL ) != 0 ) {
            Error( "problem with temporary library" );
        }
        QRemove( TEMP_OBJ_NAME );
    }
}

static void ProcFile( char * fname )
/**********************************/
{
    int         ftype;
    char *      name;
    int         status;
    int         namelen;
    char *      bak;

    namelen = strlen( fname ) + 5;
    name = alloca( namelen );
    if( name == NULL ) Suicide();           // null == no stack space left.
    strcpy( name, fname );
    ReplaceExt( name, ".obj", FALSE );
    InFile = QOpen( name, O_RDONLY | O_BINARY, 0 );
    for(;;) {
        CleanRecStuff();
        ftype = ReadRec();
        if( ftype == ENDLIBRARY || ftype == ENDFILE ) {
            break;
        } else if( ftype == LIBRARY ) {
            Warning( "exclude option does not apply to libraries" );
            FreeList( ExcludeList );
            ExcludeList = NULL;
        } else if( ftype != OBJECT ) {
            Error( "file is not a standard OBJECT or LIBRARY file" );
        }
        OutFile = QOpen( TEMP_OBJ_NAME, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0 );
        do {
            ProcessRec();
            status = ReadRec();
        } while( status == OK );
        if( status == ENDMODULE ) {
            ProcessRec();           // process the modend rec.
            DoReplace();
        } else {
            Error( "premature end of file encountered" );
        }
        FreeList( ExcludeList );    // do this here so concatenated .obj files
        ExcludeList = NULL;         // only have the first module excluded.
    }
    CloseFiles();
    if( MakeBackup ) {
        bak = alloca( namelen );
        if( bak == NULL ) Suicide();           // null == no stack space left.
        strcpy( bak, name );
        if( ftype == ENDLIBRARY ) {
            ReplaceExt( bak, ".bak", TRUE );
        } else {
            ReplaceExt( bak, ".bob", TRUE );
        }
        CopyFile( name, bak );
    }
    QRemove( name );
    if( ftype == ENDLIBRARY ) {
        rename( TEMP_LIB_NAME, name );
    } else {
        rename( TEMP_OBJ_NAME, name );
    }
    FileCleanup();
}

int CopyFile( char * file1, char * file2 )
/****************************************/
{
    int len;
    auto struct stat            statblk;
    auto struct utimbuf         utimebuf;

    remove( file2 );
    OutFile = NOFILE;
    InFile = QOpen( file1, O_RDONLY | O_BINARY, 0 );
    OutFile = QOpen( file2, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0 );
    for( ;; ) {
        len = QRead( InFile, Rec1, MAX_OBJECT_REC_SIZE );
        if( len == 0 ) break;
        QWrite( OutFile, Rec1, len );
    }
    CloseFiles();
    if( stat( file1, &statblk ) == 0 ) {
        utimebuf.actime = statblk.st_atime;
        utimebuf.modtime = statblk.st_mtime;
        utime( file2, &utimebuf );
    }
    return( OK );
}

extern void put( char * str )
/***************************/
{
    write( STDOUT_HANDLE, str, strlen( str ) );
}

extern void putlen( char *str, int len )
/**************************************/
{
    write( STDOUT_HANDLE, str, len );
}

// these are utility routines used frequently in TDCVT.

typedef struct _node {      // structure used for list traversal routines.
    struct _node *  next;
} node;

extern void LinkList( void **in_head, void *newnode )
/***************************************************/
/* Link a new node into a linked list (new node goes at the end of the list) */
{
    node                **owner;

    owner = in_head;
    while( *owner != NULL ) {
        owner = &(*owner)->next;
    }
    *owner = newnode;
}

extern void FreeList( void *list )
/********************************/
/* Free a list of nodes. */
{
    node *  next_node;
    node *  curr;

    curr = (node *) list;
    while( curr ) {
        next_node = curr->next;
        MemFree( curr );
        curr = next_node;
    }
}

extern void Warning( char * msg )
/*******************************/
{
    put( "warning: " );
    put( msg );
    put( "\n" );
}

extern void Error( char * msg )
/*****************************/
{
    put( "Error: " );
    put( msg );
    put( "\n" );
    Suicide();
}

extern void IOError( char *msg )
/******************************/
{
    put( msg );
    put( ": " );
    put( strerror( errno ) );
    put( "\n" );
    Suicide();
}

// these are the file i/o routines for tdcvt.

extern int QRead( int handle, char *buffer, int len )
/***************************************************/
{
    int result;

    result = read( handle, buffer, len );
    if( result == ERROR ) {
        IOError( "problem reading file" );
    }
    return( result );
}

extern int QWrite( int handle, char *buffer, int len )
/****************************************************/
{
    int result;

    result = write( handle, buffer, len );
    if( result == ERROR ) {
        IOError( "problem writing file" );
    } else if( result != len ) {
        Error( "disk full" );
    }
    return( result );
}

extern long int QSeek( int handle, long offset, int origin )
/**********************************************************/
{
    long int result;

    result = lseek( handle, offset, origin );
    if( result == ERROR ) {
        IOError( "problem during seek" );
    }
    return( result );
}

⌨️ 快捷键说明

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