mirror of
https://github.com/boostorg/python.git
synced 2026-01-27 19:12:16 +00:00
- Lots of fixes in the documentation
- Fixed support for return_opaque_pointer policy [SVN r18199]
This commit is contained in:
10
pyste/NEWS
10
pyste/NEWS
@@ -1,6 +1,12 @@
|
||||
07 Apr 2003
|
||||
Removed the warnings about forward declarations: it was not accurate enough.
|
||||
Another strategy must be thought of.
|
||||
- Removed the warnings about forward declarations: it was not accurate enough.
|
||||
Another strategy must be thought of.
|
||||
- Fixed bug in the --multiple mode, where the order of the class instantiations
|
||||
could end up wrong.
|
||||
- Lots of fixes in the documentation, pointed out by Dirk Gerrits. Thanks Dirk!
|
||||
- Fixed support for the return_opaque_pointer policy (the support macro was not
|
||||
being declared).
|
||||
|
||||
|
||||
06 Apr 2003
|
||||
Support for the improved static data members support of Boost.Python.
|
||||
|
||||
@@ -51,7 +51,7 @@ Here's the interface file for it, named <tt>world.pyste</tt>:</p>
|
||||
<p>
|
||||
and that's it!</p>
|
||||
<p>
|
||||
The next step is invoke pyste in the command-line:</p>
|
||||
The next step is invoke Pyste in the command-line:</p>
|
||||
<code><pre>python pyste.py --module=hello world.pyste</pre></code><p>
|
||||
this will create a file "<tt>hello.cpp</tt>" in the directory where the command was
|
||||
run. </p>
|
||||
|
||||
@@ -69,7 +69,7 @@ and set the policy for it, otherwise the generated cpp won't compile.
|
||||
Note that, for functions/methods that return <tt>const T&</tt>, the policy
|
||||
<tt>return_value_policy<copy_const_reference>()</tt> wil be used by default, because
|
||||
that's normally what you want. You can change it to something else if you need
|
||||
to, thought.
|
||||
to, though.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -30,7 +30,7 @@ Here's the interface file for it, named [^world.pyste]:
|
||||
|
||||
and that's it!
|
||||
|
||||
The next step is invoke pyste in the command-line:
|
||||
The next step is invoke Pyste in the command-line:
|
||||
|
||||
[pre python pyste.py --module=hello world.pyste]
|
||||
|
||||
@@ -51,17 +51,17 @@ Pyste supports the following features:
|
||||
|
||||
[page Running Pyste]
|
||||
|
||||
To run pyste, you will need:
|
||||
To run Pyste, you will need:
|
||||
|
||||
* Python 2.2, avaiable at [@http://www.python.org python's website].
|
||||
* Python 2.2, available at [@http://www.python.org python's website].
|
||||
* The great [@http://effbot.org elementtree] library, from Fredrik Lundh.
|
||||
* The excellent GCCXML, from Brad King.
|
||||
|
||||
Installation for the tools is avaiable in their respective webpages.
|
||||
Installation for the tools is available in their respective webpages.
|
||||
|
||||
[blurb
|
||||
[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so
|
||||
that pyste can call it. How to do this varies from platform to platform.
|
||||
that Pyste can call it. How to do this varies from platform to platform.
|
||||
]
|
||||
|
||||
[h2 Ok, now what?]
|
||||
@@ -87,7 +87,7 @@ where options are:
|
||||
--no-using do not declare "using namespace boost";
|
||||
use explicit declarations instead
|
||||
--pyste-ns=<name> set the namespace where new types will be declared;
|
||||
default is "pyste"
|
||||
default is the empty namespace
|
||||
--debug writes the xml for each file parsed in the current
|
||||
directory
|
||||
-h, --help print this help and exit
|
||||
@@ -97,11 +97,11 @@ where options are:
|
||||
|
||||
Options explained:
|
||||
|
||||
The [^-I] and [^-D] are preprocessor flags, which are needed by gccxml to parse
|
||||
the header files correctly and by pyste to find the header files declared in the
|
||||
The [^-I] and [^-D] are preprocessor flags, which are needed by GCCXML to parse
|
||||
the header files correctly and by Pyste to find the header files declared in the
|
||||
interface files.
|
||||
|
||||
[^--multiple] tells pyste to generate multiple cpps for this module (one for
|
||||
[^--multiple] tells Pyste to generate multiple cpps for this module (one for
|
||||
each header parsed) in the directory named by [^--out], instead of the usual
|
||||
single cpp file. This mode is useful during development of a binding, because
|
||||
you are constantly changing source files, re-generating the bindings and
|
||||
@@ -110,7 +110,7 @@ recompiling. This saves a lot of time in compiling.
|
||||
[^--out] names the output file (default: [^<module>.cpp]), or in multiple mode,
|
||||
names a output directory for the files (default: [^<module>]).
|
||||
|
||||
[^--no-using] tells pyste to don't declare "[^using namespace boost;]" in the
|
||||
[^--no-using] tells Pyste to don't declare "[^using namespace boost;]" in the
|
||||
generated cpp, using the namespace boost::python explicitly in all declarations.
|
||||
Use only if you're having a name conflict in one of the files.
|
||||
|
||||
@@ -118,7 +118,7 @@ Use [^--pyste-ns] to change the namespace where new types are declared (for
|
||||
instance, the virtual wrappers). Use only if you are having any problems. By
|
||||
default, Pyste uses the empty namespace.
|
||||
|
||||
[^--debug] will write in the current directory a xml file as outputted by gccxml
|
||||
[^--debug] will write in the current directory a xml file as outputted by GCCXML
|
||||
for each header parsed. Useful for bug reports.
|
||||
|
||||
[^-h, --help, -v, --version] are self-explaining, I believe. ;)
|
||||
@@ -160,7 +160,7 @@ Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to use
|
||||
|
||||
The interface files are the heart of Pyste. The user creates one or more
|
||||
interface files declaring the classes and functions he wants to export, and then
|
||||
invokes pyste passing the interface files to it. Pyste then generates a single
|
||||
invokes Pyste passing the interface files to it. Pyste then generates a single
|
||||
cpp file with Boost.Python code, with all the classes and functions exported.
|
||||
|
||||
Besides declaring the classes and functions, the user has a number of other
|
||||
@@ -265,12 +265,12 @@ and set the policy for it, otherwise the generated cpp won't compile.
|
||||
Note that, for functions/methods that return [^const T&], the policy
|
||||
[^return_value_policy<copy_const_reference>()] wil be used by default, because
|
||||
that's normally what you want. You can change it to something else if you need
|
||||
to, thought.
|
||||
to, though.
|
||||
]
|
||||
|
||||
[page:1 Templates]
|
||||
|
||||
Template Classes can easily exported too, but you can't export the "Template"
|
||||
Template classes can easily be exported too, but you can't export the template
|
||||
itself... you have to export instantiations of it! So, if you want to export a
|
||||
[^std::vector], you will have to export vectors of int, doubles, etc.
|
||||
|
||||
@@ -297,7 +297,7 @@ rename the instantiations:
|
||||
double_inst = Point("double") // another way to do the same
|
||||
rename(double_inst, "DPoint")
|
||||
|
||||
Note that you can rename, exclude, set policies, etc, in the [^Template] class
|
||||
Note that you can rename, exclude, set policies, etc, in the [^Template] object
|
||||
like you would do with a [^Function] or a [^Class]. This changes affect all
|
||||
[*future] instantiations:
|
||||
|
||||
@@ -318,7 +318,7 @@ If you want to change a option of a particular instantiation, you can do so:
|
||||
|
||||
[blurb [$theme/note.gif] [*What if my template accepts more than one type?]
|
||||
[br][br]
|
||||
When you want to instantiate a Template with more than one type, you can pass
|
||||
When you want to instantiate a template with more than one type, you can pass
|
||||
either a string with the types separated by whitespace, or a list of strings
|
||||
'''("int double" or ["int", "double"]''' would both work).
|
||||
]
|
||||
@@ -329,8 +329,8 @@ Suppose you have this function:
|
||||
|
||||
std::vector<std::string> names();
|
||||
|
||||
But you don't want to export [^std::vector<string>], you want this function
|
||||
to return a python list of strings. Boost.Python has an excellent support for
|
||||
But you don't want to export [^std::vector<std::string>], you want this function
|
||||
to return a python list of strings. Boost.Python has excellent support for
|
||||
that:
|
||||
|
||||
list names_wrapper()
|
||||
@@ -338,7 +338,11 @@ that:
|
||||
list result;
|
||||
// call original function
|
||||
vector<string> v = names();
|
||||
// put each string from the vector in the list
|
||||
// put all the strings inside the python list
|
||||
vector<string>::iterator it;
|
||||
for (it = v.begin(); it != v.end(); ++it){
|
||||
result.append(*it);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -360,13 +364,13 @@ You can optionally declare the function in the interface file itself:
|
||||
"""
|
||||
list names_wrapper()
|
||||
{
|
||||
// call name() and convert the vector to a list...
|
||||
// code to call name() and convert the vector to a list...
|
||||
}
|
||||
""")
|
||||
names = Function("names", "test.h")
|
||||
set_wrapper(names, names_wrapper)
|
||||
|
||||
The same mechanism can be done with methods too. Just remember that the first
|
||||
The same mechanism can be used with methods too. Just remember that the first
|
||||
parameter of wrappers for methods is a pointer to the class, like in
|
||||
Boost.Python:
|
||||
|
||||
@@ -449,7 +453,7 @@ Pyste for now has manual support for smart pointers. Suppose:
|
||||
}
|
||||
|
||||
To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
|
||||
conversor for [^boost::shared_ptr<C>] is needed.
|
||||
convertor for [^boost::shared_ptr<C>] is needed.
|
||||
|
||||
C = Class('C', 'C.h')
|
||||
use_shared_ptr(C)
|
||||
@@ -458,6 +462,6 @@ conversor for [^boost::shared_ptr<C>] is needed.
|
||||
|
||||
For [^std::auto_ptr]'s, use the function [^use_auto_ptr].
|
||||
|
||||
This system is temporary, and in the future the conversors will automatically be
|
||||
This system is temporary, and in the future the converters will automatically be
|
||||
exported if needed, without the need to tell Pyste about them explicitly.
|
||||
|
||||
|
||||
@@ -25,19 +25,19 @@
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
To run pyste, you will need:</p>
|
||||
<ul><li>Python 2.2, avaiable at <a href="http://www.python.org">
|
||||
To run Pyste, you will need:</p>
|
||||
<ul><li>Python 2.2, available at <a href="http://www.python.org">
|
||||
python's website</a>.</li><li>The great <a href="http://effbot.org">
|
||||
elementtree</a> library, from Fredrik Lundh.</li><li>The excellent <a href="http://www.gccxml.org">
|
||||
GCCXML</a>, from Brad King.</li></ul><p>
|
||||
Installation for the tools is avaiable in their respective webpages.</p>
|
||||
Installation for the tools is available in their respective webpages.</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
|
||||
<img src="theme/note.gif"></img> <a href="http://www.gccxml.org">
|
||||
GCCXML</a> must be accessible in the PATH environment variable, so
|
||||
that pyste can call it. How to do this varies from platform to platform.
|
||||
that Pyste can call it. How to do this varies from platform to platform.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -62,7 +62,7 @@ where options are:
|
||||
--no-using do not declare "using namespace boost";
|
||||
use explicit declarations instead
|
||||
--pyste-ns=<name> set the namespace where new types will be declared;
|
||||
default is "pyste"
|
||||
default is the empty namespace
|
||||
--debug writes the xml for each file parsed in the current
|
||||
directory
|
||||
-h, --help print this help and exit
|
||||
@@ -71,11 +71,12 @@ where options are:
|
||||
</pre></code><p>
|
||||
Options explained:</p>
|
||||
<p>
|
||||
The <tt>-I</tt> and <tt>-D</tt> are preprocessor flags, which are needed by gccxml to parse
|
||||
the header files correctly and by pyste to find the header files declared in the
|
||||
The <tt>-I</tt> and <tt>-D</tt> are preprocessor flags, which are needed by <a href="http://www.gccxml.org">
|
||||
GCCXML</a> to parse
|
||||
the header files correctly and by Pyste to find the header files declared in the
|
||||
interface files.</p>
|
||||
<p>
|
||||
<tt>--multiple</tt> tells pyste to generate multiple cpps for this module (one for
|
||||
<tt>--multiple</tt> tells Pyste to generate multiple cpps for this module (one for
|
||||
each header parsed) in the directory named by <tt>--out</tt>, instead of the usual
|
||||
single cpp file. This mode is useful during development of a binding, because
|
||||
you are constantly changing source files, re-generating the bindings and
|
||||
@@ -84,7 +85,7 @@ recompiling. This saves a lot of time in compiling.</p>
|
||||
<tt>--out</tt> names the output file (default: <tt><module>.cpp</tt>), or in multiple mode,
|
||||
names a output directory for the files (default: <tt><module></tt>).</p>
|
||||
<p>
|
||||
<tt>--no-using</tt> tells pyste to don't declare "<tt>using namespace boost;</tt>" in the
|
||||
<tt>--no-using</tt> tells Pyste to don't declare "<tt>using namespace boost;</tt>" in the
|
||||
generated cpp, using the namespace boost::python explicitly in all declarations.
|
||||
Use only if you're having a name conflict in one of the files.</p>
|
||||
<p>
|
||||
@@ -92,7 +93,8 @@ Use <tt>--pyste-ns</tt> to change the namespace where new types are declared (fo
|
||||
instance, the virtual wrappers). Use only if you are having any problems. By
|
||||
default, Pyste uses the empty namespace.</p>
|
||||
<p>
|
||||
<tt>--debug</tt> will write in the current directory a xml file as outputted by gccxml
|
||||
<tt>--debug</tt> will write in the current directory a xml file as outputted by <a href="http://www.gccxml.org">
|
||||
GCCXML</a>
|
||||
for each header parsed. Useful for bug reports.</p>
|
||||
<p>
|
||||
<tt>-h, --help, -v, --version</tt> are self-explaining, I believe. ;)</p>
|
||||
|
||||
@@ -45,7 +45,7 @@ Pyste for now has manual support for smart pointers. Suppose:</p>
|
||||
</span></pre></code>
|
||||
<p>
|
||||
To make <tt>newC</tt> and <tt>printC</tt> work correctly, you have to tell Pyste that a
|
||||
conversor for <tt>boost::shared_ptr<C></tt> is needed.</p>
|
||||
convertor for <tt>boost::shared_ptr<C></tt> is needed.</p>
|
||||
<code><pre>
|
||||
<span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
|
||||
</span><span class=identifier>use_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
|
||||
@@ -55,7 +55,7 @@ conversor for <tt>boost::shared_ptr<C></tt> is needed.</p>
|
||||
<p>
|
||||
For <tt>std::auto_ptr</tt>'s, use the function <tt>use_auto_ptr</tt>.</p>
|
||||
<p>
|
||||
This system is temporary, and in the future the conversors will automatically be
|
||||
This system is temporary, and in the future the converters will automatically be
|
||||
exported if needed, without the need to tell Pyste about them explicitly.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Template Classes can easily exported too, but you can't export the "Template"
|
||||
Template classes can easily be exported too, but you can't export the template
|
||||
itself... you have to export instantiations of it! So, if you want to export a
|
||||
<tt>std::vector</tt>, you will have to export vectors of int, doubles, etc.</p>
|
||||
<p>
|
||||
@@ -55,7 +55,7 @@ rename the instantiations:</p>
|
||||
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>double_inst</span><span class=special>, </span><span class=string>"DPoint"</span><span class=special>)
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> class
|
||||
Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> object
|
||||
like you would do with a <tt>Function</tt> or a <tt>Class</tt>. This changes affect all
|
||||
<b>future</b> instantiations:</p>
|
||||
<code><pre>
|
||||
@@ -80,7 +80,7 @@ If you want to change a option of a particular instantiation, you can do so:</p>
|
||||
<td class="note_box">
|
||||
<img src="theme/note.gif"></img> <b>What if my template accepts more than one type?</b>
|
||||
<br><br>
|
||||
When you want to instantiate a Template with more than one type, you can pass
|
||||
When you want to instantiate a template with more than one type, you can pass
|
||||
either a string with the types separated by whitespace, or a list of strings
|
||||
("int double" or ["int", "double"] would both work).
|
||||
</td>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<p>
|
||||
The interface files are the heart of Pyste. The user creates one or more
|
||||
interface files declaring the classes and functions he wants to export, and then
|
||||
invokes pyste passing the interface files to it. Pyste then generates a single
|
||||
invokes Pyste passing the interface files to it. Pyste then generates a single
|
||||
cpp file with <a href="../../index.html">
|
||||
Boost.Python</a> code, with all the classes and functions exported.</p>
|
||||
<p>
|
||||
|
||||
@@ -30,9 +30,9 @@ Suppose you have this function:</p>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>> </span><span class=identifier>names</span><span class=special>();
|
||||
</span></pre></code>
|
||||
<p>
|
||||
But you don't want to export <tt>std::vector<string></tt>, you want this function
|
||||
But you don't want to export <tt>std::vector<std::string></tt>, you want this function
|
||||
to return a python list of strings. <a href="../../index.html">
|
||||
Boost.Python</a> has an excellent support for
|
||||
Boost.Python</a> has excellent support for
|
||||
that:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>()
|
||||
@@ -40,7 +40,11 @@ that:</p>
|
||||
</span><span class=identifier>list </span><span class=identifier>result</span><span class=special>;
|
||||
// </span><span class=identifier>call </span><span class=identifier>original </span><span class=identifier>function
|
||||
</span><span class=identifier>vector</span><span class=special><</span><span class=identifier>string</span><span class=special>> </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>names</span><span class=special>();
|
||||
// </span><span class=identifier>put </span><span class=identifier>each </span><span class=identifier>string </span><span class=identifier>from </span><span class=identifier>the </span><span class=identifier>vector </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>list
|
||||
// </span><span class=identifier>put </span><span class=identifier>all </span><span class=identifier>the </span><span class=identifier>strings </span><span class=identifier>inside </span><span class=identifier>the </span><span class=identifier>python </span><span class=identifier>list
|
||||
</span><span class=identifier>vector</span><span class=special><</span><span class=identifier>string</span><span class=special>>::</span><span class=identifier>iterator </span><span class=identifier>it</span><span class=special>;
|
||||
</span><span class=keyword>for </span><span class=special>(</span><span class=identifier>it </span><span class=special>= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(); </span><span class=identifier>it </span><span class=special>!= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(); ++</span><span class=identifier>it</span><span class=special>){
|
||||
</span><span class=identifier>result</span><span class=special>.</span><span class=identifier>append</span><span class=special>(*</span><span class=identifier>it</span><span class=special>);
|
||||
}
|
||||
</span><span class=keyword>return </span><span class=identifier>result</span><span class=special>;
|
||||
}
|
||||
|
||||
@@ -64,14 +68,14 @@ You can optionally declare the function in the interface file itself:</p>
|
||||
</span><span class=string>""</span><span class=string>"
|
||||
list names_wrapper()
|
||||
{
|
||||
// call name() and convert the vector to a list...
|
||||
// code to call name() and convert the vector to a list...
|
||||
}
|
||||
"</span><span class=string>""</span><span class=special>)
|
||||
</span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>"names"</span><span class=special>, </span><span class=string>"test.h"</span><span class=special>)
|
||||
</span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=identifier>names_wrapper</span><span class=special>)
|
||||
</span></pre></code>
|
||||
<p>
|
||||
The same mechanism can be done with methods too. Just remember that the first
|
||||
The same mechanism can be used with methods too. Just remember that the first
|
||||
parameter of wrappers for methods is a pointer to the class, like in
|
||||
<a href="../../index.html">
|
||||
Boost.Python</a>:</p>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
*.cpp
|
||||
.sconsign
|
||||
*.obj
|
||||
|
||||
8
pyste/example/basic.cpp
Normal file
8
pyste/example/basic.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "basic.h"
|
||||
|
||||
namespace basic {
|
||||
|
||||
int C::static_value = 3;
|
||||
const int C::const_static_value = 100;
|
||||
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifndef BASIC_H
|
||||
#define BASIC_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace basic {
|
||||
@@ -24,27 +28,26 @@ struct C
|
||||
const int const_value;
|
||||
};
|
||||
|
||||
int C::static_value = 3;
|
||||
const int C::const_static_value = 100;
|
||||
|
||||
int call_f(C& c)
|
||||
inline int call_f(C& c)
|
||||
{
|
||||
return c.f();
|
||||
}
|
||||
|
||||
int call_f(C& c, int x)
|
||||
inline int call_f(C& c, int x)
|
||||
{
|
||||
return c.f(x);
|
||||
}
|
||||
|
||||
int get_static()
|
||||
inline int get_static()
|
||||
{
|
||||
return C::static_value;
|
||||
}
|
||||
|
||||
int get_value(C& c)
|
||||
inline int get_value(C& c)
|
||||
{
|
||||
return c.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef ENUMS_H
|
||||
#define ENUMS_H
|
||||
|
||||
namespace enums {
|
||||
|
||||
enum color { red, blue };
|
||||
@@ -17,3 +20,5 @@ struct X
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef HEADER_TEST_H
|
||||
#define HEADER_TEST_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@@ -5,7 +8,7 @@ namespace header_test {
|
||||
|
||||
enum choice { red, blue };
|
||||
|
||||
std::string choice_str(choice c)
|
||||
inline std::string choice_str(choice c)
|
||||
{
|
||||
std::map<choice, std::string> choice_map;
|
||||
choice_map[red] = "red";
|
||||
@@ -24,3 +27,5 @@ struct C
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
4
pyste/example/nested.cpp
Normal file
4
pyste/example/nested.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "nested.h"
|
||||
|
||||
int nested::X::staticXValue = 10;
|
||||
int nested::X::Y::staticYValue = 20;
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef NESTED_H
|
||||
#define NESTED_H
|
||||
|
||||
namespace nested {
|
||||
|
||||
struct X
|
||||
@@ -16,9 +19,8 @@ struct X
|
||||
int valueX;
|
||||
};
|
||||
|
||||
int X::staticXValue = 10;
|
||||
int X::Y::staticYValue = 20;
|
||||
|
||||
typedef X Root;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
47
pyste/example/opaque.h
Normal file
47
pyste/example/opaque.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef OPAQUE_H
|
||||
#define OPAQUE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace opaque {
|
||||
|
||||
|
||||
struct C {
|
||||
C(int v): value(v) {}
|
||||
int value;
|
||||
};
|
||||
|
||||
|
||||
inline C* new_C()
|
||||
{
|
||||
return new C(10);
|
||||
}
|
||||
|
||||
inline int get(C* c)
|
||||
{
|
||||
return c->value;
|
||||
}
|
||||
|
||||
struct D {
|
||||
D(double v): value(v) {}
|
||||
double value;
|
||||
};
|
||||
|
||||
struct A
|
||||
{
|
||||
D* new_handle()
|
||||
{
|
||||
return new D(3.0);
|
||||
}
|
||||
|
||||
double get(D* d)
|
||||
{
|
||||
return d->value;
|
||||
}
|
||||
|
||||
int f(int x=0) { return x; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
5
pyste/example/opaque.pyste
Normal file
5
pyste/example/opaque.pyste
Normal file
@@ -0,0 +1,5 @@
|
||||
foo = Function('opaque::new_C', 'opaque.h')
|
||||
set_policy(foo, return_value_policy(return_opaque_pointer))
|
||||
Function('opaque::get', 'opaque.h' )
|
||||
A = Class('opaque::A', 'opaque.h')
|
||||
set_policy(A.new_handle, return_value_policy(return_opaque_pointer))
|
||||
3
pyste/example/operators.cpp
Normal file
3
pyste/example/operators.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "operators.h"
|
||||
|
||||
double operators::C::x = 10;
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifndef OPERATORS_H
|
||||
#define OPERATORS_H
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace operators {
|
||||
@@ -31,9 +35,7 @@ struct C
|
||||
operator const char*() { return "C"; }
|
||||
};
|
||||
|
||||
double C::x = 10;
|
||||
|
||||
const C operator*(const C& lhs, const C& rhs)
|
||||
inline const C operator*(const C& lhs, const C& rhs)
|
||||
{
|
||||
C c;
|
||||
c.value = lhs.value * rhs.value;
|
||||
@@ -42,3 +44,6 @@ const C operator*(const C& lhs, const C& rhs)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifndef SMART_PTR_H
|
||||
#define SMART_PTR_H
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
@@ -8,7 +12,7 @@ struct C
|
||||
int value;
|
||||
};
|
||||
|
||||
boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
|
||||
inline boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
|
||||
|
||||
struct D
|
||||
{
|
||||
@@ -18,5 +22,8 @@ private:
|
||||
boost::shared_ptr<C> ptr;
|
||||
};
|
||||
|
||||
std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
|
||||
inline std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,6 @@ private:
|
||||
virtual const char* name() { return "C"; }
|
||||
};
|
||||
|
||||
int call_f(C& c) { return c.f(); }
|
||||
inline int call_f(C& c) { return c.f(); }
|
||||
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ struct B: A
|
||||
virtual int f2() { return 20; }
|
||||
};
|
||||
|
||||
int call_fs(A*a)
|
||||
inline int call_fs(A*a)
|
||||
{
|
||||
int r = a->f1();
|
||||
B* b = dynamic_cast<B*>(a);
|
||||
return r + b->f2();
|
||||
}
|
||||
|
||||
int call_f(A* a)
|
||||
inline int call_f(A* a)
|
||||
{
|
||||
return a->f();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace wrappertest {
|
||||
|
||||
std::vector<int> Range(int count)
|
||||
inline std::vector<int> Range(int count)
|
||||
{
|
||||
std::vector<int> v;
|
||||
v.reserve(count);
|
||||
@@ -40,7 +40,7 @@ struct A
|
||||
virtual int f() { return 1; };
|
||||
};
|
||||
|
||||
int call_foo(A* a){ return a->f(); }
|
||||
inline int call_foo(A* a){ return a->f(); }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ list VectorToList(const std::vector<T> & v)
|
||||
return res;
|
||||
}
|
||||
|
||||
list RangeWrapper(int count){
|
||||
inline list RangeWrapper(int count){
|
||||
return VectorToList(wrappertest::Range(count));
|
||||
}
|
||||
|
||||
int f_wrapper(wrappertest::A*) { return 10; }
|
||||
inline int f_wrapper(wrappertest::A*) { return 10; }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@ import exporters
|
||||
from Exporter import Exporter
|
||||
from declarations import *
|
||||
from settings import *
|
||||
from policies import *
|
||||
from SingleCodeUnit import SingleCodeUnit
|
||||
from EnumExporter import EnumExporter
|
||||
from utils import makeid, enumerate
|
||||
@@ -35,12 +36,14 @@ class ClassExporter(Exporter):
|
||||
self.sections['scope'] = []
|
||||
# declarations: outside the BOOST_PYTHON_MODULE macro
|
||||
self.sections['declaration'] = []
|
||||
self.sections['declaration-outside'] = []
|
||||
self.sections['include'] = []
|
||||
# a list of Constructor instances
|
||||
self.constructors = []
|
||||
self.wrapper_generator = None
|
||||
# a list of code units, generated by nested declarations
|
||||
self.nested_codeunits = []
|
||||
self._exported_opaque_pointers = {}
|
||||
|
||||
|
||||
def ScopeName(self):
|
||||
@@ -96,6 +99,7 @@ class ClassExporter(Exporter):
|
||||
self.ExportNestedClasses(exported_names)
|
||||
self.ExportNestedEnums()
|
||||
self.ExportSmartPointer()
|
||||
self.ExportOpaquePointerPolicies()
|
||||
self.Write(codeunit)
|
||||
|
||||
|
||||
@@ -149,6 +153,9 @@ class ClassExporter(Exporter):
|
||||
declarations += nested_unit.Section('declaration')
|
||||
if declarations:
|
||||
codeunit.Write('declaration', declarations + '\n')
|
||||
declarations_outside = '\n'.join(self.sections['declaration-outside'])
|
||||
if declarations_outside:
|
||||
codeunit.Write('declaration-outside', declarations_outside + '\n')
|
||||
|
||||
# write the includes to the codeunit
|
||||
includes = '\n'.join(self.sections['include'])
|
||||
@@ -546,6 +553,19 @@ class ClassExporter(Exporter):
|
||||
smart_ptr = self.info.smart_ptr
|
||||
if smart_ptr:
|
||||
self.Add('template', smart_ptr % self.class_.FullName())
|
||||
|
||||
|
||||
def ExportOpaquePointerPolicies(self):
|
||||
# check all methods for 'return_opaque_pointer' policies
|
||||
methods = [x for x in self.public_members if isinstance(x, Method)]
|
||||
for method in methods:
|
||||
return_opaque_policy = return_value_policy(return_opaque_pointer)
|
||||
if self.info[method.name].policy == return_opaque_policy:
|
||||
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method.result.name
|
||||
if macro not in self._exported_opaque_pointers:
|
||||
self.Add('declaration-outside', macro)
|
||||
self._exported_opaque_pointers[macro] = 1
|
||||
|
||||
|
||||
|
||||
#==============================================================================
|
||||
|
||||
@@ -14,6 +14,7 @@ class FunctionExporter(Exporter):
|
||||
|
||||
def __init__(self, info, tail=None):
|
||||
Exporter.__init__(self, info, tail)
|
||||
self._exported_opaque_pointers = {}
|
||||
|
||||
|
||||
def Export(self, codeunit, exported_names):
|
||||
@@ -22,7 +23,8 @@ class FunctionExporter(Exporter):
|
||||
self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
|
||||
exporterutils.WarnForwardDeclarations(decl)
|
||||
self.ExportDeclaration(decl, len(decls) == 1, codeunit)
|
||||
self.GenerateOverloads(decls, codeunit)
|
||||
self.ExportOpaquePointer(decl, codeunit)
|
||||
self.GenerateOverloads(decls, codeunit)
|
||||
|
||||
|
||||
def ExportDeclaration(self, decl, unique, codeunit):
|
||||
@@ -75,6 +77,15 @@ class FunctionExporter(Exporter):
|
||||
return ''
|
||||
|
||||
|
||||
def ExportOpaquePointer(self, function, codeunit):
|
||||
if self.info.policy == return_value_policy(return_opaque_pointer):
|
||||
type = function.result.name
|
||||
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % type
|
||||
if macro not in self._exported_opaque_pointers:
|
||||
codeunit.Write('declaration-outside', macro)
|
||||
self._exported_opaque_pointers[macro] = 1
|
||||
|
||||
|
||||
def Order(self):
|
||||
return self.info.name
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class HeaderExporter(Exporter):
|
||||
|
||||
|
||||
def Unit(self):
|
||||
return self.info.include
|
||||
return None # doesn't write anything by himself
|
||||
|
||||
|
||||
def Order(self):
|
||||
|
||||
@@ -34,7 +34,10 @@ class MultipleCodeUnit(object):
|
||||
def SetCurrent(self, code_unit_name):
|
||||
'Changes the current code unit'
|
||||
try:
|
||||
codeunit = self.codeunits[code_unit_name]
|
||||
if code_unit_name is not None:
|
||||
codeunit = self.codeunits[code_unit_name]
|
||||
else:
|
||||
codeunit = None
|
||||
except KeyError:
|
||||
filename = self._FileName(code_unit_name)
|
||||
function_name = self._FunctionName(code_unit_name)
|
||||
@@ -52,19 +55,14 @@ class MultipleCodeUnit(object):
|
||||
current = property(Current, SetCurrent)
|
||||
|
||||
|
||||
def _CheckCurrent(self):
|
||||
if self.current is None:
|
||||
raise RuntimeError, "No current code unit to write to!"
|
||||
|
||||
|
||||
def Write(self, section, code):
|
||||
self._CheckCurrent()
|
||||
self.current.Write(section, code)
|
||||
if self._current is not None:
|
||||
self.current.Write(section, code)
|
||||
|
||||
|
||||
def Section(self, section):
|
||||
self._CheckCurrent()
|
||||
return self.current.Section(section)
|
||||
if self._current is not None:
|
||||
return self.current.Section(section)
|
||||
|
||||
|
||||
def _CreateOutputDir(self):
|
||||
|
||||
@@ -22,8 +22,13 @@ class SingleCodeUnit:
|
||||
self.filename = filename
|
||||
# define the avaiable sections
|
||||
self.code = {}
|
||||
# include section
|
||||
self.code['include'] = ''
|
||||
# declaration section (inside namespace)
|
||||
self.code['declaration'] = ''
|
||||
# declaration (outside namespace)
|
||||
self.code['declaration-outside'] = ''
|
||||
# inside BOOST_PYTHON_MACRO
|
||||
self.code['module'] = ''
|
||||
# create the default module definition
|
||||
self.module_definition = 'BOOST_PYTHON_MODULE(%s)' % modulename
|
||||
@@ -37,7 +42,7 @@ class SingleCodeUnit:
|
||||
|
||||
|
||||
def Merge(self, other):
|
||||
for section in ('include', 'declaration', 'module'):
|
||||
for section in ('include', 'declaration', 'declaration-outside', 'module'):
|
||||
self.code[section] = self.code[section] + other.code[section]
|
||||
|
||||
|
||||
@@ -60,21 +65,20 @@ class SingleCodeUnit:
|
||||
fout.write(left_equals('Using'))
|
||||
fout.write('using namespace boost::python;\n\n')
|
||||
# declarations
|
||||
if self.code['declaration']:
|
||||
pyste_namespace = namespaces.pyste[:-2]
|
||||
declaration = self.code['declaration']
|
||||
declaration_outside = self.code['declaration-outside']
|
||||
if declaration_outside or declaration:
|
||||
fout.write(left_equals('Declarations'))
|
||||
fout.write('namespace %s {\n\n\n' % pyste_namespace)
|
||||
fout.write(self.code['declaration'])
|
||||
fout.write('\n\n}// namespace %s\n' % pyste_namespace)
|
||||
fout.write(space)
|
||||
fout.write(declaration_outside + '\n\n')
|
||||
if declaration:
|
||||
pyste_namespace = namespaces.pyste[:-2]
|
||||
fout.write('namespace %s {\n\n\n' % pyste_namespace)
|
||||
fout.write(declaration)
|
||||
fout.write('\n\n}// namespace %s\n' % pyste_namespace)
|
||||
fout.write(space)
|
||||
# module
|
||||
fout.write(left_equals('Module'))
|
||||
fout.write(self.module_definition + '\n')
|
||||
fout.write('{\n')
|
||||
fout.write(self.code['module'])
|
||||
fout.write('}\n')
|
||||
|
||||
|
||||
def _leftEquals(self, s):
|
||||
s = '// %s ' % s
|
||||
return s + ('='*(80-len(s))) + '\n'
|
||||
|
||||
@@ -19,6 +19,13 @@ class Policy:
|
||||
return ' >'
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
return self.Code() == other.Code()
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
class return_internal_reference(Policy):
|
||||
'Ties the return value to one of the parameters.'
|
||||
|
||||
@@ -14,7 +14,7 @@ where options are:
|
||||
--no-using do not declare "using namespace boost";
|
||||
use explicit declarations instead
|
||||
--pyste-ns=<name> set the namespace where new types will be declared;
|
||||
default is "pyste"
|
||||
default is the empty namespace
|
||||
--debug writes the xml for each file parsed in the current
|
||||
directory
|
||||
-h, --help print this help and exit
|
||||
@@ -34,7 +34,7 @@ from policies import *
|
||||
from CppParser import CppParser, CppParserError
|
||||
import time
|
||||
|
||||
__VERSION__ = '0.7.1'
|
||||
__VERSION__ = '0.7.2'
|
||||
|
||||
def RecursiveIncludes(include):
|
||||
'Return a list containg the include dir and all its subdirectories'
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
*.pyc
|
||||
*.exp
|
||||
*.lib
|
||||
*.obj
|
||||
*.arg
|
||||
*.dll
|
||||
*.cpp
|
||||
.sconsign
|
||||
|
||||
@@ -47,8 +47,13 @@ env = Environment(
|
||||
modules = [os.path.splitext(os.path.basename(x))[0] for x in glob.glob('../example/*.pyste')]
|
||||
for module in modules:
|
||||
multiple = ARGUMENTS.get('multiple', '')
|
||||
if multiple:
|
||||
env.SharedLibrary(target=module, source=glob.glob(module+'/*.cpp'))
|
||||
example_cpp = '../example/%s.cpp' % module
|
||||
if os.path.isfile(example_cpp):
|
||||
sources = [example_cpp]
|
||||
else:
|
||||
env.SharedLibrary(target=module, source=module + '.cpp')
|
||||
sources = []
|
||||
if multiple:
|
||||
env.SharedLibrary(target=module, source=sources + glob.glob('_%s/*.cpp'%module))
|
||||
else:
|
||||
env.SharedLibrary(target=module, source=sources + ['_%s.cpp' % module])
|
||||
|
||||
|
||||
18
pyste/tests/example_opaqueUT.py
Normal file
18
pyste/tests/example_opaqueUT.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import unittest
|
||||
from opaque import *
|
||||
|
||||
class OpaqueTest(unittest.TestCase):
|
||||
|
||||
def testIt(self):
|
||||
|
||||
c = new_C()
|
||||
self.assertEqual(get(c), 10)
|
||||
a = A()
|
||||
d = a.new_handle()
|
||||
self.assertEqual(a.get(d), 3.0)
|
||||
self.assertEqual(a.f(), 0)
|
||||
self.assertEqual(a.f(3), 3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -11,3 +11,4 @@ call nt_build_pyste.bat unions %1
|
||||
call nt_build_pyste.bat virtual %1
|
||||
call nt_build_pyste.bat virtual2 %1
|
||||
call nt_build_pyste.bat wrappertest %1
|
||||
call nt_build_pyste.bat opaque %1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@echo off
|
||||
set BOOST_INCLUDE=D:\Programming\Libraries\boost-cvs\boost
|
||||
set out=%1.cpp
|
||||
if "%2" == "--multiple" set out=%1
|
||||
set out=_%1.cpp
|
||||
if "%2" == "--multiple" set out=_%1
|
||||
rem python ../src/pyste.py %2 -I%BOOST_INCLUDE -I../example --module=%1 --out=%out ../example/%1.pyste
|
||||
pyste %2 -I%BOOST_INCLUDE -I../example --module=%1 --out=%out ../example/%1.pyste
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
@echo off
|
||||
|
||||
rm -Rf basic
|
||||
rm -Rf enums
|
||||
rm -Rf header_test
|
||||
rm -Rf nested
|
||||
rm -Rf operators
|
||||
rm -Rf smart_ptr
|
||||
rm -Rf templates
|
||||
rm -Rf unions
|
||||
rm -Rf virtual
|
||||
rm -Rf virtual2
|
||||
rm -Rf wrappertest
|
||||
rm -Rf _basic
|
||||
rm -Rf _enums
|
||||
rm -Rf _header_test
|
||||
rm -Rf _nested
|
||||
rm -Rf _operators
|
||||
rm -Rf _smart_ptr
|
||||
rm -Rf _templates
|
||||
rm -Rf _unions
|
||||
rm -Rf _virtual
|
||||
rm -Rf _virtual2
|
||||
rm -Rf _wrappertest
|
||||
rm -Rf _opaque
|
||||
|
||||
rm -f *.cpp
|
||||
rm -f *.obj
|
||||
@@ -19,3 +20,4 @@ rm -f *.arg
|
||||
rm -f *.dll
|
||||
rm -f *.pyc
|
||||
rm -f *.lib
|
||||
rm -f ../example/*.obj
|
||||
|
||||
Reference in New Issue
Block a user