cmdline.c

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

C
1,052
字号

    if( prompt ) {
        PressKey();
    }
    for( ; first_ln <= last_ln; first_ln++ ) {
        Msg_Get( (int) first_ln, msg_buffer );
        if( previous_null ) {
            if( msg_buffer[0] != '\0' ) {
                PressKey();
                WriteMsg( msg_buffer );
                previous_null = 0;
            } else break;
        } else if( msg_buffer[0] == '\0' ) {
            previous_null = 1;
        } else {
            WriteMsg( msg_buffer );
        }
    }
}

static void PressKey( void )
/**************************/
{
    char        msg_buffer[RESOURCE_MAX_SIZE];
    char        result;

    Msg_Get( MSG_PRESS_KEY, msg_buffer );
    WriteStdOut( msg_buffer );
    result = WaitForKey();
    WriteNLStdOut();
    if( tolower(result) == 'q' ) {
        Ignite();
        Suicide();
    }
}

static void WriteMsg( char msg_buffer[] )
/***************************************/
{
    WriteStdOut( msg_buffer );
    WriteNLStdOut();
}

extern void FreePaths( void )
/***************************/
// Free paths & filenames.
{
    FreeList( Path );
    Path = NULL;
    if( Name != NULL ) {
        _LnkFree( Name );
        Name = NULL;
    }
}

extern void Burn( void )
/**********************/
// necessary to split this out from Ignite() for the workframe options
// processor.
{
    outfilelist *   fnode;

    FreePaths();
    if( MapFName != NULL ) {
        _LnkFree( MapFName );
        MapFName = NULL;
    }
    fnode = OutFiles;
    while( fnode != NULL ) {
        _LnkFree( fnode->fname );
        OutFiles = fnode->next;
        _LnkFree( fnode );
        fnode = OutFiles;
    }
    BurnUtils();
}

extern void Ignite( void )
/************************/
/* free local structures */
{
    BurnSystemList();
    Burn();
}

extern void SetFormat( void )
/***************************/
// do final processing now that the executable format has been decided.
{
    char *      fname;

    if( CmdFlags & CF_NO_EXTENSION ) {
        fname = Name;
    } else {
        int const len = (int) strlen(Name);

        if ( FmtData.output_hex ) {  // override default extension if hex or raw (bin)
            Extension = E_HEX;       //   has been specified
        }
        else if ( FmtData.output_raw ) {
            Extension = E_BIN;
        }
        fname = FileName( Name, len, Extension, CmdFlags & CF_UNNAMED);
        _LnkFree( Name );
    }
    Root->outfile = NewOutFile( fname );
    Name = NULL;
    FillOutFilePtrs();   // fill in all unspecified outfile pointers.
    if( MapFlags & MAP_FLAG ) {
        LnkMsg( MAP+MSG_EXE_NAME, "s", Root->outfile->fname );
        LnkMsg( MAP+MSG_CREATE_EXE, "f" );
    }
#ifdef _QNXLOAD
    if( FmtData.type & MK_QNX ) {
        CmdQNXFini();
    }
#endif
    SetRelocSize();
}

struct select_format {
    exe_format      bits;
    char            *lib_var_name;
    void            (*set_func)(void);
    void            (*free_func)(void);
};

static struct select_format PossibleFmt[] = {
    MK_DOS,         "LIBDOS",       NULL,           NULL,
#ifdef _QNXLOAD
    MK_QNX,         "LIBQNX",       SetQNXFmt,      FreeQNXFmt,
#endif
#ifdef _ELF
    MK_ELF,         "LIBELF",       SetELFFmt,      FreeELFFmt,
#endif
#ifdef _OS2
    MK_WINDOWS,     "LIBWIN",       SetOS2Fmt,      FreeOS2Fmt,
    MK_OS2_NE,      "LIBOS2",       SetOS2Fmt,      FreeOS2Fmt,
    MK_OS2_LE,      "LIBOS2FLAT",   SetOS2Fmt,      FreeOS2Fmt,
    MK_OS2_LX,      "LIBOS2FLAT",   SetOS2Fmt,      FreeOS2Fmt,
    MK_PE,          "LIBPE",        SetOS2Fmt,      FreeOS2Fmt,
    MK_WIN_VXD,     "LIBVXD",       SetOS2Fmt,      FreeOS2Fmt,
#endif
#ifdef _PHARLAP
    MK_PHAR_LAP,    "LIBPHAR",      SetPharFmt,     FreePharFmt,
#endif
#ifdef _NOVELL
    MK_NOVELL,      "LIBNOV",       SetNovFmt,      FreeNovFmt,
#endif
    0 };


extern void AddFmtLibPaths( void )
/********************************/
{
    struct select_format const *check;
    exe_format                  possible;

    if( !(LinkState & FMT_DECIDED) ) return;
    check = PossibleFmt;
    for( ;; ) {
        possible = check->bits;
        if( possible == 0 ) return;
        if( (~possible & FmtData.type) == 0 ) break;
        ++check;
    }
    AddEnvPaths( check->lib_var_name );
}

