2 static char *RCSid
= "$Id$";
6 * The Regina Rexx Interpreter
7 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Sigh, let's live dangerously. We need to remove the definition of
26 * _POSIX_SOURCE, in order to get defined some extenstions to POSIX,
27 * since dynamic loading is not a part of POSIX.
36 typedef struct { /* lib_tsd: static variables of this module (thread-safe) */
37 struct library
* first_library
;
39 struct library_func
*libfuncs
[133] ;
41 streng
* err_message
;
42 } lib_tsd_t
; /* thread-specific but only needed by this module. see
45 #define LIBFUNCS_COUNT (sizeof(((lib_tsd_t*)0)->libfuncs) / \
46 sizeof(((lib_tsd_t*)0)->libfuncs[0]))
48 /* init_library initializes the module.
49 * Currently, we set up the thread specific data.
50 * The function returns 1 on success, 0 if memory is short.
52 int init_library( tsd_t
*TSD
)
56 if (TSD
->lib_tsd
!= NULL
)
59 if ((lt
= TSD
->lib_tsd
= MallocTSD(sizeof(lib_tsd_t
))) == NULL
)
61 memset(lt
,0,sizeof(lib_tsd_t
)); /* correct for all values */
67 /* Operations on the library and library_func structures */
69 static void insert_library( const tsd_t
*TSD
, struct library
*ptr
)
75 ptr
->next
= lt
->first_library
;
76 if ((lt
->first_library
=ptr
)->next
)
77 ptr
->next
->prev
= ptr
;
80 static void remove_function( const tsd_t
*TSD
, const struct library_func
*fptr
)
86 fptr
->next
->prev
= fptr
->prev
;
88 fptr
->prev
->next
= fptr
->next
;
90 lt
->libfuncs
[fptr
->hash
% LIBFUNCS_COUNT
] = fptr
->next
;
93 fptr
->forw
->backw
= fptr
->backw
;
95 fptr
->backw
->forw
= fptr
->forw
;
97 fptr
->lib
->first
= fptr
->forw
;
100 static void remove_library( const tsd_t
*TSD
, struct library
*ptr
)
106 ptr
->next
->prev
= ptr
->prev
;
109 ptr
->prev
->next
= ptr
->next
;
111 lt
->first_library
= ptr
->next
;
113 assert( ptr
->name
) ;
114 Free_stringTSD( ptr
->name
) ;
118 void purge_library( const tsd_t
*TSD
)
120 struct library_func
*lptr
, *save_lptr
;
121 struct library
*ptr
, *save_ptr
;
125 for (ptr
= lt
->first_library
; ptr
!= NULL
; )
127 save_ptr
= ptr
->next
;
128 for ( lptr
= ptr
->first
; lptr
; )
130 save_lptr
= lptr
->next
;
131 remove_function( TSD
, lptr
) ;
132 Free_stringTSD( lptr
->name
);
135 remove_library( TSD
, ptr
);
138 lt
->first_library
= NULL
;
139 memset( lt
->libfuncs
, 0, sizeof(lt
->libfuncs
) ) ;
143 static struct library
*find_library( const tsd_t
*TSD
, const streng
*name
)
145 struct library
*lptr
=NULL
;
149 lptr
= lt
->first_library
;
150 for (;lptr
; lptr
=lptr
->next
)
152 if (!Str_cmp(name
,lptr
->name
))
159 static void add_function( const tsd_t
*TSD
, struct library_func
*fptr
)
165 hash0
= fptr
->hash
% LIBFUNCS_COUNT
;
166 fptr
->next
= lt
->libfuncs
[hash0
] ;
167 lt
->libfuncs
[hash0
] = fptr
;
170 fptr
->next
->prev
= fptr
;
172 fptr
->forw
= fptr
->lib
->first
;
174 fptr
->lib
->first
= fptr
;
176 fptr
->forw
->backw
= fptr
;
179 static struct library_func
*find_library_func( const tsd_t
*TSD
, const streng
*name
)
181 struct library_func
*lptr
=NULL
;
182 unsigned hash
, hash0
;
186 hash
= hashvalue( name
->value
, name
->len
) ;
187 hash0
= hash
% LIBFUNCS_COUNT
;
188 for (lptr
=lt
->libfuncs
[hash0
]; lptr
; lptr
=lptr
->next
)
190 if (hash
== lptr
->hash
)
191 if (Str_cmp(name
,lptr
->name
) == 0)
198 void set_err_message( const tsd_t
*TSD
, const char *message1
, const char *message2
)
205 Free_stringTSD( lt
->err_message
) ;
208 lt
->err_message
= Str_creTSD( message
) ;
210 size
= strlen(message1
)+strlen(message2
);
211 lt
->err_message
= MallocTSD(size
+1);
212 if ( lt
->err_message
)
214 strcpy( lt
->err_message
->value
, message1
);
215 strcat( lt
->err_message
->value
, message2
);
216 lt
->err_message
->len
= size
;
221 int loadrxfunc( const tsd_t
*TSD
, struct library
*lptr
, const streng
*rxname
, const streng
*objnam
)
225 struct library_func
*fptr
=NULL
;
229 fptr
= find_library_func( TSD
, rxname
) ;
230 if (!fptr
|| fptr
->lib
!=lptr
)
232 addr
= wrapper_get_addr( TSD
, lptr
, objnam
) ;
235 fptr
= MallocTSD( sizeof( struct library_func
)) ;
236 fptr
->name
= Str_upper( Str_dupstrTSD( rxname
) );
237 fptr
->hash
= hashvalue(fptr
->name
->value
, fptr
->name
->len
);
240 add_function( TSD
, fptr
) ;
261 * This loads a module as a result of a RexxRegisterFunctionDll() call
264 * 1) name of the function to be added (in Rexx)
265 * 2) name of object file to link in
266 * 3) name of the function to be added (in the object file)
268 static int rex_rxfuncdlladd( const tsd_t
*TSD
, const streng
* rxname
,
269 const streng
* module
, const streng
* objnam
)
271 struct library
*lptr
=NULL
;
275 if ((lptr
=find_library(TSD
, module
)) == NULL
)
277 handle
= wrapper_load( TSD
, module
) ;
280 lptr
= MallocTSD( sizeof( struct library
)) ;
281 lptr
->name
= Str_dupTSD( module
) ;
282 lptr
->handle
= handle
;
290 insert_library( TSD
, lptr
) ;
292 rc
= loadrxfunc( TSD
, lptr
, rxname
, objnam
) ;
297 streng
*rex_rxfuncerrmsg( tsd_t
*TSD
, cparamboxptr parms
)
303 checkparam( parms
, 0, 0 , "RXFUNCERRMSG" ) ;
308 return Str_dupTSD( lt
->err_message
) ;
310 return nullstringptr() ;
312 return Str_creTSD( "Platform doesn't support dynamic linking" ) ;
316 streng
*rex_rxfuncquery( tsd_t
*TSD
, cparamboxptr parms
)
320 struct library_func
*fptr
=NULL
;
323 checkparam( parms
, 1, 1 , "RXFUNCQUERY" ) ;
324 name
= Str_upper( parms
->value
) ;
326 fptr
= find_library_func( TSD
, name
) ;
329 return int_to_streng( TSD
, 0 ) ;
331 *... otherwise fall through and try to find the function
332 * loaded via RexxRegisterFunctionExe()
335 return int_to_streng( TSD
,(external_func( TSD
, name
) ) ? 0 : 1);
341 * 1) name of the function to be added (in Rexx)
342 * 2) name of object file to link in
343 * 3) name of the function to be added (in the object file)
345 streng
*rex_rxfuncadd( tsd_t
*TSD
, cparamboxptr parms
)
348 streng
*rxname
=NULL
;
349 streng
*module
=NULL
, *objnam
=NULL
;
352 if ( TSD
->restricted
)
353 exiterror( ERR_RESTRICTED
, 1, "RXFUNCADD" ) ;
355 checkparam( parms
, 3, 3 , "RXFUNCADD" ) ;
357 rxname
= Str_upper (Str_dupTSD(parms
->value
) ) ;
358 module
= (parms
=parms
->next
)->value
;
359 objnam
= parms
->next
->value
;
361 rc
= rex_rxfuncdlladd( TSD
, rxname
, module
, objnam
) ;
362 Free_stringTSD( rxname
);
363 return int_to_streng( TSD
, rc
) ;
365 checkparam( parms
, 3, 3 , "RXFUNCADD" ) ;
366 return int_to_streng( TSD
, 1 ) ;
370 int IfcRegDllFunc( const tsd_t
*TSD
, const char* rxname
, const char* module
, const char* objnam
)
378 ext
= Str_upper( Str_creTSD( rxname
) ) ;
379 intr
= Str_creTSD( objnam
) ;
380 lib
= Str_creTSD( module
) ;
382 rc
= rex_rxfuncdlladd( TSD
, ext
, lib
, intr
) ;
383 Free_stringTSD( ext
);
384 Free_stringTSD( intr
);
385 Free_stringTSD( lib
);
388 TSD
= TSD
; /* keep compiler happy */
389 rxname
= rxname
; /* keep compiler happy */
390 module
= module
; /* keep compiler happy */
391 objnam
= objnam
; /* keep compiler happy */
397 streng
*rex_rxfuncdrop( tsd_t
*TSD
, cparamboxptr parms
)
402 struct library_func
*fptr
=NULL
;
405 checkparam( parms
, 1, 1 , "RXFUNCDROP" ) ;
406 name
= Str_upper( parms
->value
) ;
408 fptr
= find_library_func( TSD
, name
) ;
413 * if found OK, remove the function...
415 remove_function( TSD
, fptr
) ;
417 return int_to_streng( TSD
, 0 ) ;
420 *... otherwise fall through and try to remove from function
421 * loaded via RexxRegisterFunctionExe()
424 if (external_func( TSD
, name
) )
425 rc
= delfunc ( TSD
, name
) ;
428 return int_to_streng( TSD
, rc
) ; /* value of 1 indicates failure */
431 int rex_rxfuncdlldrop( tsd_t
*TSD
, const streng
* objnam
)
435 struct library_func
*fptr
=NULL
;
437 * try to find the function loaded from a dynamic library
439 fptr
=find_library_func(TSD
, objnam
);
443 * if found OK, remove the function...
445 remove_function( TSD
, fptr
);
450 *... otherwise fall through and try to remove from function
451 * loaded via RexxRegisterFunctionExe()
454 if (external_func( TSD
, objnam
) )
455 rc
= delfunc ( TSD
, objnam
);
458 return rc
; /* value of 0 indicates failure */
461 int rex_rxfuncdllquery( tsd_t
*TSD
, const streng
* objnam
)
464 struct library_func
*fptr
=NULL
;
466 * try to find the function loaded from a dynamic library
468 fptr
=find_library_func(TSD
, objnam
);
472 *... otherwise fall through and try to find the function
473 * loaded via RexxRegisterFunctionExe()
476 return((external_func( TSD
, objnam
)) ? 0 : 1 );
479 void *loaded_lib_func( const tsd_t
*TSD
, const streng
*name
)
482 struct library_func
*box
=NULL
;
484 box
= find_library_func( TSD
, name
) ;
485 return (void*)(box
) ;
487 TSD
= TSD
; /* keep compiler happy */
488 name
= name
; /* keep compiler happy */