idedrv.c

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

C
818
字号

    if( !inf->loaded ) {
        if( NULL == inf->ent_name ) {
            runcode = IDEInitDLL( NULL
                                , CBPtr
                                , &inf->ide_handle );
            if( 0 == runcode ) {
                if( InfoPtr == NULL ) {
                    InfoPtr = &info;
                    info.console_output = isatty( fileno( stdout ) );
                }
                _SET_PROGRESS;
                runcode = IDEPassInitInfo( inf->ide_handle, InfoPtr );
                if( 0 != runcode ) {
                    retcode = IDEDRV_ERR_INFO_EXEC;
                }
            } else {
                retcode = IDEDRV_ERR_INIT_EXEC;
            }
        }
        if( IDEDRV_SUCCESS == retcode ) {
            inf->loaded = TRUE;
        }
    }
    *p_runcode = runcode;
    return( retcode );
}
#else
static int ensureLoaded( IDEDRV *inf, int *p_runcode )
{
    int runcode = 0;
    int retcode = IDEDRV_SUCCESS;

    if( ! inf->loaded ) {
        retcode = sysdepDLLLoad( inf );
        if( IDEDRV_SUCCESS == retcode ) {
            if( NULL == inf->ent_name ) {
                InitDllFn initdll;
                retcode = sysdepDLLgetProc( inf
                                          , IDETOOL_INITDLL
                                          , (P_FUN *)&initdll );
                if( IDEDRV_SUCCESS == retcode ) {
                    runcode = initdll( NULL , CBPtr, &inf->ide_handle );
                    if( 0 == runcode ) {
                        PassInitInfo initinfo;
                        retcode = sysdepDLLgetProc( inf
                                                  , IDETOOL_INITINFO
                                                  , (P_FUN *)&initinfo );
                        if( IDEDRV_SUCCESS == retcode ) {
                            if( InfoPtr == NULL ) {
                                InfoPtr = &info;
                                info.console_output = isatty( fileno(stdout) );
                            }
                            _SET_PROGRESS;
                            runcode = initinfo( inf->ide_handle, InfoPtr );
                            if( 0 != runcode ) {
                                retcode = IDEDRV_ERR_INFO_EXEC;
                            }
                        } else {
                            retcode = IDEDRV_ERR_INFO;
                        }
                    } else {
                        retcode = IDEDRV_ERR_INIT_EXEC;
                    }
                } else {
                    retcode = IDEDRV_ERR_INIT;
                }
                if( IDEDRV_SUCCESS != retcode ) {
                    sysdepDLLUnload( inf );
                }
            }
        } else {
            retcode = IDEDRV_ERR_LOAD;
        }
        if( IDEDRV_SUCCESS == retcode ) {
            inf->loaded = TRUE;
        }
    }
    *p_runcode = runcode;
    return( retcode );
}
#endif

static int retcodeFromFatal( IDEBool fatal, int runcode, int retcode )
{
    if( fatal ) {
        retcode = IDEDRV_ERR_RUN_FATAL;
    } else if( 0 != runcode ) {
        retcode = IDEDRV_ERR_RUN_EXEC;
    }
    return( retcode );
}

static void initConsole( void )
{
    if( info.console_output ) {
        initInterrupt();
    }
}

static void finiConsole( void )
{
    if( info.console_output ) {
        finiInterrupt();
    }
}

#define stashCodes( _inf, _run, _ret ) \
    (_inf)->dll_status = (_run); (_inf)->drv_status = (_ret);

int IdeDrvExecDLL               // EXECUTE THE DLL ONE TIME (LOAD IF REQ'D)
    ( IDEDRV *inf               // - driver control information
    , char const *cmd_line )    // - command line
