bringing SDL 1.2.14 from vendor into the main branch
[AROS-Contrib.git] / regina / wrappers.c
blobaa89f75f7a182345230f782c5e4d2284caaf0803
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.
21 * $Id$
25 * This file is 'a hell of a file'. It contain _anything_ that is neither
26 * POSIX nor ANSI. The meaning is that when these things are needed in
27 * the code, they are located in a wrapper in this file. Thus, if you need
28 * to hack the code, it's likely that you only need to hack this file.
30 * At least, that's the theory ...
33 #if defined(WIN32)
34 # ifdef _MSC_VER
35 # if _MSC_VER >= 1100
36 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
37 # pragma warning(disable: 4115 4201 4214)
38 # endif
39 # endif
40 # include <windows.h>
41 # ifdef _MSC_VER
42 # if _MSC_VER >= 1100
43 # pragma warning(default: 4115 4201 4214)
44 # endif
45 # endif
46 #endif
48 #if defined(OS2)
49 # define INCL_DOSMODULEMGR
50 # include <os2.h>
51 # define DONT_TYPEDEF_PFN
52 #endif
54 #ifdef _POSIX_SOURCE
55 # undef _POSIX_SOURCE
56 #endif
58 #include "rexx.h"
59 #include <ctype.h>
61 #ifdef DYNAMIC
64 * Most Unix systems have dlopen(), so set this as the default and
65 * unset it for platforms that don't have it - except for HPUX
67 # if defined(__hpux)
68 # define DYNAMIC_HPSHLOAD
69 # endif
71 # if defined(HAVE_DLFCN_H) && !defined(DYNAMIC_HPSHLOAD)
72 # define DYNAMIC_DLOPEN
73 # endif
75 # if 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 # else
86 # define DYNLIBPRE "lib"
87 # if defined(AIX)
88 # define DYNLIBPST ".a"
89 # define DYNLIBLEN 5
90 # else
91 # define DYNLIBPST ".so"
92 # define DYNLIBLEN 6
93 # endif
94 # endif
95 # elif defined(DYNAMIC_AIXLOAD)
96 # include <sys/types.h>
97 # include <sys/ldr.h>
98 typedef int (*handle_type) ;
99 # define DYNLIBPRE "lib"
100 # define DYNLIBPST ".a"
101 # define DYNLIBLEN 5
103 # elif defined(DYNAMIC_HPSHLOAD)
104 # include <dl.h>
105 typedef shl_t handle_type ;
106 # define DYNLIBPRE "lib"
107 # define DYNLIBPST ".sl"
108 # define DYNLIBLEN 6
110 # elif defined(__BEOS__)
111 # include <be/kernel/image.h>
112 # define DYNAMIC_BEOS 1
113 typedef image_id handle_type ;
115 * BeOS add-ons are all in a directory specified in $ADDON_PATH
117 # define DYNLIBPRE "lib"
118 # define DYNLIBPST ".so"
119 # define DYNLIBLEN 6
121 # elif defined(DYNAMIC_OS2)
122 typedef HMODULE handle_type ;
123 /* typedef PHMODULE handle_type ; */
125 # elif defined(DYNAMIC_WIN32)
126 typedef HINSTANCE handle_type ;
127 # elif defined(DYNAMIC_VMS)
128 # define DYNLIBPRE "LIB"
129 # define DYNLIBPST ".EXE"
130 # define DYNLIBLEN 7
131 #endif /* DYNAMIC */
133 #include <errno.h>
134 #include <string.h>
136 #ifdef DYNAMIC_HPSHLOAD_NOT_NEEDED
138 * HP/UX doesn't find symbols unless they are 'true data'; entrypoints
139 * for functions are not sufficient! Thus, we need to force it to
140 * 'release' that these symbols are defined. There's no need to do
141 * anything more, once it sets some flag somewhere ... it'll find'em
142 * later. Weird!
144 * Datatype char only used to save space ... this is never used, so
145 * there is no reason to waste space.
147 * Removed by MH 0.08h. Causes problems on HPUX 10.20 linker, and may
148 * not be needed anymore.
151 char Food_For_Fuzzy_HP_Linkers[] = {
152 (char)exiterror, (char)getonechar,
153 (char)nullstringptr,
154 (char)atozpos, (char)checkparam, (char)loadrxfunc } ;
155 #endif
157 #if defined(DYNAMIC_AIXLOAD)
158 void *wrapper_dummy_for_aix( void )
161 #endif
163 /* versions of strlwr & strupr to simulate case-insensitivity */
164 static void rxstrlwr(unsigned char * s, unsigned char *e)
166 while (*s && s != e)
168 *s = (unsigned char) (tolower(*s));
169 s++;
173 static void rxstrupr(unsigned char * s, unsigned char *e)
175 while (*s && s != e)
177 *s = (unsigned char) (toupper(*s));
178 s++;
183 void *wrapper_load( const tsd_t *TSD, const streng *module )
185 handle_type handle=(handle_type)NULL ;
186 #if defined(DYNAMIC_OS2)
187 CHAR LoadError[256];
188 APIRET rc=0L;
189 #endif
190 #if defined(DYNAMIC_WIN32)
191 char LoadError[256];
192 #endif
193 #if defined(DYNAMIC_HPSHLOAD)
194 char buf[1024];
195 #endif
196 char *file_name, *module_name, *udpart, *postfix;
198 #ifndef DYNLIBLEN
199 file_name = module_name = str_ofTSD(module);
200 #else
201 module_name = MallocTSD( Str_len( module ) + strlen(DYNLIBPRE) +
202 strlen(DYNLIBPST) + 1 ) ;
203 strcpy(module_name, DYNLIBPRE );
204 udpart = module_name + strlen(DYNLIBPRE);
205 memcpy(udpart, module->value, Str_len(module) );
206 strcpy(udpart + Str_len(module), DYNLIBPST );
207 file_name = module_name;
208 postfix = udpart + Str_len(module);
209 # if defined(DYNAMIC_HPSHLOAD)
210 find_shared_library(TSD,module_name,"SHLIB_PATH",buf);
211 file_name = buf;
212 # endif
213 #endif
215 #if defined(DYNAMIC_DLOPEN)
216 handle = dlopen( file_name, RTLD_LAZY ) ;
218 /* deal with incorrect case in call */
219 if (handle == NULL)
221 rxstrlwr(udpart,postfix);
222 handle = dlopen(module_name, RTLD_LAZY);
224 if (handle == NULL)
226 rxstrupr(udpart,postfix);
227 handle = dlopen(module_name, RTLD_LAZY);
229 * Reset the original module portion of the filename to be
230 * searched again so that any error message returned uses the
231 * original module name
233 if ( handle == NULL )
235 memcpy(udpart, module->value, Str_len(module) );
236 handle = dlopen(module_name, RTLD_LAZY);
241 /* or maybe it's just not there */
242 if (handle==NULL)
244 char *msg=NULL;
245 msg = dlerror();
246 if (msg)
247 set_err_message(TSD, "dlopen() failed: ", msg ) ;
248 else
249 set_err_message(TSD, "", "");
251 #elif defined(DYNAMIC_HPSHLOAD)
252 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L ) ;
253 if (handle == NULL)
255 rxstrlwr(udpart,postfix);
256 find_shared_library(TSD,module_name,"SHLIB_PATH",buf);
257 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ;
259 if (handle == NULL)
261 rxstrupr(udpart,postfix);
262 find_shared_library(TSD,module_name,"SHLIB_PATH",buf);
263 handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ;
267 if (handle==NULL)
268 set_err_message(TSD, "shl_load() failed: ", strerror(errno)) ;
269 #elif defined(DYNAMIC_AIXLOAD)
270 handle = load( file_name, 1, NULL ) ;
271 if (handle)
273 int rc=loadbind( 0, (void *)wrapper_dummy_for_aix, (void *)handle ) ;
274 if (rc)
275 handle = NULL ;
277 else
278 set_err_message(TSD, "load() failed: ", strerror( errno )) ;
279 #elif defined(DYNAMIC_OS2)
280 rc = DosLoadModule( LoadError, sizeof(LoadError),
281 file_name, &handle ) ;
282 if (rc)
284 set_err_message(TSD, "DosLoadModule() unable to load DLL: ", LoadError);
285 handle = (handle_type)NULL;
287 #elif defined(DYNAMIC_WIN32)
288 handle = LoadLibrary( file_name ) ;
289 if (handle==NULL)
291 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL ) ;
292 set_err_message(TSD, "LoadLibrary() failed: ", LoadError);
294 #elif defined(DYNAMIC_BEOS)
295 handle = load_add_on( file_name );
296 if (handle == B_ERROR)
298 set_err_message(TSD, "load_add_on() failed loading:", file_name );
299 handle = (handle_type)NULL;
301 #endif
303 FreeTSD(module_name);
305 return (void *)handle ;
308 PFN wrapper_get_addr( const tsd_t *TSD, const struct library *lptr, const streng *name)
310 PFN addr;
311 handle_type handle=(handle_type)lptr->handle;
312 char *funcname ;
313 #if defined(DYNAMIC_WIN32)
314 char LoadError[256];
315 #endif
316 #if defined(DYNAMIC_OS2)
317 APIRET rc=0L;
318 #endif
319 #if defined(DYNAMIC_BEOS)
320 status_t rc=0;
321 #endif
322 #if defined(MODULES_NEED_USCORE)
323 streng *us_func;
324 #endif
326 funcname = str_of( TSD, name ) ;
328 #if defined(DYNAMIC_DLOPEN)
329 # if defined(MODULES_NEED_USCORE)
331 * Some platforms need to have an underscore prepended to the function
332 * name to be found in a loadable module.
334 FreeTSD( funcname );
335 us_func = Str_makeTSD( Str_len( name ) + 1 );
336 memcpy( us_func->value, "_", 1 );
337 us_func->len = 1;
338 Str_catTSD( us_func, name );
339 funcname = str_of( TSD, us_func );
340 # endif
342 * Note, the following assignment is not allowed by ANSI, but SVR4.2
343 * includes it as an example, so it is probably safe in this context
345 addr = (PFN)(dlsym( handle, funcname )) ;
347 /* deal with, eg 'SysLoadFuncs' when the function is 'sysloadfuncs' or 'SYSLOADFUNCS' */
348 if (addr == NULL)
350 rxstrupr(funcname,NULL);
351 addr = (PFN)(dlsym( handle, funcname )) ;
353 if (addr == NULL)
355 rxstrlwr(funcname,NULL);
356 addr = (PFN)(dlsym( handle, funcname )) ;
358 if (addr==NULL)
359 set_err_message(TSD, "dlsym() failed: ", dlerror()) ;
363 #elif defined(DYNAMIC_HPSHLOAD)
365 long eaddr ;
366 int rc;
368 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
370 rxstrupr(funcname,NULL);
371 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
373 rxstrlwr(funcname,NULL);
374 if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr ))
376 addr = NULL ;
377 set_err_message(TSD, "shl_findsym() failed: ", strerror(errno)) ;
382 if (!rc)
383 addr = (PFN)eaddr ;
385 #elif defined(DYNAMIC_AIXLOAD)
386 addr = (PFN)handle ;
387 #elif defined(DYNAMIC_OS2)
388 rc = DosQueryProcAddr(handle,0L,funcname,&addr);
389 if (rc)
391 char buf[150];
392 sprintf(buf,"DosQueryProcAddr() failed with %ld looking for %s", (long) rc, funcname );
393 set_err_message(TSD, buf, "" ) ;
395 #elif defined(DYNAMIC_WIN32)
396 /* 13/12/1999 JH moved cast, (HMODULE), from second parm to first. Removed
397 * a compiler warning,
399 addr = (PFN)GetProcAddress((HMODULE)handle,funcname);
401 if (addr == NULL)
403 strlwr(funcname);
404 addr = (PFN)GetProcAddress((HMODULE)handle,funcname);
406 if (addr == NULL)
408 strupr(funcname);
409 addr = (PFN)GetProcAddress((HMODULE)handle, funcname);
410 if (addr == NULL)
412 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL ) ;
413 set_err_message(TSD, "GetProcAddress() failed: ", LoadError ) ;
417 #elif defined(DYNAMIC_BEOS)
418 rc = get_image_symbol(handle,funcname,B_SYMBOL_TYPE_TEXT,(void **)&addr);
419 if (rc == B_BAD_IMAGE_ID)
421 char buf[150];
422 sprintf(buf,"get_image_symbol() failed with %d looking for %s", rc, funcname );
423 set_err_message(TSD, buf, "" ) ;
424 addr = NULL;
426 #endif
428 FreeTSD( funcname ) ;
430 if (addr)
431 return (PFN)addr ;
432 else
433 return NULL ;
436 #endif /* DYNAMIC */