Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: swig/Lib/typemaps/fragments.swg

Issue 553095: Checkin swig binaries for win, linux and Mac... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/
Patch Set: '' Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « swig/Lib/typemaps/factory.swg ('k') | swig/Lib/typemaps/implicit.swg » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « swig/Lib/typemaps/factory.swg ('k') | swig/Lib/typemaps/implicit.swg » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698