static void InitFmt( void (*set)(void) )
/**************************************/
{
    if( LinkState & FMT_INITIALIZED ) return;
    if( set != NULL ) set();
    LinkState |= FMT_INITIALIZED;
}

extern bool HintFormat( exe_format hint )
/***************************************/
{
    struct select_format const *check;
    exe_format                  possible;

    if( !(hint & FmtData.type) )
        return( FALSE );
    FmtData.type &= hint;
    if( LinkState & FMT_DECIDED )
        return( TRUE );
    check = PossibleFmt;
    for( ;; ) {
        possible = check->bits;
        if( possible == 0 ) {
#ifdef _OS2
            if( (~(MK_OS2|MK_PE|MK_WIN_VXD) & FmtData.type) == 0 ) {
                /* Windows, OS/2 V1.x, OS/2 V2.x, PE, VxD all
                   want the same structure */
                InitFmt( SetOS2Fmt );
            }
#endif
            return( TRUE );
        }
        if( (~possible & FmtData.type) == 0 )
            break;
        ++check;
    }
    InitFmt( check->set_func );
    LinkState |= FMT_DECIDED;
    if( LinkState & SEARCHING_LIBRARIES )
        AddFmtLibPaths();
    return( TRUE );
}

extern void DecideFormat( void )
/******************************/
{
    exe_format  possible;
    exe_format  allowed;
    char        rc_buff[RESOURCE_MAX_SIZE];

    if( !(LinkState & FMT_DECIDED) ) {
        possible = FmtData.type;
        allowed = MK_OS2_NE | MK_OS2_LX;
        if( !(LinkState & FMT_SEEN_IMPORT_CMT) ) allowed = ~allowed;
        if( (possible & allowed) != 0 ) possible &= allowed;
        HintFormat( possible );
        if( !(LinkState & FMT_DECIDED) ) {
            Msg_Get( MSG_FORMAT_NOT_DECIDED, rc_buff );
            LnkMsg( FTL+MSG_INTERNAL, "s", rc_buff );
        }
    }
}

extern void FreeFormatStuff()
/***************************/
{
    struct select_format const *check;
    exe_format                  possible;

    if( !(LinkState & FMT_DECIDED) ) return;
    check = PossibleFmt;
    for( ;; ) {
        possible = check->bits;
        if( possible == 0 ) return;
        if( (~possible & FmtData.type) == 0 ) break;
        ++check;
    }
    if( check->free_func != NULL ) check->free_func();
}

extern void AddCommentLib( char *ptr, int len, unsigned char priority )
/*********************************************************************/
//  Add a library from a comment record.
{
    file_list * result;

    if( CmdFlags & CF_NO_DEF_LIBS ) return;
    ptr = FileName( ptr, len, E_LIBRARY, FALSE );
    result = AddObjLib( ptr, priority );
    CheckLibTrace( result );
    DEBUG(( DBG_BASE, "library: %s", ptr ));
    _LnkFree( ptr );
}

// we don't need these next two when under workframe
#ifndef APP

extern void AddLibPaths( char *name, int len, bool add_to_front )
/***************************************************************/
{
    path_entry         *newpath;
    file_list const    *libfiles;

    _ChkAlloc( newpath, sizeof( path_entry ) + (size_t) len );
    memcpy( newpath->name, name, (size_t) len );
    newpath->name[len] = '\0';
    if( add_to_front ) {
        newpath->next = LibPath;
        LibPath = newpath;
    } else {
        LinkList( &LibPath, newpath );
    }
    if( LibPath == newpath ) {
        libfiles = ObjLibFiles;
        while( libfiles != NULL ) {
            libfiles->file->path_list = LibPath;
            libfiles = libfiles->next_file;
        }
        libfiles = Root->files;
        while( libfiles != NULL && libfiles->file->flags & INSTAT_USE_LIBPATH ) {
            libfiles->file->path_list = LibPath;
            libfiles = libfiles->next_file;
        }
    }
}

extern void AddEnvPaths( char *envname )
/**************************************/
{
    char * const        val = GetEnvString( envname );
    int                 len;

    if( val == NULL ) return;
    len = (int) strlen( val );
    AddLibPaths( val, len, FALSE );
}

#endif

extern void ExecSystem( char *name )
/**********************************/
/* run a system block with the given name (only called once!)
 * (this is called after the parser has already been stopped */
{
    sysblock *  sys;

    sys = FindSysBlock( name );
    if( sys != NULL ) {
        NewCommandSource( NULL, NULL, ENVIRONMENT ); // the "command line"
        Token.where = ENDOFCMD;     // nothing on this command line
        NewCommandSource( sys->name, sys->commands, SYSTEM ); // input file
        sys->name = NULL;
        while( GetToken( SEP_END, TOK_INCLUDE_DOT ) == FALSE ) {
            if( ProcOne( SysDirectives, SEP_NO, FALSE ) == FALSE ) {
                LnkMsg( LOC+LINE+WRN+MSG_ERROR_IN_SYSTEM_BLOCK, NULL );
                RestoreCmdLine();
                break;
            }
        }
        BurnSystemList();
        BurnUtils();
    }
}

