]>
Commit | Line | Data |
---|---|---|
c90f71dd RD |
1 | #include "EXTERN.h" |
2 | #include "perl.h" | |
3 | #include "XSUB.h" | |
4 | /* Definitions for compiling Perl extensions on a variety of machines */ | |
5 | ||
6 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | |
7 | # if defined(_MSC_VER) | |
8 | # define SWIGEXPORT(a) __declspec(dllexport) a | |
9 | # else | |
10 | # if defined(__BORLANDC__) | |
11 | # define SWIGEXPORT(a) a _export | |
12 | # else | |
13 | # define SWIGEXPORT(a) a | |
14 | # endif | |
15 | # endif | |
16 | #else | |
17 | # define SWIGEXPORT(a) a | |
18 | #endif | |
19 | ||
20 | #ifdef PERL_OBJECT | |
21 | #define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; | |
22 | #define MAGIC_CAST (int (CPerlObj::*)(SV *, MAGIC *)) | |
23 | #define SWIGCLASS_STATIC | |
24 | #else | |
25 | #define MAGIC_PPERL | |
26 | #define MAGIC_CAST | |
27 | #define SWIGCLASS_STATIC static | |
28 | #endif | |
29 | ||
30 | #if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) | |
31 | #define PerlIO_exportFILE(fh,fl) (FILE*)(fh) | |
32 | #endif | |
33 | ||
34 | /* Modifications for newer Perl 5.005 releases */ | |
35 | ||
36 | #if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) | |
37 | #ifndef PL_sv_yes | |
38 | #define PL_sv_yes sv_yes | |
39 | #endif | |
40 | #ifndef PL_sv_undef | |
41 | #define PL_sv_undef sv_undef | |
42 | #endif | |
43 | #ifndef PL_na | |
44 | #define PL_na na | |
45 | #endif | |
46 | #endif | |
47 | ||
48 | /****************************************************************************** | |
49 | * Pointer type-checking code | |
50 | *****************************************************************************/ | |
51 | ||
52 | #include <stdlib.h> | |
53 | ||
54 | #ifdef __cplusplus | |
55 | extern "C" { | |
56 | #endif | |
57 | ||
58 | #ifdef SWIG_NOINCLUDE | |
59 | extern void SWIG_MakePtr(char *, void *, char *); | |
60 | #ifndef PERL_OBJECT | |
61 | extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); | |
62 | #else | |
63 | #define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl,a,b,c); | |
64 | extern void _SWIG_RegisterMapping(CPerlObj *,char *, char *, void *(*)(void *),int); | |
65 | #endif | |
66 | #ifndef PERL_OBJECT | |
67 | extern char *SWIG_GetPtr(SV *, void **, char *); | |
68 | #else | |
69 | extern char *_SWIG_GetPtr(CPerlObj *, SV *, void **, char *); | |
70 | #define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) | |
71 | #endif | |
72 | ||
73 | #else | |
74 | ||
75 | #ifdef SWIG_GLOBAL | |
76 | #define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) | |
77 | #else | |
78 | #define SWIGSTATICRUNTIME(a) static a | |
79 | #endif | |
80 | ||
81 | /* These are internal variables. Should be static */ | |
82 | ||
83 | typedef struct SwigPtrType { | |
84 | char *name; | |
85 | int len; | |
86 | void *(*cast)(void *); | |
87 | struct SwigPtrType *next; | |
88 | } SwigPtrType; | |
89 | ||
90 | /* Pointer cache structure */ | |
91 | ||
92 | typedef struct { | |
93 | int stat; /* Status (valid) bit */ | |
94 | SwigPtrType *tp; /* Pointer to type structure */ | |
95 | char name[256]; /* Given datatype name */ | |
96 | char mapped[256]; /* Equivalent name */ | |
97 | } SwigCacheType; | |
98 | ||
99 | static int SwigPtrMax = 64; /* Max entries that can be currently held */ | |
100 | static int SwigPtrN = 0; /* Current number of entries */ | |
101 | static int SwigPtrSort = 0; /* Status flag indicating sort */ | |
102 | static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ | |
103 | static int SwigStart[256]; /* Table containing starting positions */ | |
104 | ||
105 | /* Cached values */ | |
106 | ||
107 | #define SWIG_CACHESIZE 8 | |
108 | #define SWIG_CACHEMASK 0x7 | |
109 | static SwigCacheType SwigCache[SWIG_CACHESIZE]; | |
110 | static int SwigCacheIndex = 0; | |
111 | static int SwigLastCache = 0; | |
112 | ||
113 | /* Sort comparison function */ | |
114 | static int swigsort(const void *data1, const void *data2) { | |
115 | SwigPtrType *d1 = (SwigPtrType *) data1; | |
116 | SwigPtrType *d2 = (SwigPtrType *) data2; | |
117 | return strcmp(d1->name,d2->name); | |
118 | } | |
119 | ||
120 | /* Binary Search function */ | |
121 | static int swigcmp(const void *key, const void *data) { | |
122 | char *k = (char *) key; | |
123 | SwigPtrType *d = (SwigPtrType *) data; | |
124 | return strncmp(k,d->name,d->len); | |
125 | } | |
126 | ||
127 | /* Register a new datatype with the type-checker */ | |
128 | ||
129 | #ifndef PERL_OBJECT | |
130 | SWIGSTATICRUNTIME(void) | |
131 | SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { | |
132 | #else | |
133 | #define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl, a,b,c) | |
134 | SWIGSTATICRUNTIME(void) | |
135 | _SWIG_RegisterMapping(CPerlObj *pPerl, char *origtype, char *newtype, void *(*cast)(void *)) { | |
136 | #endif | |
137 | ||
138 | int i; | |
139 | SwigPtrType *t = 0, *t1; | |
140 | ||
141 | if (!SwigPtrTable) { | |
142 | SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); | |
143 | SwigPtrN = 0; | |
144 | } | |
145 | if (SwigPtrN >= SwigPtrMax) { | |
146 | SwigPtrMax = 2*SwigPtrMax; | |
147 | SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); | |
148 | } | |
149 | for (i = 0; i < SwigPtrN; i++) | |
150 | if (strcmp(SwigPtrTable[i].name,origtype) == 0) { | |
151 | t = &SwigPtrTable[i]; | |
152 | break; | |
153 | } | |
154 | if (!t) { | |
155 | t = &SwigPtrTable[SwigPtrN]; | |
156 | t->name = origtype; | |
157 | t->len = strlen(t->name); | |
158 | t->cast = 0; | |
159 | t->next = 0; | |
160 | SwigPtrN++; | |
161 | } | |
162 | while (t->next) { | |
163 | if (strcmp(t->name,newtype) == 0) { | |
164 | if (cast) t->cast = cast; | |
165 | return; | |
166 | } | |
167 | t = t->next; | |
168 | } | |
169 | t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); | |
170 | t1->name = newtype; | |
171 | t1->len = strlen(t1->name); | |
172 | t1->cast = cast; | |
173 | t1->next = 0; | |
174 | t->next = t1; | |
175 | SwigPtrSort = 0; | |
176 | } | |
177 | ||
178 | /* Make a pointer value string */ | |
179 | ||
180 | SWIGSTATICRUNTIME(void) | |
181 | SWIG_MakePtr(char *_c, const void *_ptr, char *type) { | |
182 | static char _hex[16] = | |
183 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', | |
184 | 'a', 'b', 'c', 'd', 'e', 'f'}; | |
185 | unsigned long _p, _s; | |
186 | char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ | |
187 | _r = _result; | |
188 | _p = (unsigned long) _ptr; | |
189 | if (_p > 0) { | |
190 | while (_p > 0) { | |
191 | _s = _p & 0xf; | |
192 | *(_r++) = _hex[_s]; | |
193 | _p = _p >> 4; | |
194 | } | |
195 | *_r = '_'; | |
196 | while (_r >= _result) | |
197 | *(_c++) = *(_r--); | |
198 | } else { | |
199 | strcpy (_c, "NULL"); | |
200 | } | |
201 | if (_ptr) | |
202 | strcpy (_c, type); | |
203 | } | |
204 | ||
205 | /* Function for getting a pointer value */ | |
206 | ||
207 | #ifndef PERL_OBJECT | |
208 | SWIGSTATICRUNTIME(char *) | |
209 | SWIG_GetPtr(SV *sv, void **ptr, char *_t) | |
210 | #else | |
211 | #define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) | |
212 | SWIGSTATICRUNTIME(char *) | |
213 | _SWIG_GetPtr(CPerlObj *pPerl, SV *sv, void **ptr, char *_t) | |
214 | #endif | |
215 | { | |
216 | char temp_type[256]; | |
217 | char *name,*_c; | |
218 | int len,i,start,end; | |
219 | IV tmp; | |
220 | SwigPtrType *sp,*tp; | |
221 | SwigCacheType *cache; | |
222 | ||
223 | /* If magical, apply more magic */ | |
224 | ||
225 | if (SvGMAGICAL(sv)) | |
226 | mg_get(sv); | |
227 | ||
228 | /* Check to see if this is an object */ | |
229 | if (sv_isobject(sv)) { | |
230 | SV *tsv = (SV*) SvRV(sv); | |
231 | if ((SvTYPE(tsv) == SVt_PVHV)) { | |
232 | MAGIC *mg; | |
233 | if (SvMAGICAL(tsv)) { | |
234 | mg = mg_find(tsv,'P'); | |
235 | if (mg) { | |
236 | SV *rsv = mg->mg_obj; | |
237 | if (sv_isobject(rsv)) { | |
238 | tmp = SvIV((SV*)SvRV(rsv)); | |
239 | } | |
240 | } | |
241 | } else { | |
242 | return "Not a valid pointer value"; | |
243 | } | |
244 | } else { | |
245 | tmp = SvIV((SV*)SvRV(sv)); | |
246 | } | |
247 | if (!_t) { | |
248 | *(ptr) = (void *) tmp; | |
249 | return (char *) 0; | |
250 | } | |
251 | } else if (! SvOK(sv)) { /* Check for undef */ | |
252 | *(ptr) = (void *) 0; | |
253 | return (char *) 0; | |
254 | } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ | |
255 | *(ptr) = (void *) 0; | |
256 | if (!SvROK(sv)) | |
257 | return (char *) 0; | |
258 | else | |
259 | return "Not a valid pointer value"; | |
260 | } else { /* Don't know what it is */ | |
261 | *(ptr) = (void *) 0; | |
262 | return "Not a valid pointer value"; | |
263 | } | |
264 | if (_t) { | |
265 | /* Now see if the types match */ | |
266 | ||
267 | if (!sv_isa(sv,_t)) { | |
268 | _c = HvNAME(SvSTASH(SvRV(sv))); | |
269 | if (!SwigPtrSort) { | |
270 | qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); | |
271 | for (i = 0; i < 256; i++) { | |
272 | SwigStart[i] = SwigPtrN; | |
273 | } | |
274 | for (i = SwigPtrN-1; i >= 0; i--) { | |
275 | SwigStart[SwigPtrTable[i].name[0]] = i; | |
276 | } | |
277 | for (i = 255; i >= 1; i--) { | |
278 | if (SwigStart[i-1] > SwigStart[i]) | |
279 | SwigStart[i-1] = SwigStart[i]; | |
280 | } | |
281 | SwigPtrSort = 1; | |
282 | for (i = 0; i < SWIG_CACHESIZE; i++) | |
283 | SwigCache[i].stat = 0; | |
284 | } | |
285 | /* First check cache for matches. Uses last cache value as starting point */ | |
286 | cache = &SwigCache[SwigLastCache]; | |
287 | for (i = 0; i < SWIG_CACHESIZE; i++) { | |
288 | if (cache->stat) { | |
289 | if (strcmp(_t,cache->name) == 0) { | |
290 | if (strcmp(_c,cache->mapped) == 0) { | |
291 | cache->stat++; | |
292 | *ptr = (void *) tmp; | |
293 | if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); | |
294 | return (char *) 0; | |
295 | } | |
296 | } | |
297 | } | |
298 | SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; | |
299 | if (!SwigLastCache) cache = SwigCache; | |
300 | else cache++; | |
301 | } | |
302 | ||
303 | start = SwigStart[_t[0]]; | |
304 | end = SwigStart[_t[0]+1]; | |
305 | sp = &SwigPtrTable[start]; | |
306 | while (start < end) { | |
307 | if (swigcmp(_t,sp) == 0) break; | |
308 | sp++; | |
309 | start++; | |
310 | } | |
311 | if (start > end) sp = 0; | |
312 | while (start <= end) { | |
313 | if (swigcmp(_t,sp) == 0) { | |
314 | name = sp->name; | |
315 | len = sp->len; | |
316 | tp = sp->next; | |
317 | while(tp) { | |
318 | if (tp->len >= 255) { | |
319 | return _c; | |
320 | } | |
321 | strcpy(temp_type,tp->name); | |
322 | strncat(temp_type,_t+len,255-tp->len); | |
323 | if (sv_isa(sv,temp_type)) { | |
324 | /* Get pointer value */ | |
325 | *ptr = (void *) tmp; | |
326 | if (tp->cast) *ptr = (*(tp->cast))(*ptr); | |
327 | ||
328 | strcpy(SwigCache[SwigCacheIndex].mapped,_c); | |
329 | strcpy(SwigCache[SwigCacheIndex].name,_t); | |
330 | SwigCache[SwigCacheIndex].stat = 1; | |
331 | SwigCache[SwigCacheIndex].tp = tp; | |
332 | SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; | |
333 | return (char *) 0; | |
334 | } | |
335 | tp = tp->next; | |
336 | } | |
337 | } | |
338 | sp++; | |
339 | start++; | |
340 | } | |
341 | /* Didn't find any sort of match for this data. | |
342 | Get the pointer value and return the received type */ | |
343 | *ptr = (void *) tmp; | |
344 | return _c; | |
345 | } else { | |
346 | /* Found a match on the first try. Return pointer value */ | |
347 | *ptr = (void *) tmp; | |
348 | return (char *) 0; | |
349 | } | |
350 | } | |
351 | *ptr = (void *) tmp; | |
352 | return (char *) 0; | |
353 | } | |
354 | ||
355 | #endif | |
356 | #ifdef __cplusplus | |
357 | } | |
358 | #endif | |
359 | ||
360 | ||
361 | ||
362 | ||
363 | ||
364 |