#ifdef STATIC_LINKAGE
// Execute DLL
//
// One mode (with static linkage):
//
//  (1) WATCOM IDE interface is used.
//
{
    int runcode;
    int retcode;

    retcode = ensureLoaded( inf, &runcode );
    if( retcode == IDEDRV_SUCCESS ) {
        IDEBool fatal = FALSE;
        initConsole();
        runcode = IDERunYourSelf( inf->ide_handle, cmd_line, &fatal );
        finiConsole();
        retcode = retcodeFromFatal( fatal, runcode, retcode );
    }
    stashCodes( inf, runcode, retcode );
    return( retcode );
}
#else
// Execute DLL
//
// Two modes (both with dynamic linkage):
//
//  (1) when second parameter is NULL, WATCOM IDE interface is used.
//
//  (2) otherwise, the dll is called at the entry name
//
{
    int runcode;
    int retcode;

    Inf = inf;
    retcode = ensureLoaded( inf, &runcode );
    if( retcode == IDEDRV_SUCCESS ) {
        if( NULL == inf->ent_name ) {
            RunSelfFn fun;
            retcode = sysdepDLLgetProc( inf, IDETOOL_RUNSELF, (P_FUN *)&fun );
            if( IDEDRV_SUCCESS == retcode ) {
                IDEBool fatal = FALSE;
                initConsole();
                runcode = fun( inf->ide_handle, cmd_line, &fatal );
                finiConsole();
                retcode = retcodeFromFatal( fatal, runcode, retcode );
                if( retcode == IDEDRV_ERR_RUN_FATAL ) {
                    sysdepDLLUnload( inf );
                    inf->loaded = FALSE;
                }
            } else {
                retcode = IDEDRV_ERR_RUN;
            }
        } else {
            USER_DLL_FUN fun;
            retcode = sysdepDLLgetProc( inf, inf->ent_name, (P_FUN *)&fun );
            if( IDEDRV_SUCCESS == retcode ) {
                initConsole();
                runcode = fun( cmd_line );
                finiConsole();
                retcode = retcodeFromFatal( FALSE, runcode, retcode );
            } else {
                retcode = IDEDRV_ERR_RUN;
            }
        }
    }
    stashCodes( inf, runcode, retcode );
    return( retcode );
}
#endif

#ifdef __UNIX__

int IdeDrvExecDLLArgv           // EXECUTE THE DLL ONE TIME (LOAD IF REQ'D)
    ( IDEDRV *inf               // - driver control information
    , int argc                  // - # of arguments
    , char **argv )             // - argument vector
#ifdef STATIC_LINKAGE
// Execute DLL
//
// One mode (with static linkage):
//
//  (1) WATCOM IDE interface is used.
//
{
    int runcode;
    int retcode;

    retcode = ensureLoaded( inf, &runcode );
    if( retcode == IDEDRV_SUCCESS ) {
        IDEBool fatal = FALSE;
        initConsole();
        runcode = IDERunYourSelfArgv( inf->ide_handle, argc, argv, &fatal );
        finiConsole();
        retcode = retcodeFromFatal( fatal, runcode, retcode );
    }
    stashCodes( inf, runcode, retcode );
    return( retcode );
}
#else
// Execute DLL
//
// Two modes (both with dynamic linkage):
//
//  (1) when second parameter is NULL, WATCOM IDE interface is used.
//
//  (2) otherwise, the dll is called at the entry name
//
{
    int runcode;
    int retcode;

    Inf = inf;
    retcode = ensureLoaded( inf, &runcode );
    if( retcode == IDEDRV_SUCCESS ) {
        if( NULL == inf->ent_name ) {
            RunSelfFnArgv fun;
            retcode = sysdepDLLgetProc( inf, IDETOOL_RUNSELF_ARGV, (P_FUN *)&fun );
            if( IDEDRV_SUCCESS == retcode ) {
                IDEBool fatal = FALSE;
                initConsole();
                runcode = fun( inf->ide_handle, argc, argv, &fatal );
                finiConsole();
                retcode = retcodeFromFatal( fatal, runcode, retcode );
                if( retcode == IDEDRV_ERR_RUN_FATAL ) {
                    sysdepDLLUnload( inf );
                    inf->loaded = FALSE;
                }
            } else {
                retcode = IDEDRV_ERR_RUN;
            }
        } else {
            USER_DLL_FUN_ARGV fun;
            retcode = sysdepDLLgetProc( inf, inf->ent_name, (P_FUN *)&fun );
            if( IDEDRV_SUCCESS == retcode ) {
                initConsole();
                runcode = fun( argc, argv );
                finiConsole();
                retcode = retcodeFromFatal( FALSE, runcode, retcode );
            } else {
                retcode = IDEDRV_ERR_RUN;
            }
        }
    }
    stashCodes( inf, runcode, retcode );
    return( retcode );
}
#endif