static void CleanSystemList( bool check )
/***************************************/
/* clean up the list of system blocks */
{
    sysblock ** sys;
    sysblock *  next;
    char *      name;

    sys = &SysBlocks;
    while( *sys != NULL ) {
        name = (*sys)->name;
        if( !check
        || (memcmp( "286", name, 4 ) != 0 && memcmp( "386", name, 4) != 0)){
            next = (*sys)->next;
            _LnkFree( name );
            _LnkFree( *sys );
            *sys = next;
        } else {
            sys = &(*sys)->next;
        }
    }
}

extern void PruneSystemList( void )
/*********************************/
/* delete all system blocks except for the "286" and "386" records */
{
    CleanSystemList( TRUE );
}

extern void BurnSystemList( void )
/********************************/
/* delete everything in the system list */
{
    CleanSystemList( FALSE );
}

extern bool ProcImport( void )
/****************************/
{
#if defined( _OS2) || defined( _ELF ) || defined( _NOVELL )
    if( HintFormat( MK_OS2 | MK_PE ) ) {
        return ProcOS2Import();
    } else if( HintFormat( MK_WIN_VXD ) ) {
        return FALSE;
    } else if( HintFormat( MK_ELF ) ) {
        return ProcELFImport();
    } else {
        return ProcNovImport();
    }
#else
    return FALSE;
#endif
}

#if defined(_OS2) || defined(_NOVELL)
extern bool ProcExport( void )
/****************************/
{
#ifdef _OS2
    if( HintFormat( ( MK_OS2 | MK_PE | MK_WIN_VXD ) ) ) {
        return( ProcOS2Export() );
    } else
#endif
#ifdef _NOVELL
            {
        return( ProcNovExport() );
    }
#endif
}
#endif

#if defined( _QNXLOAD ) || defined( _OS2 ) || defined( _ELF )
extern bool ProcNoRelocs( void )
/******************************/
{
#if defined( _QNXLOAD )
    if( HintFormat( MK_QNX ) ) {
        return( ProcQNXNoRelocs() );
    }
#endif
#if defined( _OS2 )
    if( HintFormat( MK_PE ) ) {
        return( ProcPENoRelocs() );
    }
#endif
#if defined( _ELF )
    if( HintFormat( MK_ELF ) ) {
        return( ProcELFNoRelocs() );
    }
#endif
    return( TRUE );
}
#endif

#if defined(_OS2) || defined(_QNXLOAD)
extern bool ProcSegment( void )
/*****************************/
{
#ifdef _OS2
    if( HintFormat( MK_OS2 | MK_PE | MK_WIN_VXD ) ) {
        return( ProcOS2Segment() );
    }
#endif
#ifdef _QNXLOAD
    if( HintFormat( MK_QNX ) ) {
        return( ProcQNXSegment() );
    }
#endif
    return( TRUE );
}
#endif

extern bool ProcAlignment( void )
/*******************************/
{
#if defined( _OS2 ) || defined( _ELF )
    if( HintFormat( MK_OS2_16BIT | MK_OS2_LX | MK_PE ) ) {
        return( ProcOS2Alignment() );
    } else if( HintFormat( MK_ELF ) ) {
        return( ProcELFAlignment() );
    }
#endif
    return( TRUE );
}

extern bool ProcHeapSize( void )
/******************************/
{
#if defined( __QNX__ )
    if( HintFormat( MK_QNX ) ) {
        return( ProcQNXHeapSize() );
    }
#endif
#ifdef _OS2
    if( HintFormat( MK_OS2 | MK_PE ) ) {
        return( ProcOS2HeapSize() );
    }
#endif
#if defined( _QNXLOAD ) && !defined( __QNX__ )
    if( HintFormat( MK_QNX ) ) {
        return( ProcQNXHeapSize() );
    }
#endif
    return( TRUE );
}

#ifndef APP
#if defined(_PHARLAP) || defined(_QNXLOAD) || defined(_OS2)
extern bool ProcOffset( void )
/****************************/
{
    if( !GetLong( &FmtData.base ) ) return( FALSE );
    if( !(FmtData.type & (MK_PHAR_LAP|MK_QNX_FLAT)) ) {
        ChkBase( 64 * 1024 );
    } else if( !(FmtData.type & (MK_OS2_FLAT|MK_PE)) ) {
        ChkBase( 4 * 1024 );
    }
    return( TRUE );
}
#endif
#endif

#ifdef _INT_DEBUG
extern bool ProcXDbg( void )
/**************************/
/* process DEBUG command */
{
    char        value[7];

    if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
        if( Token.len > 6 ) {
            return( FALSE );
        } else {
            memcpy( value, Token.this, Token.len );
            value[Token.len] = '\0';
            Debug = strtoul( value, NULL, 0 );
            DEBUG(( DBG_BASE, "debugging info type = %x", Debug ));
        }
        return( TRUE );
    } else {
        return( FALSE );
    }
}

extern bool ProcIntDbg( void )
/****************************/
{
    LinkState |= INTERNAL_DEBUG;
    return TRUE;
}
#endif

⌨️ 快捷键说明

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