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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « swig/Lib/typemaps/factory.swg ('k') | swig/Lib/typemaps/implicit.swg » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: swig/Lib/typemaps/fragments.swg
===================================================================
--- swig/Lib/typemaps/fragments.swg (revision 0)
+++ swig/Lib/typemaps/fragments.swg (revision 0)
@@ -0,0 +1,458 @@
+/*
+ Fragments:
+ ==========
+
+ Second to typemaps, fragments are one the most powerful and
+ dangerous swig features. So, if you are starting to read about them,
+ make sure you read all of this document.
+
+ Basics:
+ =======
+
+ Fragments provide a way to include or generate code into "on-demand"
+ as the typemaps could require.
+
+ For example, if you have a very long typemap
+
+ %typemap(in) MyClass * {
+ MyClass *value = 0;
+
+ <very long typemap>
+ ....
+ value = somewhere_converted_from_input_object_here($input);
+ ...
+ <very long typemap>
+
+ $result = value;
+ }
+
+ very soon you will discover yourself copying the same long
+ conversion code in several typemaps, such as varin, directorout,
+ etc. Also, you will discover that swig copes verbatim the same very
+ long conversion code for every argument that requires it, making the
+ code very large too.
+
+ To eliminate this automatic or manual code copying, we define a
+ fragment that includes the common conversion code:
+
+ %fragment("AsMyClass","header") {
+ MyClass *AsMyClass(PyObject *obj) {
+ MyClass *value = 0;
+ <very long conversion>
+ ....
+ value = somewhere_converted_from_input_object_here(obj);
+ ...
+ <very long conversion>
+
+ return value;
+ }
+ }
+
+ %typemap(in,fragment="AsMyClass") MyClass * {
+ $result = AsMyClass($input);
+ }
+
+ %typemap(varin,fragment="AsMyClass") MyClass * {
+ $result = AsMyClass($input);
+ }
+
+ When the 'in' or 'varin' typemaps for MyClass are invoked, the
+ fragment "AsMyClass" is added to the "header" section, and then the
+ typemap code is emitted. Hence, the method AsMyClass will be
+ included in the wrapping code and it will be available at the time
+ the typemap is applied.
+
+ To define a fragment then you need a name, a section where it goes,
+ and the code. Usually the section refers to the "header" part, and
+ both string and braces forms are accepted, ie:
+
+ %fragment("my_name","header") { ... }
+ %fragment("my_name","header") "...";
+
+ To ensure all the fragment/typemap engine works as expected, there
+ are some rules that fragments follow:
+
+ 1.- A fragment is added to the wrapping code only once, ie, for the
+ method:
+
+ int foo(MyClass *a, MyClass *b);
+
+ the wrapped code will look as much as:
+
+ MyClass *AsMyClass(PyObject *obj) {
+ .....
+ }
+
+ int _wrap_foo(...) {
+ ....
+ arg1 = AsMyClass(obj1);
+ arg2 = AsMyClass(obj2);
+ ...
+ result = foo(arg1, arg2);
+ }
+
+
+ even when there will be duplicated typemap to process 'a' and
+ 'b', the 'AsMyClass' method will be defined only once.
+
+
+ 2.- A fragment can only defined once, and the first definition
+ is the only one taking in account. All other definitions of the
+ same fragments are silently ignored. For example, you can have
+
+
+ %fragment("AsMyClass","header") { <definition 1> }
+ ....
+ %fragment("AsMyClass","header") { <definition 2> }
+
+ and then only the first definition is considered. In this way
+ you can change the 'system' fragments by including yours first.
+
+ Note that this behavior is opposite to the typemaps, where the
+ last typemap applied or defined prevails. Fragment follows the
+ first-in-first-out convention since they are intended to be
+ "global", while typemaps intend to be "locally" specialized.
+
+ 3.- Fragments names can not contain commas.
+
+
+ A fragment can include one or more additional fragments, for example:
+
+ %fragment("<limits.h>", "header") {
+ #include <limits.h>
+ }
+
+
+ %fragment("AsMyClass", "header", fragment="<limits.h>") {
+ MyClass *AsMyClass(PyObject *obj) {
+ MyClass *value = 0;
+ int ival = somewhere_converted_from_input_object_here(obj)
+ ...
+ if (ival < CHAR_MIN) {
+ value = something_from_ival(ival);
+ } else {
+ ...
+ }
+ ...
+ return value;
+ }
+ }
+
+ in this case, when the "AsMyClass" fragment is emitted, it also
+ trigger the inclusion of the "<limits.h>" fragment.
+
+ You can add as many fragments as you want, for example
+
+ %fragment("bigfragment","header", fragment="frag1", fragment="frag2", fragment="frag3") "";
+
+ here, when the "bigfragment" is included, the three fragments "frag1",
+ "frag2" and "frag3" are included. Note that as "bigframent" is defined
+ empty, "", it does not add any code by itself, buy only trigger the
+ inclusion of the other fragments.
+
+ In a typemap you can also include more than one fragment, but since the
+ syntax is different, you need to specify them in a 'comma separated'
+ list, for example, considering the previous example:
+
+ %typemap(in,fragment="frag1,frag2,frag3") {...}
+
+ is equivalent to
+
+ %typemap(in,fragment="bigfragment") {...}
+
+
+ Finally, you can force the inclusion of a fragment at any moment as follow:
+
+ %fragment("bigfragment");
+
+ which is very useful inside a template class, for example.
+
+
+ Fragment type specialization
+ ============================
+
+ Fragments can be "type specialized". The syntax is as follows
+
+ %fragment("name","header") { a type independent fragment }
+ %fragment("name" {Type}, "header") { a type dependent fragment }
+
+ and they can also, as typemaps, be used inside templates, for exampe:
+
+ template <class T>
+ struct A {
+ %fragment("incode"{A<T>},"header") {
+ 'incode' specialized fragment
+ }
+
+ %typemap(in,fragment="incode"{A<T>}) {
+ here we use the 'type specialized'
+ fragment "incode"{A<T>}
+ }
+ };
+
+ which could seems a not much interesting feature, but is
+ fundamental for automatic typemap and template specialization.
+
+
+ Fragments and automatic typemap specialization:
+ ===============================================
+
+ Since fragments can be type specialized, they can be elegantly used
+ to specialized typemaps .
+
+ For example, if you have something like:
+
+ %fragment("incode"{float}, "header") {
+ float in_method_float(PyObject *obj) {
+ ...
+ }
+ }
+
+ %fragment("incode"{long}, "header") {
+ float in_method_long(PyObject *obj) {
+ ...
+ }
+ }
+
+ %define %my_typemaps(Type)
+ %typemaps(in,fragment="incode"{Type}) {
+ value = in_method_##Type(obj);
+ }
+ %enddef
+
+ %my_typemaps(float);
+ %my_typemaps(long);
+
+ then the proper "incode"{float,double} fragment will be included,
+ and the proper in_method_{float,double} will be called.
+
+ Since this is a recurrent fragment use, we provide a couple of
+ macros that make the automatic generation of typemaps easier:
+
+
+ Consider for example the following code:
+
+ %fragment(SWIG_From_frag(bool),"header") {
+ static PyObject*
+ SWIG_From_dec(bool)(bool value)
+ {
+ PyObject *obj = value ? Py_True : Py_False;
+ Py_INCREF(obj);
+ return obj;
+ }
+ }
+
+ %typemap(out,fragment=SWIG_From_frag(bool)) bool {
+ $result = SWIG_From(bool)($1));
+ }
+
+ Here the macros
+
+ SWIG_From_frag => fragment
+ SWIG_From_dec => declaration
+ SWIG_From => call
+
+ allow you to define/include a fragment, and declare and call the
+ 'from-bool' method as needed. In the simpler case, these macros
+ just return something like
+
+ SWIG_From_frag(bool) => "SWIG_From_bool"
+ SWIG_From_dec(bool) => SWIG_From_bool
+ SWIG_From(bool) => SWIG_From_bool
+
+ But they are specialized for the different languages requirements,
+ such as perl or tcl that requires passing the interpreter pointer,
+ and also they can manage C++ ugly types, for example:
+
+ SWIG_From_frag(std::complex<double>) => "SWIG_From_std_complex_Sl_double_Sg_"
+ SWIG_From_dec(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_
+ SWIG_From(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_
+
+
+ Hence, to declare methods to use with typemaps, always use the
+ SWIG_From* macros. In the same way, the SWIG_AsVal* and SWIG_AsPtr*
+ set of macros are provided.
+
+*/
+
+
+/* -----------------------------------------------------------------------------
+ * Define the basic macros to 'normalize' the type fragments
+ * ----------------------------------------------------------------------------- */
+
+#ifndef SWIG_AS_DECL_ARGS
+#define SWIG_AS_DECL_ARGS
+#endif
+
+#ifndef SWIG_FROM_DECL_ARGS
+#define SWIG_FROM_DECL_ARGS
+#endif
+
+#ifndef SWIG_AS_CALL_ARGS
+#define SWIG_AS_CALL_ARGS
+#endif
+
+#ifndef SWIG_FROM_CALL_ARGS
+#define SWIG_FROM_CALL_ARGS
+#endif
+
+#define %fragment_name(Name, Type...) %string_name(Name) "_" {Type}
+
+#define SWIG_Traits_frag(Type...) %fragment_name(Traits, Type)
+#define SWIG_AsPtr_frag(Type...) %fragment_name(AsPtr, Type)
+#define SWIG_AsVal_frag(Type...) %fragment_name(AsVal, Type)
+#define SWIG_From_frag(Type...) %fragment_name(From, Type)
+
+#define SWIG_AsVal_name(Type...) %symbol_name(AsVal, Type)
+#define SWIG_AsPtr_name(Type...) %symbol_name(AsPtr, Type)
+#define SWIG_From_name(Type...) %symbol_name(From, Type)
+
+#define SWIG_AsVal_dec(Type...) SWIG_AsVal_name(Type) SWIG_AS_DECL_ARGS
+#define SWIG_AsPtr_dec(Type...) SWIG_AsPtr_name(Type) SWIG_AS_DECL_ARGS
+#define SWIG_From_dec(Type...) SWIG_From_name(Type) SWIG_FROM_DECL_ARGS
+
+#define SWIG_AsVal(Type...) SWIG_AsVal_name(Type) SWIG_AS_CALL_ARGS
+#define SWIG_AsPtr(Type...) SWIG_AsPtr_name(Type) SWIG_AS_CALL_ARGS
+#define SWIG_From(Type...) SWIG_From_name(Type) SWIG_FROM_CALL_ARGS
+
+/* ------------------------------------------------------------
+ * common fragments
+ * ------------------------------------------------------------ */
+
+/* Default compiler options for gcc allow long_long but not LLONG_MAX.
+ * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
+%fragment("<limits.h>","header") %{
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+# define LLONG_MAX __LONG_LONG_MAX__
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+%}
+
+%fragment("<math.h>","header") %{
+#include <math.h>
+%}
+
+%fragment("<wchar.h>","header") %{
+#include <wchar.h>
+#include <limits.h>
+#ifndef WCHAR_MIN
+# define WCHAR_MIN 0
+#endif
+#ifndef WCHAR_MAX
+# define WCHAR_MAX 65535
+#endif
+%}
+
+%fragment("<float.h>","header") %{
+#include <float.h>
+%}
+
+%fragment("<stdio.h>","header") %{
+#include <stdio.h>
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# ifndef snprintf
+# define snprintf _snprintf
+# endif
+#endif
+%}
+
+%fragment("<stdlib.h>","header") %{
+#include <stdlib.h>
+#ifdef _MSC_VER
+# ifndef strtoull
+# define strtoull _strtoui64
+# endif
+# ifndef strtoll
+# define strtoll _strtoi64
+# endif
+#endif
+%}
+
+/* -----------------------------------------------------------------------------
+ * special macros for fragments
+ * ----------------------------------------------------------------------------- */
+
+/* Macros to derive numeric types */
+
+%define %numeric_type_from(Type, Base)
+%fragment(SWIG_From_frag(Type),"header",
+ fragment=SWIG_From_frag(Base)) {
+SWIGINTERNINLINE SWIG_Object
+SWIG_From_dec(Type)(Type value)
+{
+ return SWIG_From(Base)(value);
+}
+}
+%enddef
+
+%define %numeric_type_asval(Type, Base, Frag, OverflowCond)
+%fragment(SWIG_AsVal_frag(Type),"header",
+ fragment=Frag,
+ fragment=SWIG_AsVal_frag(Base)) {
+SWIGINTERN int
+SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val)
+{
+ Base v;
+ int res = SWIG_AsVal(Base)(obj, &v);
+ if (SWIG_IsOK(res)) {
+ if (OverflowCond) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = %numeric_cast(v, Type);
+ }
+ }
+ return res;
+}
+}
+%enddef
+
+#define %numeric_signed_type_asval(Type, Base, Frag, Min, Max) \
+%numeric_type_asval(Type, Base, Frag, (v < Min || v > Max))
+
+#define %numeric_unsigned_type_asval(Type, Base, Frag, Max) \
+%numeric_type_asval(Type, Base, Frag, (v > Max))
+
+
+/* Macro for 'signed long' derived types */
+
+%define %numeric_slong(Type, Frag, Min, Max)
+%numeric_type_from(Type, long)
+%numeric_signed_type_asval(Type, long, Frag , Min, Max)
+%enddef
+
+/* Macro for 'unsigned long' derived types */
+
+%define %numeric_ulong(Type, Frag, Max)
+%numeric_type_from(Type, unsigned long)
+%numeric_unsigned_type_asval(Type, unsigned long, Frag, Max)
+%enddef
+
+
+/* Macro for 'double' derived types */
+
+%define %numeric_double(Type, Frag, Min, Max)
+%numeric_type_from(Type, double)
+%numeric_signed_type_asval(Type, double, Frag , Min, Max)
+%enddef
+
+
+/* Macros for missing fragments */
+
+%define %ensure_fragment(Fragment)
+%fragment(`Fragment`,"header") {
+%#error "Swig language implementation must provide the Fragment fragment"
+}
+%enddef
+
+%define %ensure_type_fragments(Type)
+%fragment(SWIG_From_frag(Type),"header") {
+%#error "Swig language implementation must provide a SWIG_From_frag(Type) fragment"
+}
+%fragment(SWIG_AsVal_frag(Type),"header") {
+%#error "Swig language implementation must provide a SWIG_AsVal_frag(Type) fragment"
+}
+%enddef
« 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