#endif


int IdeDrvUnloadDLL             // UNLOAD THE DLL
    ( IDEDRV *inf )             // - driver control information
#ifdef STATIC_LINKAGE
// Static Linkage: nothing to unload
{
    if( inf->loaded ) {
        inf->loaded = FALSE;
        IDEFiniDLL( inf->ide_handle );
    }
    return( IDEDRV_SUCCESS );
}
#else
// Dynamic Linkage: unload the DLL
{
    int         retcode;                // - return code
    FiniDllFn   fini;

    if( inf->loaded ) {
        retcode = sysdepDLLgetProc( inf, IDETOOL_FINIDLL, (P_FUN*)&fini );
        if( IDEDRV_SUCCESS == retcode ) {
            fini( inf->ide_handle );
        }
        inf->loaded = FALSE;
        if( 0 == sysdepDLLUnload( inf ) ) {
            retcode = IDEDRV_SUCCESS;
        } else {
            retcode = IDEDRV_ERR_UNLOAD;
        }
    } else {
        retcode = IDEDRV_SUCCESS;
    }
    return( retcode );
}
#endif


int IdeDrvStopRunning           // SIGNAL A BREAK
    ( IDEDRV *inf )             // - driver control information
#ifdef STATIC_LINKAGE
// Static Linkage: direct call
{
    if( inf->loaded ) {
        inf->loaded = FALSE;
        IDEStopRunning();
    }
    return( IDEDRV_SUCCESS );
}
#else
// Dynamic Linkage: indirect call
{
    int         retcode;                // - return code
    StopRunFn   idestopdll;

    if( inf->loaded ) {
        retcode = sysdepDLLgetProc( inf, IDETOOL_STOPRUN, (P_FUN*)&idestopdll );
        if( IDEDRV_SUCCESS == retcode ) {
           idestopdll();
        }
    } else {
        retcode = IDEDRV_SUCCESS;
    }
    return( retcode );
}
#endif


static char const *msgs[] =
{
#define _IDEDRV(e,m) m
__IDEDRV
#undef _IDEDRV
};


int IdeDrvPrintError            // UNLOAD THE DLL
    ( IDEDRV *inf )             // - driver control information
{
    char const  *msg;
    int         retcode = inf->drv_status;

    if( retcode != IDEDRV_SUCCESS ) {
        if( retcode <= 0 || retcode >= IDEDRV_ERR_MAXIMUM ) {
            msg = "impossible error";
        } else {
            msg = msgs[ retcode ];
        }
        fputs( "ERROR with dll: ", errout );
        fputs( inf->dll_name, errout );
        fputs( "\n    ", errout );
        fputs( msg, errout );
        if( inf->dll_status != 0 ) {
            char    buf[32];

            fputs( "    return code: ", errout );
            itoa( inf->dll_status, buf, 10 );
            fputs( buf, errout );
        }
        fputc( '\n', errout );
        fflush( errout );
    }
    return( inf->drv_status );
}

void IdeDrvChainCallbacks       // SET CALLBACKS FOR DLL CALLLING A DLL
    ( void *cb                  // - parent dll callbacks
    , void *info )              // - parent dll initialization
{
    CBPtr   = (IDECallBacks *)cb;
    InfoPtr = (IDEInitInfo *)info;
}

void *IdeDrvGetCallbacks                // GET CALLBACKS
    ( void )
{
    return( (void *)CBPtr );
}

void IdeDrvSetCallbacks         // GET CALLBACKS
    ( void *cb )
{
    CBPtr = (IDECallBacks *)cb;
}


void IdeDrvInit                 // INITIALIZE IDEDRV INFORMATION
    ( IDEDRV *inf               // - information
    , char const *dll_name      // - dll name
    , char const *ent_name )    // - entry name
{
    inf->dll_name   = dll_name;
    inf->ent_name   = ent_name;
    inf->ide_handle = 0;
    inf->dll_handle = 0;
    inf->drv_status = 0;
    inf->dll_status = 0;
    inf->loaded     = 0;
}


#else
    #error IDE not implemented for target platform
#endif // DLLS_IMPLEMENTED

⌨️ 快捷键说明

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