OLD | NEW |
(Empty) | |
| 1 /* |
| 2 Fragments: |
| 3 ========== |
| 4 |
| 5 Second to typemaps, fragments are one the most powerful and |
| 6 dangerous swig features. So, if you are starting to read about them, |
| 7 make sure you read all of this document. |
| 8 |
| 9 Basics: |
| 10 ======= |
| 11 |
| 12 Fragments provide a way to include or generate code into "on-demand" |
| 13 as the typemaps could require. |
| 14 |
| 15 For example, if you have a very long typemap |
| 16 |
| 17 %typemap(in) MyClass * { |
| 18 MyClass *value = 0; |
| 19 |
| 20 <very long typemap> |
| 21 .... |
| 22 value = somewhere_converted_from_input_object_here($input); |
| 23 ... |
| 24 <very long typemap> |
| 25 |
| 26 $result = value; |
| 27 } |
| 28 |
| 29 very soon you will discover yourself copying the same long |
| 30 conversion code in several typemaps, such as varin, directorout, |
| 31 etc. Also, you will discover that swig copes verbatim the same very |
| 32 long conversion code for every argument that requires it, making the |
| 33 code very large too. |
| 34 |
| 35 To eliminate this automatic or manual code copying, we define a |
| 36 fragment that includes the common conversion code: |
| 37 |
| 38 %fragment("AsMyClass","header") { |
| 39 MyClass *AsMyClass(PyObject *obj) { |
| 40 MyClass *value = 0; |
| 41 <very long conversion> |
| 42 .... |
| 43 value = somewhere_converted_from_input_object_here(obj); |
| 44 ... |
| 45 <very long conversion> |
| 46 |
| 47 return value; |
| 48 } |
| 49 } |
| 50 |
| 51 %typemap(in,fragment="AsMyClass") MyClass * { |
| 52 $result = AsMyClass($input); |
| 53 } |
| 54 |
| 55 %typemap(varin,fragment="AsMyClass") MyClass * { |
| 56 $result = AsMyClass($input); |
| 57 } |
| 58 |
| 59 When the 'in' or 'varin' typemaps for MyClass are invoked, the |
| 60 fragment "AsMyClass" is added to the "header" section, and then the |
| 61 typemap code is emitted. Hence, the method AsMyClass will be |
| 62 included in the wrapping code and it will be available at the time |
| 63 the typemap is applied. |
| 64 |
| 65 To define a fragment then you need a name, a section where it goes, |
| 66 and the code. Usually the section refers to the "header" part, and |
| 67 both string and braces forms are accepted, ie: |
| 68 |
| 69 %fragment("my_name","header") { ... } |
| 70 %fragment("my_name","header") "..."; |
| 71 |
| 72 To ensure all the fragment/typemap engine works as expected, there |
| 73 are some rules that fragments follow: |
| 74 |
| 75 1.- A fragment is added to the wrapping code only once, ie, for the |
| 76 method: |
| 77 |
| 78 int foo(MyClass *a, MyClass *b); |
| 79 |
| 80 the wrapped code will look as much as: |
| 81 |
| 82 MyClass *AsMyClass(PyObject *obj) { |
| 83 ..... |
| 84 } |
| 85 |
| 86 int _wrap_foo(...) { |
| 87 .... |
| 88 arg1 = AsMyClass(obj1); |
| 89 arg2 = AsMyClass(obj2); |
| 90 ... |
| 91 result = foo(arg1, arg2); |
| 92 } |
| 93 |
| 94 |
| 95 even when there will be duplicated typemap to process 'a' and |
| 96 'b', the 'AsMyClass' method will be defined only once. |
| 97 |
| 98 |
| 99 2.- A fragment can only defined once, and the first definition |
| 100 is the only one taking in account. All other definitions of the |
| 101 same fragments are silently ignored. For example, you can have |
| 102 |
| 103 |
| 104 %fragment("AsMyClass","header") { <definition 1> } |
| 105 .... |
| 106 %fragment("AsMyClass","header") { <definition 2> } |
| 107 |
| 108 and then only the first definition is considered. In this way |
| 109 you can change the 'system' fragments by including yours first. |
| 110 |
| 111 Note that this behavior is opposite to the typemaps, where the |
| 112 last typemap applied or defined prevails. Fragment follows the |
| 113 first-in-first-out convention since they are intended to be |
| 114 "global", while typemaps intend to be "locally" specialized. |
| 115 |
| 116 3.- Fragments names can not contain commas. |
| 117 |
| 118 |
| 119 A fragment can include one or more additional fragments, for example: |
| 120 |
| 121 %fragment("<limits.h>", "header") { |
| 122 #include <limits.h> |
| 123 } |
| 124 |
| 125 |
| 126 %fragment("AsMyClass", "header", fragment="<limits.h>") { |
| 127 MyClass *AsMyClass(PyObject *obj) { |
| 128 MyClass *value = 0; |
| 129 int ival = somewhere_converted_from_input_object_here(obj) |
| 130 ... |
| 131 if (ival < CHAR_MIN) { |
| 132 value = something_from_ival(ival); |
| 133 } else { |
| 134 ... |
| 135 } |
| 136 ... |
| 137 return value; |
| 138 } |
| 139 } |
| 140 |
| 141 in this case, when the "AsMyClass" fragment is emitted, it also |
| 142 trigger the inclusion of the "<limits.h>" fragment. |
| 143 |
| 144 You can add as many fragments as you want, for example |
| 145 |
| 146 %fragment("bigfragment","header", fragment="frag1", fragment="frag2", fragme
nt="frag3") ""; |
| 147 |
| 148 here, when the "bigfragment" is included, the three fragments "frag1", |
| 149 "frag2" and "frag3" are included. Note that as "bigframent" is defined |
| 150 empty, "", it does not add any code by itself, buy only trigger the |
| 151 inclusion of the other fragments. |
| 152 |
| 153 In a typemap you can also include more than one fragment, but since the |
| 154 syntax is different, you need to specify them in a 'comma separated' |
| 155 list, for example, considering the previous example: |
| 156 |
| 157 %typemap(in,fragment="frag1,frag2,frag3") {...} |
| 158 |
| 159 is equivalent to |
| 160 |
| 161 %typemap(in,fragment="bigfragment") {...} |
| 162 |
| 163 |
| 164 Finally, you can force the inclusion of a fragment at any moment as follow: |
| 165 |
| 166 %fragment("bigfragment"); |
| 167 |
| 168 which is very useful inside a template class, for example. |
| 169 |
| 170 |
| 171 Fragment type specialization |
| 172 ============================ |
| 173 |
| 174 Fragments can be "type specialized". The syntax is as follows |
| 175 |
| 176 %fragment("name","header") { a type independent fragment } |
| 177 %fragment("name" {Type}, "header") { a type dependent fragment } |
| 178 |
| 179 and they can also, as typemaps, be used inside templates, for exampe: |
| 180 |
| 181 template <class T> |
| 182 struct A { |
| 183 %fragment("incode"{A<T>},"header") { |
| 184 'incode' specialized fragment |
| 185 } |
| 186 |
| 187 %typemap(in,fragment="incode"{A<T>}) { |
| 188 here we use the 'type specialized' |
| 189 fragment "incode"{A<T>} |
| 190 } |
| 191 }; |
| 192 |
| 193 which could seems a not much interesting feature, but is |
| 194 fundamental for automatic typemap and template specialization. |
| 195 |
| 196 |
| 197 Fragments and automatic typemap specialization: |
| 198 =============================================== |
| 199 |
| 200 Since fragments can be type specialized, they can be elegantly used |
| 201 to specialized typemaps . |
| 202 |
| 203 For example, if you have something like: |
| 204 |
| 205 %fragment("incode"{float}, "header") { |
| 206 float in_method_float(PyObject *obj) { |
| 207 ... |
| 208 } |
| 209 } |
| 210 |
| 211 %fragment("incode"{long}, "header") { |
| 212 float in_method_long(PyObject *obj) { |
| 213 ... |
| 214 } |
| 215 } |
| 216 |
| 217 %define %my_typemaps(Type) |
| 218 %typemaps(in,fragment="incode"{Type}) { |
| 219 value = in_method_##Type(obj); |
| 220 } |
| 221 %enddef |
| 222 |
| 223 %my_typemaps(float); |
| 224 %my_typemaps(long); |
| 225 |
| 226 then the proper "incode"{float,double} fragment will be included, |
| 227 and the proper in_method_{float,double} will be called. |
| 228 |
| 229 Since this is a recurrent fragment use, we provide a couple of |
| 230 macros that make the automatic generation of typemaps easier: |
| 231 |
| 232 |
| 233 Consider for example the following code: |
| 234 |
| 235 %fragment(SWIG_From_frag(bool),"header") { |
| 236 static PyObject* |
| 237 SWIG_From_dec(bool)(bool value) |
| 238 { |
| 239 PyObject *obj = value ? Py_True : Py_False; |
| 240 Py_INCREF(obj); |
| 241 return obj; |
| 242 } |
| 243 } |
| 244 |
| 245 %typemap(out,fragment=SWIG_From_frag(bool)) bool { |
| 246 $result = SWIG_From(bool)($1)); |
| 247 } |
| 248 |
| 249 Here the macros |
| 250 |
| 251 SWIG_From_frag => fragment |
| 252 SWIG_From_dec => declaration |
| 253 SWIG_From => call |
| 254 |
| 255 allow you to define/include a fragment, and declare and call the |
| 256 'from-bool' method as needed. In the simpler case, these macros |
| 257 just return something like |
| 258 |
| 259 SWIG_From_frag(bool) => "SWIG_From_bool" |
| 260 SWIG_From_dec(bool) => SWIG_From_bool |
| 261 SWIG_From(bool) => SWIG_From_bool |
| 262 |
| 263 But they are specialized for the different languages requirements, |
| 264 such as perl or tcl that requires passing the interpreter pointer, |
| 265 and also they can manage C++ ugly types, for example: |
| 266 |
| 267 SWIG_From_frag(std::complex<double>) => "SWIG_From_std_complex_Sl_double_
Sg_" |
| 268 SWIG_From_dec(std::complex<double>) => SWIG_From_std_complex_Sl_double_
Sg_ |
| 269 SWIG_From(std::complex<double>) => SWIG_From_std_complex_Sl_double_
Sg_ |
| 270 |
| 271 |
| 272 Hence, to declare methods to use with typemaps, always use the |
| 273 SWIG_From* macros. In the same way, the SWIG_AsVal* and SWIG_AsPtr* |
| 274 set of macros are provided. |
| 275 |
| 276 */ |
| 277 |
| 278 |
| 279 /* ----------------------------------------------------------------------------- |
| 280 * Define the basic macros to 'normalize' the type fragments |
| 281 * -----------------------------------------------------------------------------
*/ |
| 282 |
| 283 #ifndef SWIG_AS_DECL_ARGS |
| 284 #define SWIG_AS_DECL_ARGS |
| 285 #endif |
| 286 |
| 287 #ifndef SWIG_FROM_DECL_ARGS |
| 288 #define SWIG_FROM_DECL_ARGS |
| 289 #endif |
| 290 |
| 291 #ifndef SWIG_AS_CALL_ARGS |
| 292 #define SWIG_AS_CALL_ARGS |
| 293 #endif |
| 294 |
| 295 #ifndef SWIG_FROM_CALL_ARGS |
| 296 #define SWIG_FROM_CALL_ARGS |
| 297 #endif |
| 298 |
| 299 #define %fragment_name(Name, Type...) %string_name(Name) "_" {Type} |
| 300 |
| 301 #define SWIG_Traits_frag(Type...) %fragment_name(Traits, Type) |
| 302 #define SWIG_AsPtr_frag(Type...) %fragment_name(AsPtr, Type) |
| 303 #define SWIG_AsVal_frag(Type...) %fragment_name(AsVal, Type) |
| 304 #define SWIG_From_frag(Type...) %fragment_name(From, Type) |
| 305 |
| 306 #define SWIG_AsVal_name(Type...) %symbol_name(AsVal, Type) |
| 307 #define SWIG_AsPtr_name(Type...) %symbol_name(AsPtr, Type) |
| 308 #define SWIG_From_name(Type...) %symbol_name(From, Type) |
| 309 |
| 310 #define SWIG_AsVal_dec(Type...) SWIG_AsVal_name(Type) SWIG_AS_DECL_ARGS |
| 311 #define SWIG_AsPtr_dec(Type...) SWIG_AsPtr_name(Type) SWIG_AS_DECL_ARGS |
| 312 #define SWIG_From_dec(Type...) SWIG_From_name(Type) SWIG_FROM_DECL_ARGS |
| 313 |
| 314 #define SWIG_AsVal(Type...) SWIG_AsVal_name(Type) SWIG_AS_CALL_ARGS |
| 315 #define SWIG_AsPtr(Type...) SWIG_AsPtr_name(Type) SWIG_AS_CALL_ARGS
|
| 316 #define SWIG_From(Type...) SWIG_From_name(Type) SWIG_FROM_CALL_ARGS |
| 317 |
| 318 /* ------------------------------------------------------------ |
| 319 * common fragments |
| 320 * ------------------------------------------------------------ */ |
| 321 |
| 322 /* Default compiler options for gcc allow long_long but not LLONG_MAX. |
| 323 * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ |
| 324 %fragment("<limits.h>","header") %{ |
| 325 #include <limits.h> |
| 326 #if !defined(SWIG_NO_LLONG_MAX) |
| 327 # if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) |
| 328 # define LLONG_MAX __LONG_LONG_MAX__ |
| 329 # define LLONG_MIN (-LLONG_MAX - 1LL) |
| 330 # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) |
| 331 # endif |
| 332 #endif |
| 333 %} |
| 334 |
| 335 %fragment("<math.h>","header") %{ |
| 336 #include <math.h> |
| 337 %} |
| 338 |
| 339 %fragment("<wchar.h>","header") %{ |
| 340 #include <wchar.h> |
| 341 #include <limits.h> |
| 342 #ifndef WCHAR_MIN |
| 343 # define WCHAR_MIN 0 |
| 344 #endif |
| 345 #ifndef WCHAR_MAX |
| 346 # define WCHAR_MAX 65535 |
| 347 #endif |
| 348 %} |
| 349 |
| 350 %fragment("<float.h>","header") %{ |
| 351 #include <float.h> |
| 352 %} |
| 353 |
| 354 %fragment("<stdio.h>","header") %{ |
| 355 #include <stdio.h> |
| 356 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) |
| 357 # ifndef snprintf |
| 358 # define snprintf _snprintf |
| 359 # endif |
| 360 #endif |
| 361 %} |
| 362 |
| 363 %fragment("<stdlib.h>","header") %{ |
| 364 #include <stdlib.h> |
| 365 #ifdef _MSC_VER |
| 366 # ifndef strtoull |
| 367 # define strtoull _strtoui64 |
| 368 # endif |
| 369 # ifndef strtoll |
| 370 # define strtoll _strtoi64 |
| 371 # endif |
| 372 #endif |
| 373 %} |
| 374 |
| 375 /* ----------------------------------------------------------------------------- |
| 376 * special macros for fragments |
| 377 * -----------------------------------------------------------------------------
*/ |
| 378 |
| 379 /* Macros to derive numeric types */ |
| 380 |
| 381 %define %numeric_type_from(Type, Base) |
| 382 %fragment(SWIG_From_frag(Type),"header", |
| 383 fragment=SWIG_From_frag(Base)) { |
| 384 SWIGINTERNINLINE SWIG_Object |
| 385 SWIG_From_dec(Type)(Type value) |
| 386 { |
| 387 return SWIG_From(Base)(value); |
| 388 } |
| 389 } |
| 390 %enddef |
| 391 |
| 392 %define %numeric_type_asval(Type, Base, Frag, OverflowCond) |
| 393 %fragment(SWIG_AsVal_frag(Type),"header", |
| 394 fragment=Frag, |
| 395 fragment=SWIG_AsVal_frag(Base)) { |
| 396 SWIGINTERN int |
| 397 SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val) |
| 398 { |
| 399 Base v; |
| 400 int res = SWIG_AsVal(Base)(obj, &v); |
| 401 if (SWIG_IsOK(res)) { |
| 402 if (OverflowCond) { |
| 403 return SWIG_OverflowError; |
| 404 } else { |
| 405 if (val) *val = %numeric_cast(v, Type); |
| 406 } |
| 407 } |
| 408 return res; |
| 409 } |
| 410 } |
| 411 %enddef |
| 412 |
| 413 #define %numeric_signed_type_asval(Type, Base, Frag, Min, Max) \ |
| 414 %numeric_type_asval(Type, Base, Frag, (v < Min || v > Max)) |
| 415 |
| 416 #define %numeric_unsigned_type_asval(Type, Base, Frag, Max) \ |
| 417 %numeric_type_asval(Type, Base, Frag, (v > Max)) |
| 418 |
| 419 |
| 420 /* Macro for 'signed long' derived types */ |
| 421 |
| 422 %define %numeric_slong(Type, Frag, Min, Max) |
| 423 %numeric_type_from(Type, long) |
| 424 %numeric_signed_type_asval(Type, long, Frag , Min, Max) |
| 425 %enddef |
| 426 |
| 427 /* Macro for 'unsigned long' derived types */ |
| 428 |
| 429 %define %numeric_ulong(Type, Frag, Max) |
| 430 %numeric_type_from(Type, unsigned long) |
| 431 %numeric_unsigned_type_asval(Type, unsigned long, Frag, Max) |
| 432 %enddef |
| 433 |
| 434 |
| 435 /* Macro for 'double' derived types */ |
| 436 |
| 437 %define %numeric_double(Type, Frag, Min, Max) |
| 438 %numeric_type_from(Type, double) |
| 439 %numeric_signed_type_asval(Type, double, Frag , Min, Max) |
| 440 %enddef |
| 441 |
| 442 |
| 443 /* Macros for missing fragments */ |
| 444 |
| 445 %define %ensure_fragment(Fragment) |
| 446 %fragment(`Fragment`,"header") { |
| 447 %#error "Swig language implementation must provide the Fragment fragment" |
| 448 } |
| 449 %enddef |
| 450 |
| 451 %define %ensure_type_fragments(Type) |
| 452 %fragment(SWIG_From_frag(Type),"header") { |
| 453 %#error "Swig language implementation must provide a SWIG_From_frag(Type) fragme
nt" |
| 454 } |
| 455 %fragment(SWIG_AsVal_frag(Type),"header") { |
| 456 %#error "Swig language implementation must provide a SWIG_AsVal_frag(Type) fragm
ent" |
| 457 } |
| 458 %enddef |
OLD | NEW |