idedrv.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 818 行 · 第 1/2 页
C
818 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Driver for DLLs pluggable into the IDE (and wmake).
*
****************************************************************************/
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "idedll.h"
#include "idedrv.h"
#include "walloca.h"
#ifndef USE_RUNYOURSELF_ARGV
#if defined(__UNIX__)
#define USE_RUNYOURSELF_ARGV
#endif
#endif
#if defined( __OS2__ ) || defined( __NT__ )
//
// DLLs implemented only for:
// OS/2 (386, PowerPC)
// NT (386, Alpha AXP, PowerPC)
// you can use link in the dll objects into the stub in other os's
//(eg dos--if you consider that an os) by defining STATIC_LINKAGE
// and IDE_PGM. note that IDE_PGM needs to be defined anywhere that
// IDEDLL_EXPORT is used and/or idedll.h is included
#if defined( __OS2__ ) && !defined( __OSI__ )
#define DLLS_IMPLEMENTED
// The following are defined in os2.h
#undef COMMENT
#define ERR OS2_ERR
#define INCL_DOS
#include "os2.h"
#define IDETOOL_GETVER "_IDEGetVersion@0"
#define IDETOOL_INITDLL "_IDEInitDLL@12"
#define IDETOOL_RUNSELF "_IDERunYourSelf@12"
#define IDETOOL_RUNSELF_ARGV "_IDERunYourSelf@16"
#define IDETOOL_FINIDLL "_IDEFiniDLL@4"
#define IDETOOL_STOPRUN "_IDEStopRunning@0"
#define IDETOOL_INITINFO "_IDEPassInitInfo@8"
#undef ERR
typedef HMODULE DLL_HANDLE;
#elif defined( __NT__ )
#define DLLS_IMPLEMENTED
#include <windows.h>
#define IDETOOL_GETVER "_IDEGetVersion@0"
#define IDETOOL_INITDLL "_IDEInitDLL@12"
#define IDETOOL_RUNSELF "_IDERunYourSelf@12"
#define IDETOOL_RUNSELF_ARGV "_IDERunYourSelf@16"
#define IDETOOL_FINIDLL "_IDEFiniDLL@4"
#define IDETOOL_STOPRUN "_IDEStopRunning@0"
#define IDETOOL_INITINFO "_IDEPassInitInfo@8"
typedef HINSTANCE DLL_HANDLE;
#else
#include "bool.h"
#endif
#ifdef DLLS_IMPLEMENTED
typedef unsigned IDEDLL_EXPORT (*GetVerFn)( void );
typedef IDEBool IDEDLL_EXPORT (*InitDllFn)( IDECBHdl hdl
, IDECallBacks *cb
, IDEDllHdl *info );
typedef IDEBool IDEDLL_EXPORT (*RunSelfFn)( IDEDllHdl hdl
, const char *opts
, IDEBool *fatalerr );
typedef IDEBool IDEDLL_EXPORT (*RunSelfFnArgv)( IDEDllHdl hdl
, int
, char **argv
, IDEBool *fatalerr );
typedef void IDEDLL_EXPORT (*FiniDllFn)( IDEDllHdl hdl );
typedef void IDEDLL_EXPORT (*StopRunFn)( void );
typedef IDEBool IDEDLL_EXPORT (*PassInitInfo)( IDEDllHdl hdl
, IDEInitInfo *info );
#endif
#else
#include "bool.h"
#endif
#if (defined DLLS_IMPLEMENTED || (defined STATIC_LINKAGE && defined IDE_PGM) )
typedef void (*P_FUN)( void );
#ifndef STATIC_LINKAGE
#ifdef __OS2__
//
// OS/2 Interface
//
static int sysdepDLLLoad( IDEDRV *inf )
{
#define SIZE 32
unsigned char badfile[SIZE];
return (int)DosLoadModule( (PSZ)badfile
, sizeof( badfile )
, (PSZ)inf->dll_name
, (DLL_HANDLE *)&inf->dll_handle );
}
static int sysdepDLLUnload( IDEDRV *inf )
{
DosFreeModule( (DLL_HANDLE)inf->dll_handle );
return( 0 ); // sometimes get failure in good situations
}
static int sysdepDLLgetProc( IDEDRV *inf
, char const *fun_name
, P_FUN *fun )
{
int retcode;
retcode = (int)DosQueryProcAddr( (DLL_HANDLE)inf->dll_handle
, 0
, (PSZ)fun_name
, (PFN *)fun );
if( 0 != retcode ) {
// DLL could be linked case-insensitive
unsigned size = strlen( fun_name ) + 1;
char *p = alloca( size );
p = memcpy( p, fun_name, size );
p = strupr( p );
retcode = (int)DosQueryProcAddr( (DLL_HANDLE)inf->dll_handle
, 0
, (PSZ)p
, (PFN *)fun );
}
return( retcode );
}
#endif // __OS2__
#ifdef __NT__
//
// NT Interface
//
static int sysdepDLLLoad( IDEDRV *inf )
{
inf->dll_handle = (void *)LoadLibrary( inf->dll_name );
return( 0 == inf->dll_handle );
}
static int sysdepDLLUnload( IDEDRV *inf )
{
return( !(int)FreeLibrary( (DLL_HANDLE)inf->dll_handle ) );
}
static int sysdepDLLgetProc( IDEDRV *inf,
char const *fun_name,
P_FUN *fun )
{
P_FUN fp = (P_FUN)GetProcAddress( (DLL_HANDLE)inf->dll_handle, fun_name );
*fun = fp;
return( 0 == fp );
}
#endif // __NT__
#endif // STATIC_LINKAGE
typedef int (*USER_DLL_FUN)( char const * );
typedef int (*USER_DLL_FUN_ARGV)( int, char ** );
#ifndef CHAIN_CALLBACK
static IDEBool __stdcall stubPrintMsgFn( IDECBHdl hdl, char const *msg )
{
hdl = hdl;
#ifndef NDEBUG
fputs( "stubPrintMsgFn called!\n", errout );
fputs( msg, errout );
fputc( '\n', errout );
#else
msg = msg;
#endif
return( FALSE );
}
#ifndef NDEBUG
static void __stdcall printProgressIndex( IDECBHdl hdl, unsigned index )
{
hdl = hdl;
fprintf( errout, "progress: %u\n", index );
}
#else
#define printProgressIndex NULL
#endif
static IDEBool __stdcall printMessage( IDECBHdl hdl, char const *msg )
{
hdl = hdl;
fputs( msg, errout );
fputc( '\n', errout );
return( FALSE );
}
static IDEBool __stdcall printWithInfo( IDECBHdl hdl, IDEMsgInfo *inf )
{
FILE *fp;
char prt_buffer[ 512 ];
hdl = hdl;
IdeMsgFormat( hdl
, inf
, prt_buffer
, sizeof( prt_buffer )
, &printWithInfo );
switch( inf->severity ) {
case IDEMSGSEV_BANNER:
case IDEMSGSEV_DEBUG:
case IDEMSGSEV_NOTE_MSG:
fp = stdout;
break;
case IDEMSGSEV_WARNING:
case IDEMSGSEV_ERROR:
case IDEMSGSEV_NOTE:
default:
fp = errout;
}
fputs( prt_buffer, fp );
fputc( '\n', fp );
fflush( fp );
return( FALSE );
}
static IDEBool __stdcall printWithCrLf( IDECBHdl hdl, const char *message )
{
hdl = hdl;
fputs( message, errout );
fflush( errout );
return( FALSE );
}
static IDEBool __stdcall getInfoCB( IDECBHdl hdl, IDEInfoType type,
unsigned long extra, unsigned long lparam )
{
int retn;
extra = extra;
hdl = hdl;
switch( type ) {
default:
retn = TRUE;
break;
case IDE_GET_ENV_VAR:
{ char const* env_var;
char const* env_val;
char const * * p_env_val;
env_var = (char const*)extra;
env_val = getenv( env_var );
p_env_val = (char const * *)lparam;
*p_env_val = env_val;
retn = ( env_val == NULL );
} break;
}
return( retn );
}
static IDECallBacks callbacks = { // CALL-BACK STRUCTURE
// building functions
NULL, // RunBatch
printMessage, // PrintMessage
printWithCrLf, // PrintWithCRLF
printWithInfo, // PrintWithInfo
// Query functions
getInfoCB, // GetInfo
stubPrintMsgFn, // ProgressMessage
NULL, // RunDll
NULL, // RunBatchCWD
NULL, // OpenJavaSource
NULL, // OpenClassFile
NULL, // PackageExists
NULL, // GetSize
NULL, // GetTimeStamp
NULL, // IsReadOnly
NULL, // ReadData
NULL, // Close
NULL, // ReceiveOutput
printProgressIndex, // ProgressIndex
};
static IDECallBacks *CBPtr = &callbacks;
#else
static IDECallBacks *CBPtr = NULL;
#endif
static IDEInitInfo info = // INFORMATION STRUCTURE
{ IDE_CUR_INFO_VER // - ver
, 0 // - ignore_env
, 1 // - cmd_line_has_files
, 0 // - console_output
, 0 // - progress messages
, 0 // - progress index
};
static IDEInitInfo *InfoPtr = NULL;
#ifndef STATIC_LINKAGE
static IDEDRV *Inf;
#endif
#ifdef __OSI__
#define NO_CTRL_HANDLERS
#endif
#ifndef NO_CTRL_HANDLERS
static void StopRunning( void )
{
// Provide static and dynamic linking
#ifdef STATIC_LINKAGE
IDEStopRunning();
#else
StopRunFn idestopdll;
int retcode;
retcode = sysdepDLLgetProc( Inf, IDETOOL_STOPRUN, (P_FUN*)&idestopdll );
if( IDEDRV_SUCCESS == retcode ) {
idestopdll();
}
#endif
}
#endif // NO_CTRL_HANDLERS
#ifndef NO_CTRL_HANDLERS
static void intHandler( int sig_num )
{
sig_num = sig_num;
StopRunning();
}
#endif // NO_CTRL_HANDLERS
static void initInterrupt( void )
{
#ifndef NO_CTRL_HANDLERS
signal( SIGINT, intHandler );
#ifndef __UNIX__
signal( SIGBREAK, intHandler );
#endif // __UNIX__
#endif // NO_CTRL_HANDLERS
}
static void finiInterrupt( void )
{
#ifndef NO_CTRL_HANDLERS
signal( SIGINT, SIG_DFL );
#ifndef __UNIX__
signal( SIGBREAK, SIG_DFL );
#endif // __UNIX__
#endif // NO_CTRL_HANDLERS
}
#ifndef NDEBUG
#define _SET_PROGRESS \
if( getenv( "__idedrv_progress_messages" ) ) { info.progress_messages = 1; } \
if( getenv( "__idedrv_progress_index" ) ) { info.progress_index = 1; }
#else
#define _SET_PROGRESS
#endif
#ifdef STATIC_LINKAGE
static int ensureLoaded( IDEDRV *inf, int *p_runcode )
{
int runcode = 0;
int retcode = IDEDRV_SUCCESS;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?