difference() method
[imager.git] / dynaload.c
CommitLineData
02d1d628
AMH
1#include "dynaload.h"
2#include "XSUB.h" /* so we can compile on threaded perls */
3
b6cfd214
TC
4static symbol_table_t symbol_table={i_has_format,ICL_set_internal,ICL_info,
5 i_img_new,i_img_empty,i_img_empty_ch,i_img_exorcise,
6 i_img_info,i_img_setmask,i_img_getmask,
7 i_box,i_draw,i_arc,i_copyto,i_copyto_trans,i_rubthru};
8
9
02d1d628
AMH
10/* These functions are all shared - then comes platform dependant code */
11
12
13int getstr(void *hv_t,char *key,char **store) {
14 SV** svpp;
15 HV* hv=(HV*)hv_t;
16
17 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
18
19 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
20
21 svpp=hv_fetch(hv, key, strlen(key), 0);
22 *store=SvPV(*svpp, PL_na );
23
24 return 1;
25}
26
27int getint(void *hv_t,char *key,int *store) {
28 SV** svpp;
29 HV* hv=(HV*)hv_t;
30
31 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
32
33 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
34
35 svpp=hv_fetch(hv, key, strlen(key), 0);
36 *store=(int)SvIV(*svpp);
37 return 1;
38}
39
40int getdouble(void *hv_t,char* key,double *store) {
41 SV** svpp;
42 HV* hv=(HV*)hv_t;
43
44 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
45
46 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
47 svpp=hv_fetch(hv, key, strlen(key), 0);
48 *store=(float)SvNV(*svpp);
49 return 1;
50}
51
52int getvoid(void *hv_t,char* key,void **store) {
53 SV** svpp;
54 HV* hv=(HV*)hv_t;
55
56 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
57
58 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
59
60 svpp=hv_fetch(hv, key, strlen(key), 0);
61 *store=(void*)SvIV(*svpp);
62
63 return 1;
64}
65
66int getobj(void *hv_t,char *key,char *type,void **store) {
67 SV** svpp;
68 HV* hv=(HV*)hv_t;
69
70 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
71
72 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
73
74 svpp=hv_fetch(hv, key, strlen(key), 0);
75
76 if (sv_derived_from(*svpp,type)) {
77 IV tmp = SvIV((SV*)SvRV(*svpp));
78 *store = (void*) tmp;
79 } else {
80 mm_log((1,"getobj: key exists in hash but is not of correct type"));
81 return 0;
82 }
83
84 return 1;
85}
86
87
88UTIL_table_t UTIL_table={getstr,getint,getdouble,getvoid,getobj};
02d1d628
AMH
89
90/*
91 Dynamic loading works like this:
92 dynaload opens the shared object and
93 loads all the functions into an array of functions
94 it returns a string from the dynamic function that
95 can be supplied to the parser for evaling.
96*/
97
98void
99DSO_call(DSO_handle *handle,int func_index,HV* hv) {
100 mm_log((1,"DSO_call(handle 0x%X, func_index %d, hv 0x%X)\n",handle,func_index,hv));
101 (handle->function_list[func_index].iptr)((void*)hv);
102}
103
104
105#if defined( OS_hpux )
106
107void*
108DSO_open(char* file,char** evalstring) {
109 shl_t tt_handle;
110 void *d_handle,**plugin_symtab,**plugin_utiltab;
111 int rc,*iptr, (*fptr)(int);
112 func_ptr *function_list;
113 DSO_handle *dso_handle;
114 void (*f)(void *s,void *u); /* these will just have to be void for now */
115 int i;
116
117 *evalstring=NULL;
118
119 mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
120
121 if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL;
122 if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL;
123
124 /*
125 if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL;
126 if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL;
127 (*plugin_symtab)=&symbol_table;
128 (*plugin_utiltab)=&UTIL_table;
129 */
130
131 if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL;
132
133 mm_log( (1,"Calling install_tables\n") );
134 f(&symbol_table,&UTIL_table);
135 mm_log( (1,"Call ok.\n") );
136
137 if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL;
138 if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) return NULL;
139
140 dso_handle->handle=tt_handle; /* needed to close again */
141 dso_handle->function_list=function_list;
142 if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; }
143 strcpy(dso_handle->filename,file);
144
145 mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
146 return (void*)dso_handle;
147}
148
149undef_int
150DSO_close(void *ptr) {
151 DSO_handle *handle=(DSO_handle*) ptr;
152 mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
153 return !shl_unload((handle->handle));
154}
155
156#elif defined(WIN32)
157
158void *
159DSO_open(char *file, char **evalstring) {
160 HMODULE d_handle;
161 func_ptr *function_list;
162 DSO_handle *dso_handle;
163
164 void (*f)(void *s,void *u); /* these will just have to be void for now */
165
166 mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
167
168 *evalstring = NULL;
169 if ((d_handle = LoadLibrary(file)) == NULL) {
170 mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
171 return NULL;
172 }
173 if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
174 mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
175 FreeLibrary(d_handle);
176 return NULL;
177 }
178 if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
179 mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
180 FreeLibrary(d_handle);
181 return NULL;
182 }
183 mm_log((1, "Calling install tables\n"));
184 f(&symbol_table, &UTIL_table);
185 mm_log((1, "Call ok\n"));
186
187 if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
188 mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
189 FreeLibrary(d_handle);
190 return NULL;
191 }
192 if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) {
193 mm_log( (1, "DSO_Open: out of memory\n") );
194 FreeLibrary(d_handle);
195 return NULL;
196 }
197 dso_handle->handle=d_handle; /* needed to close again */
198 dso_handle->function_list=function_list;
199 if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); FreeLibrary(d_handle); return NULL; }
200 strcpy(dso_handle->filename,file);
201
202 mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
203 return (void*)dso_handle;
204
205}
206
207undef_int
208DSO_close(void *ptr) {
209 DSO_handle *handle = (DSO_handle *)ptr;
210 FreeLibrary(handle->handle);
211 free(handle->filename);
212 free(handle);
213}
214
215#else
216
217/* OS/2 has no dlclose; Perl doesn't provide one. */
218#ifdef __EMX__ /* OS/2 */
219int
220dlclose(minthandle_t h) {
221 return DosFreeModule(h) ? -1 : 0;
222}
223#endif /* __EMX__ */
224
b6cfd214
TC
225#ifdef OS_darwin
226
227#import <mach-o/dyld.h>
228
229static char *dl_error = "unknown";
230
231static char *dlopen(char *path, int mode /* mode is ignored */)
232{
233 int dyld_result;
234 NSObjectFileImage ofile;
235 NSModule handle = NULL;
236
237
238
239 dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
240 if (dyld_result != NSObjectFileImageSuccess)
241 {
242 switch (dyld_result) {
243 case NSObjectFileImageFailure:
244 dl_error = "object file setup failure";
245 break;
246 case NSObjectFileImageInappropriateFile:
247 dl_error = "not a Mach-O MH_BUNDLE file type";
248 break;
249 case NSObjectFileImageArch:
250 dl_error = "no object for this architecture";
251 break;
252 case NSObjectFileImageFormat:
253 dl_error = "bad object file format";
254 break;
255 case NSObjectFileImageAccess:
256 dl_error = "can't read object file";
257 break;
258 default:
259 dl_error = "unknown error from NSCreateObjectFileImageFromFile()";
260 break;
261 }
262 }
263 else
264 {
265 // NSLinkModule will cause the run to abort on any link error's
266 // not very friendly but the error recovery functionality is limited.
267 handle = NSLinkModule(ofile, path, TRUE);
268 }
269
270 return handle;
271}
272
560a3a0a
TC
273static void *
274dlsym(void *handle, char *symbol)
b6cfd214
TC
275{
276 void *addr;
277
278 if (NSIsSymbolNameDefined(symbol))
279 {
280 addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
281 }
282 else
283 {
284 dl_error = "cannot find symbol";
285 addr = NULL;
286 }
287
288 return addr;
289}
290
560a3a0a 291static int dlclose(void *handle) /* stub only */
b6cfd214
TC
292{
293 return 0;
294}
295
4ede8fe2 296static char *dlerror(void) /* stub only */
b6cfd214 297{
560a3a0a 298 printf("Error occurred\n");
b6cfd214
TC
299 return dl_error;
300}
301
302#define RTLD_LAZY 0
303
304#endif
02d1d628
AMH
305
306void*
307DSO_open(char* file,char** evalstring) {
308 void *d_handle;
309 func_ptr *function_list;
310 DSO_handle *dso_handle;
311
312 void (*f)(void *s,void *u); /* these will just have to be void for now */
313
314 *evalstring=NULL;
315
316 mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
317
318 if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
319 mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
320 return NULL;
321 }
322
323 if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
324 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
325 return NULL;
326 }
327
328 /*
329
330 I'll just leave this thing in here for now if I need it real soon
331
332 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
333 if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
334 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
335 return NULL;
336 }
337
338 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
339 if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
340 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
341 return NULL;
342 }
343
344 */
345
346 f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
347 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
348 if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
349 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
350 return NULL;
351 }
352
353 mm_log( (1,"Calling install_tables\n") );
354 f(&symbol_table,&UTIL_table);
355 mm_log( (1,"Call ok.\n") );
356
357 /* (*plugin_symtab)=&symbol_table;
358 (*plugin_utiltab)=&UTIL_table; */
359
360 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
361 if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
362 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
363 return NULL;
364 }
365
366 if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) return NULL;
367
368 dso_handle->handle=d_handle; /* needed to close again */
369 dso_handle->function_list=function_list;
370 if ( (dso_handle->filename=(char*)malloc(strlen(file))) == NULL) { free(dso_handle); return NULL; }
371 strcpy(dso_handle->filename,file);
372
373 mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
374 return (void*)dso_handle;
375}
376
377undef_int
378DSO_close(void *ptr) {
379 DSO_handle *handle;
380 mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
381 handle=(DSO_handle*) ptr;
382 return !dlclose(handle->handle);
383}
384
385#endif
386