Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / regina / wrappers.c
blob483acc164198c765fa8005fdba18f21ae07f8455
1 /*
2 * The Regina Rexx Interpreter
3 * Copyright (C) 1993-1994 Anders Christensen <anders@pvv.unit.no>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * This file is 'a hell of a file'. It contain _anything_ that is neither
21 * POSIX nor ANSI. The meaning is that when these things are needed in
22 * the code, they are located in a wrapper in this file. Thus, if you need
23 * to hack the code, it's likely that you only need to hack this file.
25 * At least, that's the theory ...
28 #include "regina_c.h"
30 #if defined(WIN32)
31 # ifdef _MSC_VER
32 # if _MSC_VER >= 1100
33 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
34 # pragma warning(disable: 4115 4201 4214 4514)
35 # endif
36 # endif
37 # include <windows.h>
38 # ifdef _MSC_VER
39 # if _MSC_VER >= 1100
40 # pragma warning(default: 4115 4201 4214)
41 # endif
42 # endif
43 #endif
45 #if defined(OS2)
46 # define INCL_DOSMODULEMGR
47 # include <os2.h>
48 # define DONT_TYPEDEF_PFN
49 #endif
51 #ifdef _POSIX_SOURCE
52 # undef _POSIX_SOURCE
53 #endif
55 #include "rexx.h"
57 #ifdef DYNAMIC
60 * Most Unix systems have dlopen(), so set this as the default and
61 * unset it for platforms that don't have it - except for HPUX
63 # if defined(__hpux)
64 # define DYNAMIC_HPSHLOAD
65 # endif
67 # if defined(HAVE_DLFCN_H) && !defined(DYNAMIC_HPSHLOAD)
68 # define DYNAMIC_DLOPEN
69 # endif
71 # if defined(DYNAMIC_STATIC)
72 typedef void * handle_type;
73 # define DYNLIBPRE ""
74 # define DYNLIBPST ""
75 # elif defined(DYNAMIC_DLOPEN)
76 # include <dlfcn.h>
77 typedef void *handle_type ;
78 # ifndef RTLD_LAZY
79 # define RTLD_LAZY 1
80 # endif
81 # if defined(__CYGWIN__)
82 # define DYNLIBPRE ""
83 # define DYNLIBPST ".dll"
84 # define DYNLIBLEN 4
85 # elif defined(__APPLE__) && defined(__MACH__)
86 # define DYNLIBPRE "lib"
87 # define DYNLIBPST ".dylib"
88 # define DYNLIBLEN 9
89 # elif defined(AIX)
90 # define DYNLIBPRE "lib"
91 # define DYNLIBPST ".a"
92 # define DYNLIBLEN 5
93 # else
94 # define DYNLIBPRE "lib"
95 # define DYNLIBPST ".so"
96 # define DYNLIBLEN 6
97 # endif
98 # elif defined(DYNAMIC_AIXLOAD)
99 # include <sys/types.h>
100 # include <sys/ldr.h>
101 typedef int (*handle_type) ;
102 # define DYNLIBPRE "lib"
103 # define DYNLIBPST ".a"
104 # define DYNLIBLEN 5
106 # elif defined(DYNAMIC_HPSHLOAD)
107 # include <dl.h>
108 typedef shl_t handle_type ;
109 # define DYNLIBPRE "lib"
110 # define DYNLIBPST ".sl"
111 # define DYNLIBLEN 6
113 # elif defined(__BEOS__)
114 # include <be/kernel/image.h>
115 # define DYNAMIC_BEOS 1
116 typedef image_id handle_type ;
118 * BeOS add-ons are all in a directory specified in $ADDON_PATH
120 # define DYNLIBPRE "lib"
121 # define DYNLIBPST ".so"
122 # define DYNLIBLEN 6
124 # elif defined(DYNAMIC_SKYOS)
125 typedef sDllHandle * handle_type ;
126 # define DYNLIBPRE "/boot/programs/rexx/extensions/lib"
127 # define DYNLIBPST ".dll"
128 # define DYNLIBLEN 40
130 # elif defined(DYNAMIC_OS2)
131 typedef HMODULE handle_type ;
132 /* typedef PHMODULE handle_type ; */
134 # elif defined(DYNAMIC_WIN32)
135 typedef HINSTANCE handle_type ;
137 # elif defined(DYNAMIC_VMS)
138 # define DYNLIBPRE "LIB"
139 # define DYNLIBPST ".EXE"
140 # define DYNLIBLEN 7
141 #endif /* DYNAMIC */
143 #include <errno.h>
144 #include <string.h>
146 #ifdef DYNAMIC_HPSHLOAD_NOT_NEEDED
148 * HP/UX doesn't find symbols unless they are 'true data'; entrypoints
149 * for functions are not sufficient! Thus, we need to force it to
150 * 'release' that these symbols are defined. There's no need to do
151 * anything more, once it sets some flag somewhere ... it'll find'em
152 * later. Weird!
154 * Datatype char only used to save space ... this is never used, so
155 * there is no reason to waste space.
157 * Removed by MH 0.08h. Causes problems on HPUX 10.20 linker, and may
158 * not be needed anymore.
161 char Food_For_Fuzzy_HP_Linkers[] = {
162 (char)exiterror, (char)getonechar,
163 (char)nullstringptr,
164 (char)atozpos, (char)checkparam, (char)find_library } ;
165 #endif
167 #if defined(DYNAMIC_AIXLOAD)
168 void *wrapper_dummy_for_aix( void )
171 #endif
173 void *wrapper_load( const tsd_t *TSD, const streng *module )
175 handle_type handle=(handle_type)NULL ;
176 #if defined(DYNAMIC_OS2)
177 CHAR LoadError[256];
178 APIRET rc=0L;
179 #endif
180 #if defined(DYNAMIC_WIN32)
181 char LoadError[256];
182 #endif
183 #if defined(DYNAMIC_HPSHLOAD) || defined(DYNAMIC_BEOS)
184 char buf[1024];
185 #endif
186 #ifdef DYNAMIC_SKYOS
187 sDllHandle tmp_handle;
188 #endif
189 char *file_name, *module_name, *udpart, *postfix, *orig_module;
191 orig_module = str_ofTSD( module );
192 #ifdef DYNLIBLEN
193 module_name = (char *)MallocTSD( Str_len( module ) + strlen(DYNLIBPRE) +
194 strlen(DYNLIBPST) + 1 ) ;
195 strcpy(module_name, DYNLIBPRE );
196 udpart = module_name + strlen(DYNLIBPRE);
197 memcpy(udpart, module->value, Str_len(module) );
198 strcpy(udpart + Str_len(module), DYNLIBPST );
199 file_name = module_name;
200 postfix = udpart + Str_len(module);
201 # if defined(DYNAMIC_HPSHLOAD)
202 file_name = buf;
203 # endif
204 #else
205 file_name = module_name = str_ofTSD(module);
206 #endif
208 #if defined(DYNAMIC_STATIC)
209 handle = static_dlopen( file_name );
210 if (handle == NULL)
212 set_err_message(TSD, "static_dlopen() failed loading:", file_name );
213 handle = (handle_type)NULL;
215 #elif defined(DYNAMIC_DLOPEN)
217 * Try and load the module name exactly as specified (before wrapping it
218 * in lib*.so)
220 handle = dlopen( orig_module, RTLD_LAZY ) ;
221 if (handle == NULL)
223 handle = dlopen( file_name, RTLD_LAZY ) ;
224 /* deal with incorrect case in call */
225 if (handle == NULL)
227 mem_lower( udpart, Str_len( module ) );
228 handle = dlopen(module_name, RTLD_LAZY);
230 if (handle == NULL)
232 mem_upper( udpart, Str_len( module ) );
233 handle = dlopen(module_name, RTLD_LAZY);
235 * Reset the original module portion of the filename to be
236 * searched again so that any error message returned uses the
237 * original module name
239 if ( handle == NULL )
241 memcpy(udpart, module->value, Str_len(module) );
242 handle = dlopen(module_name, RTLD_LAZY);
248 /* or maybe it's just not there */
249 if (handle==NULL)
251 char *msg=NULL;
252 msg = dlerror();
253 if (msg)
254 set_err_message(TSD, "dlopen() failed: ", msg ) ;
255 else
256 set_err_message(TSD, "", "");
258 #elif defined(DYNAMIC_HPSHLOAD)
260 * Try and load the module name exactly as specified (before wrapping it
261 * in lib*.sl)
263 find_shared_library( TSD, orig_module, "SHLIB_PATH", buf );
264 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L ) ;
265 if (handle == NULL)
267 find_shared_library(TSD,module_name,"SHLIB_PATH",buf);
268 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L ) ;
269 if (handle == NULL)
271 mem_lower( udpart, Str_len( module ) );
272 find_shared_library( TSD, module_name, "SHLIB_PATH", buf );
273 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ;
275 if (handle == NULL)
277 mem_upper( udpart, Str_len( module ) );
278 find_shared_library( TSD, module_name, "SHLIB_PATH", buf );
279 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ;
284 if (handle==NULL)
285 set_err_message(TSD, "shl_load() failed: ", strerror(errno)) ;
286 #elif defined(DYNAMIC_AIXLOAD)
288 * Try and load the module name exactly as specified (before wrapping it
289 * in lib*.a)
291 handle = load( orig_module, 1, NULL ) ;
292 if ( handle == NULL )
294 handle = load( file_name, 1, NULL ) ;
295 if ( handle == NULL )
297 set_err_message(TSD, "load() failed: ", strerror( errno )) ;
299 else
301 int rc=loadbind( 0, (void *)wrapper_dummy_for_aix, (void *)handle ) ;
302 if (rc)
304 handle = NULL ;
305 set_err_message(TSD, "loadbind() failed: ", strerror( errno )) ;
308 #elif defined(DYNAMIC_OS2)
309 rc = DosLoadModule( LoadError, sizeof(LoadError),
310 file_name, &handle ) ;
311 if (rc)
313 set_err_message(TSD, "DosLoadModule() unable to load DLL: ", LoadError);
314 handle = (handle_type)NULL;
316 #elif defined(DYNAMIC_WIN32)
317 handle = LoadLibrary( file_name ) ;
318 if (handle==NULL)
320 char buf[150];
321 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL ) ;
322 sprintf( buf, "Failed to load \"%s\" library: LoadLibrary() failed: ", file_name );
323 set_err_message(TSD, buf, LoadError);
325 #elif defined(DYNAMIC_BEOS)
326 handle = load_add_on( orig_module );
327 if (handle < B_NO_ERROR)
329 handle = load_add_on( file_name );
330 if (handle < B_NO_ERROR)
332 sprintf( buf, "load_add_on() failed loading \"%s\" with error:", file_name );
333 set_err_message(TSD, buf, strerror( handle ) );
334 handle = (handle_type)NULL;
337 #elif defined(DYNAMIC_SKYOS)
338 handle = (handle_type)MallocTSD( sizeof( sDllHandle ) );
340 * Don't try and load the module without the trimmings.
341 * You get a binary popup window otherwise!
343 fprintf(stderr,"%s %d %x %s:\n",__FILE__,__LINE__,handle,file_name);
344 if ( DllLoad( file_name, &tmp_handle ) != 0 )
346 char buf[150];
347 sprintf( buf, "Failed to load \"%s\" library: DllLoad() failed: ", file_name );
348 set_err_message(TSD, buf, strerror( errno ) );
349 FreeTSD( handle );
350 handle = (handle_type)NULL;
352 fprintf(stderr,"%s %d:\n",__FILE__,__LINE__);
353 memcpy( handle, &tmp_handle, sizeof( sDllHandle ) );
354 fprintf(stderr,"%s %d:\n",__FILE__,__LINE__);
355 #endif
357 FreeTSD( module_name );
358 FreeTSD( orig_module );
360 return (void *)handle ;
363 void wrapper_unload( const tsd_t *TSD, void *libhandle )
365 #ifdef DYNAMIC_STATIC
367 libhandle = libhandle;
369 #elif defined(DYNAMIC_DLOPEN)
371 dlclose((handle_type) libhandle);
373 #elif defined(DYNAMIC_HPSHLOAD)
375 shl_unload((handle_type) libhandle);
377 #elif defined(DYNAMIC_AIXLOAD)
379 unload((handle_type) libhandle);
381 #elif defined(DYNAMIC_OS2)
383 DosFreeModule((handle_type) libhandle);
385 #elif defined(DYNAMIC_WIN32)
387 FreeLibrary((handle_type) libhandle);
389 #elif defined(DYNAMIC_BEOS)
391 unload_add_on((handle_type) libhandle);
393 #elif defined(DYNAMIC_SKYOS)
395 fprintf(stderr,"%s %d:\n",__FILE__,__LINE__);
396 FreeTSD( libhandle );
398 #else
399 (libhandle = libhandle);
400 #endif
403 PFN wrapper_get_addr( const tsd_t *TSD, const struct library *lptr, const streng *name )
405 PFN addr;
406 handle_type handle=(handle_type)lptr->handle;
407 char *funcname ;
408 #if defined(DYNAMIC_WIN32)
409 char LoadError[256];
410 char *entryname;
411 unsigned u;
412 char c;
413 #endif
414 #if defined(DYNAMIC_OS2)
415 char *entryname;
416 unsigned u;
417 char c;
418 ULONG ordinal;
419 APIRET rc=0L;
420 #endif
421 #if defined(DYNAMIC_BEOS)
422 status_t rc=0;
423 #endif
424 #if defined(DYNAMIC_STATIC)
425 int rc=0;
426 #endif
427 #if defined(MODULES_NEED_USCORE)
428 streng *us_func;
429 #endif
431 funcname = str_of( TSD, name ) ;
433 #if defined(DYNAMIC_STATIC)
434 rc = static_dlsym( handle, funcname,(void **)&addr );
435 if ( rc != 0 )
437 char buf[150];
438 sprintf(buf,"static_dlsym() failed with %d looking for %s", rc, funcname );
439 set_err_message(TSD, buf, "" ) ;
440 addr = NULL;
442 #elif defined(DYNAMIC_DLOPEN)
443 # if defined(MODULES_NEED_USCORE)
445 * Some platforms need to have an underscore prepended to the function
446 * name to be found in a loadable module.
448 FreeTSD( funcname );
449 us_func = Str_makeTSD( Str_len( name ) + 1 );
450 memcpy( us_func->value, "_", 1 );
451 us_func->len = 1;
452 Str_catTSD( us_func, name );
453 funcname = str_of( TSD, us_func );
454 Free_stringTSD( us_func );
455 # endif
457 * Note, the following assignment is not allowed by ANSI, but SVR4.2
458 * includes it as an example, so it is probably safe in this context
460 addr = (PFN)(dlsym( handle, funcname )) ;
462 /* deal with, eg 'SysLoadFuncs' when the function is 'sysloadfuncs' or 'SYSLOADFUNCS' */
463 if (addr == NULL)
465 mem_upper( funcname, strlen( funcname ) );
466 addr = (PFN)(dlsym( handle, funcname )) ;
468 if (addr == NULL)
470 mem_lower( funcname, strlen( funcname ) );
471 addr = (PFN)(dlsym( handle, funcname )) ;
473 if (addr==NULL)
474 set_err_message( TSD, "dlsym() failed: ", dlerror() );
478 #elif defined(DYNAMIC_HPSHLOAD)
480 long eaddr ;
481 int rc;
483 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
485 mem_upper( funcname, strlen( funcname ) );
486 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
488 mem_lower( funcname, strlen( funcname ) );
489 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
491 addr = NULL ;
492 set_err_message( TSD, "shl_findsym() failed: ", strerror(errno) );
497 if (!rc)
498 addr = (PFN)eaddr ;
501 #elif defined(DYNAMIC_AIXLOAD)
502 addr = (PFN)handle ;
504 #elif defined(DYNAMIC_OS2)
505 if ( ( sscanf( funcname, "#%u%c", &u, &c ) == 1 ) && ( u != 0 ) )
507 ordinal = (ULONG) u;
508 entryname = NULL;
510 else
512 ordinal = 0L;
513 entryname = funcname;
515 rc = DosQueryProcAddr(handle,ordinal,entryname,&addr);
516 if (rc)
518 mem_upper( entryname, strlen( entryname ) );
519 rc = DosQueryProcAddr(handle,ordinal,entryname,&addr);
520 if (rc)
522 mem_lower( entryname, strlen( entryname ) );
523 rc = DosQueryProcAddr(handle,ordinal,entryname,&addr);
524 if (rc)
526 char buf[150];
527 sprintf(buf,"DosQueryProcAddr() failed with %lu looking for %.90s", (long) rc, funcname );
528 set_err_message(TSD, buf, "" ) ;
533 #elif defined(DYNAMIC_WIN32)
534 /* 13/12/1999 JH moved cast, (HMODULE), from second parm to first. Removed
535 * a compiler warning,
537 if ( ( sscanf( funcname, "#%u%c", &u, &c ) == 1 ) && ( u != 0 ) &&
538 ( u <= 0xFFFF ) )
539 entryname = (char *) u;
540 else
541 entryname = funcname;
543 addr = (PFN) GetProcAddress( (HMODULE) handle, entryname );
545 if ( ( addr == NULL ) && ( funcname == entryname ) )
547 strlwr(funcname);
548 addr = (PFN)GetProcAddress((HMODULE)handle,funcname);
550 if (addr == NULL)
552 strupr(funcname);
553 addr = (PFN)GetProcAddress((HMODULE)handle, funcname);
556 if (addr == NULL)
558 char buf[150];
559 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL );
560 sprintf( buf, "Failed to find \"%s\" in external library: GetProcAddress() failed: ", funcname );
561 set_err_message( TSD, buf, LoadError );
564 #elif defined(DYNAMIC_BEOS)
565 rc = get_image_symbol(handle,funcname,B_SYMBOL_TYPE_TEXT,(void **)&addr);
566 if (rc == B_BAD_IMAGE_ID)
568 char buf[150];
569 sprintf(buf,"get_image_symbol() failed with %d looking for %s", rc, funcname );
570 set_err_message( TSD, buf, "" );
571 addr = NULL;
574 #elif defined(DYNAMIC_SKYOS)
575 fprintf(stderr,"%s %d:\n",__FILE__,__LINE__);
576 addr = (PFN)GetDllFunction( handle, funcname );
577 if ( addr == NULL )
579 char buf[150];
580 sprintf(buf,"GetDllFunction() failed looking for %s", funcname );
581 set_err_message( TSD, buf, "" );
582 addr = NULL;
584 fprintf(stderr,"%s %d:\n",__FILE__,__LINE__);
585 #endif
587 FreeTSD( funcname );
589 if (addr)
590 return (PFN)addr ;
591 else
592 return NULL ;
594 # ifdef SKYOS
596 * Required as entry point for DLL under SkyOS
598 int DllMain( void )
600 return 0;
602 # endif
604 #endif /* DYNAMIC */