2008-03-30 11:00:12 -04:00
/************************************************
stubs . c - Tcl / Tk stubs support
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "ruby.h"
2005-07-28 05:14:59 -04:00
# include "stubs.h"
# include <tcl.h>
# include <tk.h>
/*------------------------------*/
# ifdef __MACOS__
# include <tkMac.h>
# include <Quickdraw.h>
static int call_macinit = 0 ;
static void
_macinit ( )
{
if ( ! call_macinit ) {
tcl_macQdPtr = & qd ; /* setup QuickDraw globals */
Tcl_MacSetEventProc ( TkMacConvertEvent ) ; /* setup event handler */
call_macinit = 1 ;
}
}
# endif
/*------------------------------*/
2003-08-17 10:40:00 -04:00
2005-08-04 05:41:57 -04:00
static int nativethread_checked = 0 ;
static void
_nativethread_consistency_check ( ip )
Tcl_Interp * ip ;
{
if ( nativethread_checked | | ip = = ( Tcl_Interp * ) NULL ) {
return ;
}
2005-11-06 23:47:08 -05:00
/* If the variable "tcl_platform(threaded)" exists,
then the Tcl interpreter was compiled with threads enabled . */
if ( Tcl_GetVar2 ( ip , " tcl_platform " , " threaded " , TCL_GLOBAL_ONLY ) ! = ( char * ) NULL ) {
2005-08-04 05:41:57 -04:00
# ifdef HAVE_NATIVETHREAD
/* consistent */
# else
rb_warn ( " Inconsistency. Loaded Tcl/Tk libraries are enabled nativethread-support. But `tcltklib' is not. The inconsistency causes SEGV or other troubles frequently. " ) ;
# endif
} else {
# ifdef HAVE_NATIVETHREAD
rb_warning ( " Inconsistency.`tcltklib' is enabled nativethread-support. But loaded Tcl/Tk libraries are not. (Probably, the inconsistency doesn't cause any troubles.) " ) ;
# else
/* consistent */
# endif
}
Tcl_ResetResult ( ip ) ;
nativethread_checked = 1 ;
}
/*------------------------------*/
2000-08-08 01:06:24 -04:00
# if defined USE_TCL_STUBS && defined USE_TK_STUBS
2001-05-28 12:07:34 -04:00
# if defined _WIN32 || defined __CYGWIN__
2002-11-09 03:05:27 -05:00
# include "util.h"
2000-08-08 01:06:24 -04:00
# include <windows.h>
typedef HINSTANCE DL_HANDLE ;
# define DL_OPEN LoadLibrary
# define DL_SYM GetProcAddress
# define TCL_INDEX 4
# define TK_INDEX 3
# define TCL_NAME "tcl89%s"
# define TK_NAME "tk89%s"
# undef DLEXT
# define DLEXT ".dll"
# elif defined HAVE_DLOPEN
# include <dlfcn.h>
typedef void * DL_HANDLE ;
# define DL_OPEN(file) dlopen(file, RTLD_LAZY|RTLD_GLOBAL)
# define DL_SYM dlsym
# define TCL_INDEX 8
# define TK_INDEX 7
# define TCL_NAME "libtcl8.9%s"
# define TK_NAME "libtk8.9%s"
# endif
2005-07-28 05:14:59 -04:00
static DL_HANDLE tcl_dll = ( DL_HANDLE ) 0 ;
static DL_HANDLE tk_dll = ( DL_HANDLE ) 0 ;
2003-08-18 12:24:42 -04:00
2000-08-08 01:06:24 -04:00
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_open_tcl_dll ( char * appname )
2008-03-30 11:00:12 -04:00
# else
ruby_open_tcl_dll ( appname )
char * appname ;
# endif
2000-08-08 01:06:24 -04:00
{
2004-08-18 04:14:54 -04:00
void ( * p_Tcl_FindExecutable ) ( const char * ) ;
2000-08-08 01:06:24 -04:00
int n ;
2002-10-10 04:30:52 -04:00
char * ruby_tcl_dll = 0 ;
2000-08-08 01:06:24 -04:00
char tcl_name [ 20 ] ;
2005-07-28 05:14:59 -04:00
if ( tcl_dll ) return TCLTK_STUBS_OK ;
2000-08-08 01:06:24 -04:00
ruby_tcl_dll = getenv ( " RUBY_TCL_DLL " ) ;
* configure.in, defines.h, dir.c, dir.h, dln.c, error.c,
eval.c, file.c, hash.c, io.c, main.c, missing.c,
process.c, ruby.c, rubysig.h, signal.c, st.c, util.c, util.h,
bcc/Makefile.sub, win32/Makefile.sub, win32/win32.h,
ext/Win32API/Win32API.c, ext/socket/getaddrinfo.c,
ext/socket/getnameinfo.c, ext/socket/socket.c,
ext/tcltklib/stubs.c
: replace "NT" with "_WIN32", add DOSISH_DRIVE_LETTER
* wince/exe.mak : delete \r at the end of lines.
* wince/mswince-ruby17.def : delete rb_obj_become
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3148 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2002-12-14 22:18:08 -05:00
# if defined _WIN32
2002-07-30 02:34:27 -04:00
if ( ruby_tcl_dll ) ruby_tcl_dll = ruby_strdup ( ruby_tcl_dll ) ;
# endif
2005-07-28 05:14:59 -04:00
if ( ruby_tcl_dll ) {
2004-10-11 00:51:21 -04:00
tcl_dll = ( DL_HANDLE ) DL_OPEN ( ruby_tcl_dll ) ;
2000-08-08 01:06:24 -04:00
} else {
2004-10-11 00:51:21 -04:00
snprintf ( tcl_name , sizeof tcl_name , TCL_NAME , DLEXT ) ;
/* examine from 8.9 to 8.1 */
for ( n = ' 9 ' ; n > ' 0 ' ; n - - ) {
tcl_name [ TCL_INDEX ] = n ;
tcl_dll = ( DL_HANDLE ) DL_OPEN ( tcl_name ) ;
2005-07-28 05:14:59 -04:00
if ( tcl_dll )
2004-10-11 00:51:21 -04:00
break ;
}
2000-08-08 01:06:24 -04:00
}
* configure.in, defines.h, dir.c, dir.h, dln.c, error.c,
eval.c, file.c, hash.c, io.c, main.c, missing.c,
process.c, ruby.c, rubysig.h, signal.c, st.c, util.c, util.h,
bcc/Makefile.sub, win32/Makefile.sub, win32/win32.h,
ext/Win32API/Win32API.c, ext/socket/getaddrinfo.c,
ext/socket/getnameinfo.c, ext/socket/socket.c,
ext/tcltklib/stubs.c
: replace "NT" with "_WIN32", add DOSISH_DRIVE_LETTER
* wince/exe.mak : delete \r at the end of lines.
* wince/mswince-ruby17.def : delete rb_obj_become
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3148 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2002-12-14 22:18:08 -05:00
# if defined _WIN32
2002-10-10 04:30:52 -04:00
if ( ruby_tcl_dll ) ruby_xfree ( ruby_tcl_dll ) ;
# endif
2005-07-28 05:14:59 -04:00
if ( ! tcl_dll )
return NO_TCL_DLL ;
2000-08-08 01:06:24 -04:00
2004-08-18 04:14:54 -04:00
p_Tcl_FindExecutable = ( void ( * ) ( const char * ) ) DL_SYM ( tcl_dll , " Tcl_FindExecutable " ) ;
if ( ! p_Tcl_FindExecutable )
2005-07-28 05:14:59 -04:00
return NO_FindExecutable ;
2004-08-18 04:14:54 -04:00
2005-07-28 05:14:59 -04:00
if ( appname ) {
p_Tcl_FindExecutable ( appname ) ;
} else {
p_Tcl_FindExecutable ( " ruby " ) ;
}
2004-08-18 04:14:54 -04:00
2005-07-28 05:14:59 -04:00
return TCLTK_STUBS_OK ;
}
2000-08-08 01:06:24 -04:00
2005-07-28 05:14:59 -04:00
int
ruby_open_tk_dll ( )
{
int n ;
char * ruby_tk_dll = 0 ;
char tk_name [ 20 ] ;
2000-08-08 01:06:24 -04:00
2005-07-28 05:14:59 -04:00
if ( ! tcl_dll ) {
2006-08-31 07:56:42 -04:00
/* int ret = ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */
int ret = ruby_open_tcl_dll ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2005-07-28 05:14:59 -04:00
if ( ret ! = TCLTK_STUBS_OK ) return ret ;
}
if ( tk_dll ) return TCLTK_STUBS_OK ;
ruby_tk_dll = getenv ( " RUBY_TK_DLL " ) ;
if ( ruby_tk_dll ) {
tk_dll = ( DL_HANDLE ) DL_OPEN ( ruby_tk_dll ) ;
} else {
snprintf ( tk_name , sizeof tk_name , TK_NAME , DLEXT ) ;
/* examine from 8.9 to 8.1 */
for ( n = ' 9 ' ; n > ' 0 ' ; n - - ) {
tk_name [ TK_INDEX ] = n ;
tk_dll = ( DL_HANDLE ) DL_OPEN ( tk_name ) ;
if ( tk_dll )
break ;
}
}
if ( ! tk_dll )
return NO_TK_DLL ;
return TCLTK_STUBS_OK ;
}
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_open_tcltk_dll ( char * appname )
2008-03-30 11:00:12 -04:00
# else
ruby_open_tcltk_dll ( appname )
char * appname ;
# endif
2005-07-28 05:14:59 -04:00
{
return ( ruby_open_tcl_dll ( appname ) | | ruby_open_tk_dll ( ) ) ;
}
int
tcl_stubs_init_p ( )
{
return ( tclStubsPtr ! = ( TclStubs * ) NULL ) ;
}
int
tk_stubs_init_p ( )
{
return ( tkStubsPtr ! = ( TkStubs * ) NULL ) ;
}
Tcl_Interp *
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tcl_create_ip_and_stubs_init ( int * st )
2008-03-30 11:00:12 -04:00
# else
ruby_tcl_create_ip_and_stubs_init ( st )
int * st ;
# endif
2005-07-28 05:14:59 -04:00
{
2005-08-04 05:41:57 -04:00
Tcl_Interp * tcl_ip ;
2005-07-28 05:14:59 -04:00
if ( st ) * st = 0 ;
if ( tcl_stubs_init_p ( ) ) {
2005-08-04 05:41:57 -04:00
tcl_ip = Tcl_CreateInterp ( ) ;
if ( ! tcl_ip ) {
if ( st ) * st = FAIL_CreateInterp ;
return ( Tcl_Interp * ) NULL ;
}
_nativethread_consistency_check ( tcl_ip ) ;
return tcl_ip ;
2005-07-28 05:14:59 -04:00
} else {
Tcl_Interp * ( * p_Tcl_CreateInterp ) ( ) ;
Tcl_Interp * ( * p_Tcl_DeleteInterp ) ( ) ;
if ( ! tcl_dll ) {
2006-08-31 07:56:42 -04:00
/* int ret = ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */
int ret = ruby_open_tcl_dll ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2006-04-18 04:43:10 -04:00
2005-07-28 05:14:59 -04:00
if ( ret ! = TCLTK_STUBS_OK ) {
if ( st ) * st = ret ;
return ( Tcl_Interp * ) NULL ;
}
}
p_Tcl_CreateInterp
= ( Tcl_Interp * ( * ) ( ) ) DL_SYM ( tcl_dll , " Tcl_CreateInterp " ) ;
if ( ! p_Tcl_CreateInterp ) {
if ( st ) * st = NO_CreateInterp ;
return ( Tcl_Interp * ) NULL ;
}
p_Tcl_DeleteInterp
= ( Tcl_Interp * ( * ) ( ) ) DL_SYM ( tcl_dll , " Tcl_DeleteInterp " ) ;
if ( ! p_Tcl_DeleteInterp ) {
if ( st ) * st = NO_DeleteInterp ;
return ( Tcl_Interp * ) NULL ;
}
tcl_ip = ( * p_Tcl_CreateInterp ) ( ) ;
if ( ! tcl_ip ) {
if ( st ) * st = FAIL_CreateInterp ;
return ( Tcl_Interp * ) NULL ;
}
if ( ! Tcl_InitStubs ( tcl_ip , " 8.1 " , 0 ) ) {
if ( st ) * st = FAIL_Tcl_InitStubs ;
( * p_Tcl_DeleteInterp ) ( tcl_ip ) ;
return ( Tcl_Interp * ) NULL ;
}
2005-11-06 07:48:43 -05:00
_nativethread_consistency_check ( tcl_ip ) ;
2005-07-28 05:14:59 -04:00
return tcl_ip ;
}
}
int
ruby_tcl_stubs_init ( )
{
int st ;
Tcl_Interp * tcl_ip ;
if ( ! tcl_stubs_init_p ( ) ) {
tcl_ip = ruby_tcl_create_ip_and_stubs_init ( & st ) ;
if ( ! tcl_ip ) return st ;
Tcl_DeleteInterp ( tcl_ip ) ;
}
return TCLTK_STUBS_OK ;
}
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tk_stubs_init ( Tcl_Interp * tcl_ip )
2008-03-30 11:00:12 -04:00
# else
ruby_tk_stubs_init ( tcl_ip )
Tcl_Interp * tcl_ip ;
# endif
2005-07-28 05:14:59 -04:00
{
Tcl_ResetResult ( tcl_ip ) ;
if ( tk_stubs_init_p ( ) ) {
if ( Tk_Init ( tcl_ip ) = = TCL_ERROR ) {
return FAIL_Tk_Init ;
}
} else {
int ( * p_Tk_Init ) ( Tcl_Interp * ) ;
if ( ! tk_dll ) {
int ret = ruby_open_tk_dll ( ) ;
if ( ret ! = TCLTK_STUBS_OK ) return ret ;
}
p_Tk_Init = ( int ( * ) ( Tcl_Interp * ) ) DL_SYM ( tk_dll , " Tk_Init " ) ;
if ( ! p_Tk_Init )
return NO_Tk_Init ;
if ( ( * p_Tk_Init ) ( tcl_ip ) = = TCL_ERROR )
return FAIL_Tk_Init ;
if ( ! Tk_InitStubs ( tcl_ip , " 8.1 " , 0 ) )
return FAIL_Tk_InitStubs ;
# ifdef __MACOS__
_macinit ( ) ;
# endif
}
return TCLTK_STUBS_OK ;
}
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tk_stubs_safeinit ( Tcl_Interp * tcl_ip )
2008-03-30 11:00:12 -04:00
# else
ruby_tk_stubs_safeinit ( tcl_ip )
Tcl_Interp * tcl_ip ;
# endif
2005-07-28 05:14:59 -04:00
{
Tcl_ResetResult ( tcl_ip ) ;
if ( tk_stubs_init_p ( ) ) {
if ( Tk_SafeInit ( tcl_ip ) = = TCL_ERROR )
return FAIL_Tk_Init ;
} else {
int ( * p_Tk_SafeInit ) ( Tcl_Interp * ) ;
if ( ! tk_dll ) {
int ret = ruby_open_tk_dll ( ) ;
if ( ret ! = TCLTK_STUBS_OK ) return ret ;
}
p_Tk_SafeInit = ( int ( * ) ( Tcl_Interp * ) ) DL_SYM ( tk_dll , " Tk_SafeInit " ) ;
if ( ! p_Tk_SafeInit )
return NO_Tk_Init ;
if ( ( * p_Tk_SafeInit ) ( tcl_ip ) = = TCL_ERROR )
return FAIL_Tk_Init ;
if ( ! Tk_InitStubs ( tcl_ip , " 8.1 " , 0 ) )
return FAIL_Tk_InitStubs ;
# ifdef __MACOS__
_macinit ( ) ;
# endif
}
return TCLTK_STUBS_OK ;
}
2000-08-08 01:06:24 -04:00
2005-07-28 05:14:59 -04:00
int
ruby_tcltk_stubs ( )
{
int st ;
Tcl_Interp * tcl_ip ;
2006-08-31 07:56:42 -04:00
/* st = ruby_open_tcltk_dll(RSTRING_PTR(rb_argv0)); */
st = ruby_open_tcltk_dll ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2005-07-28 05:14:59 -04:00
switch ( st ) {
case NO_FindExecutable :
return - 7 ;
case NO_TCL_DLL :
case NO_TK_DLL :
return - 1 ;
}
tcl_ip = ruby_tcl_create_ip_and_stubs_init ( & st ) ;
if ( ! tcl_ip ) {
switch ( st ) {
case NO_CreateInterp :
case NO_DeleteInterp :
return - 2 ;
case FAIL_CreateInterp :
return - 3 ;
case FAIL_Tcl_InitStubs :
return - 5 ;
}
}
st = ruby_tk_stubs_init ( tcl_ip ) ;
switch ( st ) {
case NO_Tk_Init :
Tcl_DeleteInterp ( tcl_ip ) ;
return - 4 ;
case FAIL_Tk_Init :
case FAIL_Tk_InitStubs :
Tcl_DeleteInterp ( tcl_ip ) ;
2004-10-11 00:51:21 -04:00
return - 6 ;
2005-07-28 05:14:59 -04:00
}
2000-08-08 01:06:24 -04:00
Tcl_DeleteInterp ( tcl_ip ) ;
return 0 ;
}
2005-07-28 05:14:59 -04:00
/*###################################################*/
# else /* ! USE_TCL_STUBS || ! USE_TK_STUBS) */
/*###################################################*/
static int open_tcl_dll = 0 ;
static int call_tk_stubs_init = 0 ;
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_open_tcl_dll ( char * appname )
2008-03-30 11:00:12 -04:00
# else
ruby_open_tcl_dll ( appname )
char * appname ;
# endif
2005-07-28 05:14:59 -04:00
{
if ( appname ) {
Tcl_FindExecutable ( appname ) ;
} else {
Tcl_FindExecutable ( " ruby " ) ;
}
open_tcl_dll = 1 ;
return TCLTK_STUBS_OK ;
}
2008-03-30 11:00:12 -04:00
int
ruby_open_tk_dll ( )
2005-07-28 05:14:59 -04:00
{
if ( ! open_tcl_dll ) {
2006-08-31 07:56:42 -04:00
/* ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */
ruby_open_tcl_dll ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2005-07-28 05:14:59 -04:00
}
return TCLTK_STUBS_OK ;
}
2008-03-30 11:00:12 -04:00
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2008-03-30 11:00:12 -04:00
ruby_open_tcltk_dll ( char * appname )
# else
ruby_open_tcltk_dll ( appname )
char * appname ;
# endif
2005-07-28 05:14:59 -04:00
{
return ( ruby_open_tcl_dll ( appname ) | | ruby_open_tk_dll ( ) ) ;
}
int
tcl_stubs_init_p ( )
{
return 1 ;
}
int
tk_stubs_init_p ( )
{
return call_tk_stubs_init ;
}
Tcl_Interp *
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tcl_create_ip_and_stubs_init ( int * st )
2008-03-30 11:00:12 -04:00
# else
ruby_tcl_create_ip_and_stubs_init ( st )
int * st ;
# endif
2005-07-28 05:14:59 -04:00
{
Tcl_Interp * tcl_ip ;
if ( ! open_tcl_dll ) {
2006-08-31 07:56:42 -04:00
/* ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */
ruby_open_tcl_dll ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2005-07-28 05:14:59 -04:00
}
if ( st ) * st = 0 ;
tcl_ip = Tcl_CreateInterp ( ) ;
if ( ! tcl_ip ) {
if ( st ) * st = FAIL_CreateInterp ;
return ( Tcl_Interp * ) NULL ;
}
2005-08-04 05:41:57 -04:00
_nativethread_consistency_check ( tcl_ip ) ;
2005-07-28 05:14:59 -04:00
return tcl_ip ;
}
int
ruby_tcl_stubs_init ( )
{
return TCLTK_STUBS_OK ;
}
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tk_stubs_init ( Tcl_Interp * tcl_ip )
2008-03-30 11:00:12 -04:00
# else
ruby_tk_stubs_init ( tcl_ip )
Tcl_Interp * tcl_ip ;
# endif
2005-07-28 05:14:59 -04:00
{
if ( Tk_Init ( tcl_ip ) = = TCL_ERROR )
return FAIL_Tk_Init ;
if ( ! call_tk_stubs_init ) {
# ifdef __MACOS__
_macinit ( ) ;
# endif
call_tk_stubs_init = 1 ;
}
return TCLTK_STUBS_OK ;
}
int
2008-06-11 11:56:22 -04:00
# ifdef HAVE_PROTOTYPES
2006-06-20 14:02:17 -04:00
ruby_tk_stubs_safeinit ( Tcl_Interp * tcl_ip )
2008-03-30 11:00:12 -04:00
# else
ruby_tk_stubs_safeinit ( tcl_ip )
Tcl_Interp * tcl_ip ;
# endif
2005-07-28 05:14:59 -04:00
{
# if TCL_MAJOR_VERSION >= 8
if ( Tk_SafeInit ( tcl_ip ) = = TCL_ERROR )
return FAIL_Tk_Init ;
if ( ! call_tk_stubs_init ) {
# ifdef __MACOS__
_macinit ( ) ;
# endif
call_tk_stubs_init = 1 ;
}
return TCLTK_STUBS_OK ;
# else /* TCL_MAJOR_VERSION < 8 */
return FAIL_Tk_Init ;
# endif
}
int
ruby_tcltk_stubs ( )
{
2006-08-31 07:56:42 -04:00
/* Tcl_FindExecutable(RSTRING_PTR(rb_argv0)); */
Tcl_FindExecutable ( rb_argv0 ? RSTRING_PTR ( rb_argv0 ) : 0 ) ;
2005-07-28 05:14:59 -04:00
return 0 ;
}
2000-08-08 01:06:24 -04:00
# endif