pygccxml-commit Mailing List for C++ Python language bindings (Page 72)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2006-05-08 17:08:39
|
Revision: 65 Author: roman_yakovenko Date: 2006-05-08 00:00:13 -0700 (Mon, 08 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=65&view=rev Log Message: ----------- adding introduction to call wrapper policies Added Paths: ----------- pyplusplus_dev/docs/call_wrapper_policies/ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py Added: pyplusplus_dev/docs/call_wrapper_policies/introduction.rest =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/introduction.rest (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,241 @@ +===================== +call wrapper policies +===================== + +.. contents:: Table of contents + +------------------- +What is useful for? +------------------- +Not all C++ functions could be exposed to Python as is. For example, next function +could not be exposed: +:: + + void get_size( int& size ); + +In order to expose ``get_size`` function, an user need to create next wrapper: +:: + + int get_size_wrapper( ){ + int size(0); + get_size( size ); + return size; + } + +|cwp| will provide the user with simple and intuitive way to instruct +`pyplusplus`_ to generate right wrapper. Also, it will be possible to create +a custom policies. + +-------- +Analysis +-------- + +C++ function arguments usage +---------------------------- + +In C++ function argument can be used to: + +* to pass some data to function ( in ) + + there is no need to return variable from the function + +* to return some data from function ( out ) + + there is no need to force Python programmer to pass the variable as argument + to the function + +* both ( in/out ) + +Function-wrapper signature will be a little bit different in every case. + +Variable names +-------------- +I think it should be possible to apply few |cwp| on a single function. Thus, it +will be possible to create few convinience function, from one single function. +The main,read unresolved, issue, is management of variable names within function-wrapper. +I see next problems, that we should solve, before proceeding to implementation: + +1. To share variable name, between different pieces of code. + + Right now I think, that every |cwp| will have ``pre-call`` and ``post-call`` + code creators. This design will allow the user to mix few |cwp|'s within + single function-wrapper. + +2. To insure name uniqueness. + +3. To give meaningful name. + +I think, that is it very easy to solve the problem, if I remove "readability" +requirement. + +Call policies +------------- +I don't have any solution to the next problem. +I am going to change a little an example, from `boost.python`_ tutorials: +http://www.boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies +:: + + //C++ code + struct Y + { + X x; Z* z; + int z_value() { return z->value(); } + }; + + X& f(Y& y, Z* z, int& error) + { + y.z = z; + return y.x; + } + + //boost.python code + def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >() ); + +What is the difference? Function ``f`` now takes 3rd argument - ``int&``. This +function could not be called from `Python`_. ( Hint: numbers are immutable +objects in `Python`_ ). So in order to expose function ``f`` to `Python`_, +an user need to create a wrapper. And now he has a problem: how to wrap the function? + +I see only one solution user have to change signature of function ``f``. +Now some speculations: + +1. May be it is possible with `boost.python`_ library to set call policies on the + part of the return value? + :: + + boost::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + return boost::tuple<X&, int>( x, error ); + } + + def("f", f_wrapper, smart call policies that will work only on first element within the tuple ); + +2. May be it is possible to create boost.python ``object`` with life-time management + hint? + :: + + boost::python::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + boost::python::object x_obj( x, x is internal reference of y ); + return boost::python::make_tuple( x_obj, error ); + } + +Anyway, I think we will just ignore the problem - software ( == boost.python ) +should not be perfect - it should work in most ( != all ) cases! + +------------ +Common |cwp| +------------ +Those names are not final and could( may be should ) be changed. + +immutable by reference +----------------------- +:: + + //function to be exported + something f( int& i, std::string& str ) + +I suppose this is very common use case. More over this use case `pyplusplus`_ +can and will treat by its own - no user action is needed. The wrapper +generated by `pyplusplus`_ will very similar to the next code: +:: + + void f_wrapper( const int& i, const std::string& str ){ + int i_out( i ); + std::string str_out( str ); + boost::python::object f_return = f( i_out, str_out ); + return boost::python::make_tuple( f_return, i, str ); + } + + +The only customization available for user is to setup argument type: +[in\|out\|in,out] + +array +----- +Arrays are a little bit different beasts. Python does not have arrays. +So, `pyplusplus`_, should implement arrays convertion: from/to C++/Python. +This is not the only difference, consider next function: +:: + + void fill( char* buffer, int index ){ + buffer[ index ] = 'c'; + } + + +There are few ways to expose this function: +:: + + ??? fill_wrapper( boost::python:list buffer, index ){ + long buffer_size = boost::python::extract<long>( buffer.attr("__len__") ); + boost::scoped_array<char> buffer_( new char[ buffer_size ] ); + for( long i = 0; i < buffer_size; ++i ){ + buffer_[ i ] = boost::python::extract<char>( buffer[i] ); + } + fill( buffer_.get(), index ); + //Now the question: how to return buffer_ to the caller? + //by constructing new list? + boost::python::list return_; + for( long i = 0; i < buffer_size; ++i ){ + return_.insert( i, buffer_[i] ); + } + return return_; + //or by modifying the buffer argument? In this case `pyplusplus`_ will + //delete all items from buffer and will copy into it items from buffer_ + //variable. + } + +Arrays size +~~~~~~~~~~~ +1. static array - size of array is known at compile time. +2. dynamic array + + + size of array is one of the function arguments + + + other ( will not be implemented in the first phase ) + + - size of array is some global/local variable + + - ize of array is returned by invocation some function + + +status as exception +------------------- +There a lot of code, that returns success status and/or error description by +using one of the function arguments. It will be possible to instruct `pyplusplus`_ +to create wrapper for those functions, that will throw exception. +:: + + bool do_smth( error_description& error_desc ); + + bool do_smth_wrapper(){ + error_description error_desc; + bool return_ = do_smth( error_desc ); + if( some user code that will check that error_desc contains error ){ + throw some user code that will construct an exception from the error_desc; + } + return return_; + } + +pythread safe +------------- +Why not :-)? See next FAQ: http://boost.org/libs/python/doc/v2/faq.html#threadsupport +So, how `pyplusplus`_ can help? `pyplusplus`_ can generate exception safe code, +that will acquire and release Python global interpreter lock. + + +.. _`pyplusplus` : ./../pyplusplus.html +.. |cwp| replace:: *"call wrapper policies"* +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,2 @@ +name = 'call wrapper policies' +main_html_file = 'introduction.html' \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-08 17:08:38
|
Revision: 66 Author: roman_yakovenko Date: 2006-05-08 00:13:21 -0700 (Mon, 08 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=66&view=rev Log Message: ----------- fixing links Modified Paths: -------------- pyplusplus_dev/docs/tutorials/module_builder/module_builder.rest Modified: pyplusplus_dev/docs/tutorials/module_builder/module_builder.rest =================================================================== --- pyplusplus_dev/docs/tutorials/module_builder/module_builder.rest 2006-05-08 07:00:13 UTC (rev 65) +++ pyplusplus_dev/docs/tutorials/module_builder/module_builder.rest 2006-05-08 07:13:21 UTC (rev 66) @@ -8,7 +8,7 @@ What is pyplusplus? ------------------- -.. include:: ./../definition.rest +.. include:: ./../../definition.rest -------- Preamble @@ -22,8 +22,8 @@ * `generate_code.py`_ - Python code, that uses `pyplusplus`_ to export declarations from the source file -.. _`hello_world.hpp` : ./module_builder_hello_world.html -.. _`generate_code.py` : ./module_builder_generate_code.html +.. _`hello_world.hpp` : ./hello_world.html +.. _`generate_code.py` : ./generate_code.html ---------------- module_builder_t @@ -146,13 +146,13 @@ `View generated file`_ -.. _`View generated file` : ./module_builder_hello_world_result.html +.. _`View generated file` : ./result.html That's all. I hope you enjoyed. -.. _`pyplusplus` : ./../pyplusplus.html -.. _`pygccxml` : ./../../pygccxml/pygccxml.html +.. _`pyplusplus` : ./../../pyplusplus.html +.. _`pygccxml` : ./../../../pygccxml/pygccxml.html .. _`boost.python`: http://www.boost.org/libs/python/doc/index.html .. _`SourceForge`: http://sourceforge.net/index.php .. _`Python`: http://www.python.org This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-04 16:37:46
|
Revision: 64 Author: mbaas Date: 2006-05-04 09:37:40 -0700 (Thu, 04 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=64&view=rev Log Message: ----------- Added the contrib directory and the 'arrayinfo' helper utility Added Paths: ----------- pyplusplus_dev/contrib/ pyplusplus_dev/contrib/arrayinfo/ pyplusplus_dev/contrib/arrayinfo/arrayinfo.py pyplusplus_dev/contrib/arrayinfo/cpptokenize.py pyplusplus_dev/contrib/arrayinfo/createarrayinfo.py pyplusplus_dev/contrib/arrayinfo/readme.txt Added: pyplusplus_dev/contrib/arrayinfo/arrayinfo.py =================================================================== --- pyplusplus_dev/contrib/arrayinfo/arrayinfo.py (rev 0) +++ pyplusplus_dev/contrib/arrayinfo/arrayinfo.py 2006-05-04 16:37:40 UTC (rev 64) @@ -0,0 +1,72 @@ +###################################################################### +# Array info +# +# Author: Matthias Baas (ba...@ir...) +###################################################################### + +# ArrayInfo +class ArrayInfo: + """Reads the information that was created by createarrayinfo.py. + + Usage: + + Create an instance of this class and either provide the file + name in the constructor or call read() manually. After the info + file has been read you can call arraySize() to retrieve the + size of a particular argument. + """ + + def __init__(self, datfile=None): + """Constructor. + + datfile is the name of the file that contains the array size + information (as created by the createarrayinfo.py utility). + If a name is provided is already read in (so there's no need + to manually call read() anymore). + """ + + # Key: (filename, firstline, funcname) + self.funcargs = {} + + if datfile!=None: + self.read(datfile) + + # read + def read(self, datfile): + """Read an info file. + """ + + n = 0 + for s in file(datfile, "rt"): + a = s.split(";") + filename, firstline, lastline, classname, funcname, args = a + firstline = int(firstline) + lastline = int(lastline) + args = eval(args) + key = (filename, lastline, funcname) + self.funcargs[key] = args + n += 1 + print n,"entries read from",datfile + + # arraySize + def arraySize(self, decl, idx): + """Return the array size of an argument. + + decl is the pygccxml calldef declaration whose argument list + should be inspected. idx is the index of the argument (0-based). + The return value is None if the argument is no array or the + array size is not known, otherwise the size of the array is + returned. + """ + filename = decl.location.file_name + line = decl.location.line + funcname = decl.name + args = self.funcargs.get((filename, line, funcname)) + if args==None: + return None + if idx>=len(args): + return None + else: + return args[idx] + + Added: pyplusplus_dev/contrib/arrayinfo/cpptokenize.py =================================================================== --- pyplusplus_dev/contrib/arrayinfo/cpptokenize.py (rev 0) +++ pyplusplus_dev/contrib/arrayinfo/cpptokenize.py 2006-05-04 16:37:40 UTC (rev 64) @@ -0,0 +1,119 @@ +########################################################################### +# C/C++ tokenizer +# Copyright (C) 2006 Matthias Baas (ba...@ir...) +########################################################################### + +"""C/C++ tokenizer module. + +This module provides the function tokenize() that just works like the +equivalent Python function with the only difference that it scans +C/C++ source code. +""" + +import re + +WHITESPACE = 0 +NAME = 1 +NUMBER = 2 +STRING = 3 +NEWLINE = 4 +OPERATOR = 5 +CHARACTER = 6 + +# tokenize +def tokenize(readline, tokeater): + """Reads a C/C++ input stream and creates tokens. + + The first parameter, readline, must be a callable object which + provides the same interface as the readline() method of built-in + file objects. Each call to the function should return one line of + input as a string. + + The second parameter, tokeneater, must also be a callable object. + It is called with six parameters: the token type, the token + string, a tuple (srow, scol) specifying the row and column where + the token begins in the source, a tuple (erow, ecol) giving the + ending position of the token, the line on which the token was + found and the filename of the current file. + + By default the filename argument is an empty string. It will only + be the actual filename if you provide a preprocessed file stream + as input (so you should first run cpp on any source code). The + tokenizer actually expects preprocessed data as it doesn't handle + comments. + """ + + regs = ( (WHITESPACE, re.compile(r"[ \t]+")), + (NAME, re.compile(r"[A-Za-z_][A-Za-z_0-9]*")), + (NUMBER, re.compile(r"[0-9]+(\.[0-9]+)?(E(\+|-)?[0-9]+)?")), + (STRING, re.compile(r"\"[^\"]*\"|'[^\']*\'")), + (OPERATOR, re.compile(r"->|::|\+\+|--|->\*|\.\*|<<|>>|<=|>=|==|!=|&&|\|\||\+=|-=|\*=|/=|%=|&=|\^=|\|=|<<=|>>=|\(|\)|\[|\]|\.|\+|-|!|~|\*|/|&|\^|%|<|>|\?|:|=")), + (NEWLINE, re.compile(r"\n")) + ) + + linenr = 0 + filename = "" + while 1: + # Read next line + line = readline() + # No more lines? then finish + if line=="": + break + + linenr+=1 + # Base for starting column... + scolbase = 0 + + # Process preprocessor lines... + if line[0]=="#": + try: + f = line.strip().split(" ") + linenr = int(f[1])-1 + filename = f[2][1:-1] + except: + pass + continue + + s = line + + # Create tokens... + while s!="": + unmatched=1 + # Check all regular expressions... + for r in regs: + m=r[1].match(s) + # Does it match? then the token is found + if m!=None: + scol = m.start() + ecol = m.end() + tok = s[scol:ecol] + s = s[ecol:] + typ = r[0] + tokeater(typ, tok, (linenr, scolbase+scol), (linenr, scolbase+ecol), line, filename) + scolbase += ecol + unmatched=0 + continue + + # No match? then report a single character... + if unmatched: + tok = s[0] + tokeater(CHARACTER, tok, (linenr, scolbase), (linenr, scolbase+1), line, filename) + s = s[1:] + scolbase += 1 + + +def _tokeater(type, s, start, end, line, filename): + """Test token eater.""" + if type==WHITESPACE or type==NEWLINE: + return + type_str = ["WHITESPACE", "NAME", "NUMBER", "STRING", "NEWLINE", "OPERATOR", "CHARACTER"] + + print "Token: %-11s %-20s %s %s %s"%(type_str[type],s, start,end,filename) + +###################################################################### + +if __name__=="__main__": + + f=open("header.h") + tokenize(f.readline, _tokeater) + Added: pyplusplus_dev/contrib/arrayinfo/createarrayinfo.py =================================================================== --- pyplusplus_dev/contrib/arrayinfo/createarrayinfo.py (rev 0) +++ pyplusplus_dev/contrib/arrayinfo/createarrayinfo.py 2006-05-04 16:37:40 UTC (rev 64) @@ -0,0 +1,163 @@ +#!/usr/bin/env python +###################################################################### +# This tool parses header files inside a directory and stores info +# about the array size of function arguments into a file for later +# retrieval. +# +# usage: createarrayinfo.py [options] <headerpath> +# +# options: +# -h, --help show this help message and exit +# -o FILENAME, --output=FILENAME +# Output file name (default: stdout) +# -a ARGSTRING, --cppargs=ARGSTRING +# Additional C preproceesor arguments +# +# Author: Matthias Baas (ba...@ir...) +###################################################################### + +import sys, os, os.path, glob, optparse +from cpptokenize import * + +# Parser +class Parser: + """Parser class. + + This class contains the token eater method that processes the tokens + generated by cpptokenize. + Whenever a function signature is parsed a line is written to the output. + """ + + def __init__(self, headerpath, output=sys.stdout): + """Constructor. + """ + + self.headerpath = os.path.normpath(headerpath) + self.output = output + + # Buffer for the last NAME token (which might be a function name) + self.lastname = None + # The current state + self.state = "Outside" + + self.classname = None + self.funcname = None + self.args = None + self.arraysize = None + self.no_arg = False + self.firstline = None + + def tokeater(self, type, s, start, end, line, filename): + """Token eater.""" + if type==WHITESPACE or type==NEWLINE: + return + + method = getattr(self, "state%s"%self.state) + method(type, s, start, end, line, filename) + + # The state methods. They are called by the token eater and must take + # the same arguments than the token eater. + + def stateOutside(self, type, s, start, end, line, filename): + if type==NAME and s=="class": + self.state = "ClassName" + if type==NAME: + self.firstline = start[0] + self.lastname = s + elif self.lastname=="operator": + self.lastname += s + elif type==OPERATOR and s=="(": + self.funcname = self.lastname + self.args = [] + self.arraysize = None + self.no_arg = True + self.state = "Args" + + def stateClassName(self, type, s, start, end, line, filename): + if s.upper()==s: + return + self.classname = s + self.state = "Outside" + + def stateArgs(self, type, s, start, end, line, filename): + if s==")": + if not self.no_arg: + self.args.append(self.arraysize) + self.state = "End" + elif s==",": + self.args.append(self.arraysize) + self.arraysize = None + elif s=="[": + self.state = "ArgsSize" + self.no_arg = False + + def stateArgsSize(self, type, s, start, end, line, filename): + if s=="]": + self.state = "Args" + else: + self.arraysize = int(s) + self.state = "Args" + + def stateEnd(self, type, s, start, end, line, filename): + if s==";": + if os.path.normpath(os.path.dirname(filename))==self.headerpath: + self.onFuncComplete(self.classname, self.funcname, self.args, self.firstline, end[0], filename) + self.state = "Outside" + + + def onFuncComplete(self, classname, funcname, args, firstline, lastline, filename): + """Callback that is called when one function is completely processed. + """ + print >>self.output, "%s;%d;%d;%s;%s;%s"%(filename, firstline, lastline, classname, funcname, args) + + +# parseHeader +def parseHeader(filename, cpp="cpp", cppargs="", output=sys.stdout): + """Parse a header file. + + filename is the header file name and cppargs is a string with + additional arguments for the invocation of the preprocessor 'cpp'. + output is the output stream. + """ + # Run the file through the preprocessor... + filename = os.path.abspath(filename) + print >>sys.stderr, "Parsing",filename + cmd = "%s %s %s >_tmp.h"%(cpp, cppargs, filename) + print >>sys.stderr, cmd + os.system(cmd) + + # Parse the preprocessed file... + parser = Parser(os.path.dirname(filename), output) + tokenize(file("_tmp.h").readline, parser.tokeater) + +###################################################################### + +# Preprocessor +cpp = "cpp" +# Preprocessor arguments +cppargs = "" +# Output stream +output = sys.stdout + +usage = "usage: %prog [options] <headerpath>" +op = optparse.OptionParser(usage) +op.add_option("-o", "--output", metavar="FILENAME", + help="Output file name") +op.add_option("-a", "--cppargs", metavar="ARGSTRING", default="", + help="Additional C preproceesor arguments") + +options, args = op.parse_args() + +if len(args)==0: + op.print_help() + sys.exit(1) + +if options.output!=None: + output = file(options.output, "wt") + +cppargs = options.cppargs + +headerpath = args[0] +headers = glob.glob(os.path.join(headerpath, "*.h")) +for header in headers: + parseHeader(header, cpp, cppargs, output) Property changes on: pyplusplus_dev/contrib/arrayinfo/createarrayinfo.py ___________________________________________________________________ Name: svn:executable + * Added: pyplusplus_dev/contrib/arrayinfo/readme.txt =================================================================== --- pyplusplus_dev/contrib/arrayinfo/readme.txt (rev 0) +++ pyplusplus_dev/contrib/arrayinfo/readme.txt 2006-05-04 16:37:40 UTC (rev 64) @@ -0,0 +1,33 @@ +Array info utility +================== + +Author: Matthias Baas (ba...@ir...) + +This directory contains a small utility that can be used to determine +the array size of a function argument. For example, suppose you have +a C function that is defined as: + + void foo(double v[3]); + +When this function is parsed by gccxml the type of "v" will just be +reported as "double *" and the array size has got lost. +However, for creating Python wrappers the array size is a valuable +information that can be exploited for creating appropriate wrapper +functions automatically. + +The command line utility "createarrayinfo.py" can be used to parse +the original header files and extract just the above array sizes +from function definitions. This information is stored in a file that +can then be read by your own Python scripts that create Python bindings +using pyplusplus. In your own scripts you can use the "arrayinfo" module +to read the info file and query the array size of a particular argument +from a particular function (given as a pygccxml declaration object). + +See the comments and doc strings in the Python files to get more +usage information. + +NOTE: While the utility did work for me, it is not as general to deal +with all eventualities (it only uses a very simple C/C++ parser). +So it might well be that you have to adjust the code in +createarrayinfo.py to your own needs. + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-04 05:21:43
|
Revision: 63 Author: roman_yakovenko Date: 2006-05-03 22:21:37 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=63&view=rev Log Message: ----------- adding new TODO item Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/member_variable.py Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-03 09:27:12 UTC (rev 62) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-04 05:21:37 UTC (rev 63) @@ -358,7 +358,9 @@ answer.append( ''.join( temp ) ) answer.append( ' );' ) return ''.join( answer ) - + +#TODO: generated fucntion should be static and take instance of the wrapped class +#as first argument. class array_mv_wrapper_t( declaration_based.declaration_based_t ): """ Creates C++ code that register array class. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-03 09:27:16
|
Revision: 62 Author: mbaas Date: 2006-05-03 02:27:12 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=62&view=rev Log Message: ----------- Turned the info messages into debug messages Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/scopedef.py Modified: pygccxml_dev/pygccxml/declarations/scopedef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/scopedef.py 2006-05-03 09:09:56 UTC (rev 61) +++ pygccxml_dev/pygccxml/declarations/scopedef.py 2006-05-03 09:27:12 UTC (rev 62) @@ -6,56 +6,56 @@ """ defines base class for L{namespace_t} and L{class_t} classes """ - + import time -import algorithm +import algorithm import filtering -import declaration -import mdecl_wrapper +import declaration +import mdecl_wrapper from pygccxml import utils -import matcher as matcher_module +import matcher as matcher_module class scopedef_t( declaration.declaration_t ): """Base class for L{namespace_t} and L{class_t} classes. This is the base class for all declaration classes that may have children nodes. The children can be accessed via the C{declarations} - property. - - Also this class provides "get/select/find" interface. Using this class you - can get instance or instances of internal declaration(s). - - You can find declaration(s) using next criteria: - 1. name - declaration name, could be full qualified name - 2. header_dir - directory, to which belongs file, that the declaration was declarated in. - header_dir should be absolute path. - 3. header_file - file that the declaration was declarated in. - 4. function - user ( your ) custom criteria. The interesting thing is that - this function will be joined with other arguments ( criteria ). - 5. recursive - the search declaration range, if True will be search in - internal declarations too. - - Every "select" API you can invoke and pass as first argument at declaration - name or function. This class will find out correctly what argument represents. - - Example:: - ns - referrers to global namespace - ns.member_function( "do_something ) - will return reference to member - function named "do_something". If there is no such function exception - will be raised. If there is more then one function exception will be - raised too. - - Example 2:: - ns - referers to global namespace - do_smths = ns.member_functions( "do_something ) - will return instance - of L{mdecl_wrapper_t} object. This object allows you few things: - - 1. To iterate on selected declarations - 2. To set some property to desired value using one line of code only: - do_smths.call_policies = x - 3. To call some function on every instance using one line of code: - do_smths.exclude() - + property. + + Also this class provides "get/select/find" interface. Using this class you + can get instance or instances of internal declaration(s). + + You can find declaration(s) using next criteria: + 1. name - declaration name, could be full qualified name + 2. header_dir - directory, to which belongs file, that the declaration was declarated in. + header_dir should be absolute path. + 3. header_file - file that the declaration was declarated in. + 4. function - user ( your ) custom criteria. The interesting thing is that + this function will be joined with other arguments ( criteria ). + 5. recursive - the search declaration range, if True will be search in + internal declarations too. + + Every "select" API you can invoke and pass as first argument at declaration + name or function. This class will find out correctly what argument represents. + + Example:: + ns - referrers to global namespace + ns.member_function( "do_something ) - will return reference to member + function named "do_something". If there is no such function exception + will be raised. If there is more then one function exception will be + raised too. + + Example 2:: + ns - referers to global namespace + do_smths = ns.member_functions( "do_something ) - will return instance + of L{mdecl_wrapper_t} object. This object allows you few things: + + 1. To iterate on selected declarations + 2. To set some property to desired value using one line of code only: + do_smths.call_policies = x + 3. To call some function on every instance using one line of code: + do_smths.exclude() + Pay attention: you can not use "get" functions or properties. """ @@ -115,7 +115,7 @@ if base is declaration.declaration_t: continue if base in visited: - continue + continue if 'pygccxml' not in base.__module__: continue types.append( base ) @@ -146,7 +146,7 @@ Almost every query includes declaration type information. Also very common query is to search some declaration(s) by name or full name. Those hashtables allows to search declaration very quick. - """ + """ if self.name == '::': utils.logger.debug( "preparing data structures for query optimizer - started" ) start_time = time.clock() @@ -226,15 +226,15 @@ matcher = match_class( **matcher_args ) if keywds['function']: - utils.logger.info( 'running query: %s and <user defined function>' % str( matcher ) ) + utils.logger.debug( 'running query: %s and <user defined function>' % str( matcher ) ) return lambda decl: matcher( decl ) and keywds['function'](decl) else: - utils.logger.info( 'running query: %s' % str( matcher ) ) + utils.logger.debug( 'running query: %s' % str( matcher ) ) return matcher def __findout_range( self, name, decl_type, recursive ): if not self._optimized: - utils.logger.info( 'running non optimized query - optimization has not been done' ) + utils.logger.debug( 'running non optimized query - optimization has not been done' ) decls = self.declarations if recursive: decls = algorithm.make_flatten( self.declarations ) @@ -245,34 +245,34 @@ if matcher.is_full_name(): name = matcher.decl_name_only if recursive: - utils.logger.info( 'query has been optimized on type and name' ) + utils.logger.debug( 'query has been optimized on type and name' ) if self._type2name2decls[decl_type].has_key( name ): return self._type2name2decls[decl_type][name] else: return [] else: - utils.logger.info( 'non recursive query has been optimized on type and name' ) + utils.logger.debug( 'non recursive query has been optimized on type and name' ) if self._type2name2decls_nr[decl_type].has_key( name ): return self._type2name2decls_nr[decl_type][name] else: return [] elif decl_type: if recursive: - utils.logger.info( 'query has been optimized on type' ) + utils.logger.debug( 'query has been optimized on type' ) return self._type2decls[ decl_type ] else: - utils.logger.info( 'non recursive query has been optimized on type' ) + utils.logger.debug( 'non recursive query has been optimized on type' ) return self._type2decls_nr[ decl_type ] else: if recursive: - utils.logger.info( 'query has not been optimized ( hint: query does not contain type and/or name )' ) + utils.logger.debug( 'query has not been optimized ( hint: query does not contain type and/or name )' ) return self._all_decls else: - utils.logger.info( 'non recursive query has not been optimized ( hint: query does not contain type and/or name )' ) + utils.logger.debug( 'non recursive query has not been optimized ( hint: query does not contain type and/or name )' ) return self.declarations def _find_single( self, match_class, **keywds ): - utils.logger.info( 'find single query execution - started' ) + utils.logger.debug( 'find single query execution - started' ) start_time = time.clock() norm_keywds = self.__normalize_args( **keywds ) matcher = self.__create_matcher( match_class, **norm_keywds ) @@ -280,11 +280,11 @@ recursive_ = self.__findout_recursive( **norm_keywds ) decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) found = matcher_module.matcher.get_single( matcher, decls, False ) - utils.logger.info( 'find single query execution - done( %f seconds )' % ( time.clock() - start_time ) ) + utils.logger.debug( 'find single query execution - done( %f seconds )' % ( time.clock() - start_time ) ) return found def _find_multiple( self, match_class, **keywds ): - utils.logger.info( 'find all query execution - started' ) + utils.logger.debug( 'find all query execution - started' ) start_time = time.clock() norm_keywds = self.__normalize_args( **keywds ) matcher = self.__create_matcher( match_class, **norm_keywds ) @@ -294,8 +294,8 @@ decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) found = matcher_module.matcher.find( matcher, decls, False ) mfound = mdecl_wrapper.mdecl_wrapper_t( found ) - utils.logger.info( '%d declaration(s) that match query' % len(mfound) ) - utils.logger.info( 'find single query execution - done( %f seconds )' + utils.logger.debug( '%d declaration(s) that match query' % len(mfound) ) + utils.logger.debug( 'find single query execution - done( %f seconds )' % ( time.clock() - start_time ) ) if not mfound and not allow_empty: raise RuntimeError( "Multi declaration query returned 0 declarations." ) @@ -306,7 +306,7 @@ """Finds any declaration by criteria. Please see L{scopedef_t} for full explanation.""" return self._find_single( self._impl_matchers[ scopedef_t.decl ] , name=name - , function=function + , function=function , decl_type=decl_type , header_dir=header_dir , header_file=header_file @@ -315,7 +315,7 @@ def decls( self, name=None, function=None, decl_type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): return self._find_multiple( self._impl_matchers[ scopedef_t.decl ] , name=name - , function=function + , function=function , decl_type=decl_type , header_dir=header_dir , header_file=header_file @@ -523,4 +523,4 @@ , recursive=recursive , allow_empty=allow_empty) #adding small aliase - enums = enumerations \ No newline at end of file + enums = enumerations This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-03 09:10:01
|
Revision: 61 Author: mbaas Date: 2006-05-03 02:09:56 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=61&view=rev Log Message: ----------- Added the apidocs directory to the ignore list Property Changed: ---------------- pygccxml_dev/docs/ Property changes on: pygccxml_dev/docs ___________________________________________________________________ Name: svn:ignore + apidocs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-03 09:08:45
|
Revision: 60 Author: mbaas Date: 2006-05-03 02:08:37 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=60&view=rev Log Message: ----------- Removed the apidocs directory Removed Paths: ------------- pygccxml_dev/docs/apidocs/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-03 09:07:29
|
Revision: 59 Author: mbaas Date: 2006-05-03 02:07:23 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=59&view=rev Log Message: ----------- Added the apidocs directory to the ignore list Property Changed: ---------------- pyplusplus_dev/docs/ Property changes on: pyplusplus_dev/docs ___________________________________________________________________ Name: svn:ignore + apidocs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-05-03 09:04:53
|
Revision: 58 Author: mbaas Date: 2006-05-03 02:04:48 -0700 (Wed, 03 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=58&view=rev Log Message: ----------- Removed the apidocs directory Removed Paths: ------------- pyplusplus_dev/docs/apidocs/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:47:11
|
Revision: 57 Author: roman_yakovenko Date: 2006-05-01 22:46:59 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=57&view=rev Log Message: ----------- switching to epidoc API instead of command line Modified Paths: -------------- pygccxml_dev/setup.py Modified: pygccxml_dev/setup.py =================================================================== --- pygccxml_dev/setup.py 2006-05-02 05:37:14 UTC (rev 56) +++ pygccxml_dev/setup.py 2006-05-02 05:46:59 UTC (rev 57) @@ -12,18 +12,19 @@ def generate_doc(): """Generate the epydoc reference manual. """ - print "Generating epydoc files..." - options = [ '--output="%s"'%os.path.join('docs', 'apidocs'), - '--docformat=epytext', - '--url=http://www.language-binding.net', - '--name=pygccxml', -# '--verbose', - 'pygccxml'] - cmd_line = "epydoc " + ' '.join( options ) - print cmd_line - os.system(cmd_line) + print "Generating epydoc files..." + + from epydoc.docbuilder import build_doc_index + from epydoc.docwriter.html import HTMLWriter + + docindex = build_doc_index(['pygccxml']) + html_writer = HTMLWriter( docindex + , prj_name='pygccxml' + , prj_url='http://www.language-binding.net' + , include_sourcecode=True ) + + html_writer.write( os.path.join('docs', 'apidocs') ) - class doc_cmd(Command): """This is a new distutils command 'doc' to build the epydoc manual. """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:37:28
|
Revision: 56 Author: roman_yakovenko Date: 2006-05-01 22:37:14 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=56&view=rev Log Message: ----------- adding few items to "ignore" list Property Changed: ---------------- pyplusplus_dev/examples/pyboost_dev/pyboost/random/generated/ pyplusplus_dev/unittests/temp/ Property changes on: pyplusplus_dev/examples/pyboost_dev/pyboost/random/generated ___________________________________________________________________ Name: svn:ignore + random.pypp.cpp Property changes on: pyplusplus_dev/unittests/temp ___________________________________________________________________ Name: svn:ignore - internal_classes.dll member_functions.dll member_variables.dll module_body.dll namespaces.dll noncopyable.dll operators.dll operators_bug.dll optional.dll optional_bug.dll pointer_as_arg.dll pointer_to_function_as_argument.dll private_assign.dll recursive.dll regression1.dll regression2.dll regression3.dll smart_pointers.dll special_operators.dll statics.dll temprorary_variable.dll unnamed_enums.dll user_text.dll abstract.cpp~ call_policies.cpp~ casting.cpp~ class_order2.cpp~ class_order3.cpp~ class_order4.cpp~ class_order.cpp~ classes.cpp~ enums.cpp~ factory.cpp~ finalizables.cpp~ free_functions.cpp~ free_operators.cpp~ global_variables.cpp~ index_operator.cpp~ internal_classes.cpp~ member_functions.cpp~ member_variables.cpp~ noncopyable.cpp~ operators_bug.cpp~ optional.cpp~ optional_bug.cpp~ pointer_as_arg.cpp~ pointer_to_function_as_argument.cpp~ private_assign.cpp~ recursive.cpp~ regression1.cpp~ regression2.cpp~ regression3.cpp~ smart_pointers.cpp~ special_operators.cpp~ statics.cpp~ temprorary_variable.cpp~ unnamed_enums.cpp~ user_text.cpp~ abstract.exp call_policies.exp casting.exp class_order2.exp class_order3.exp class_order4.exp class_order.exp classes.exp enums.exp factory.exp finalizables.exp free_function_ignore_bug.exp free_functions.exp free_operators.exp global_variables.exp index_operator.exp internal_classes.exp member_functions.exp member_variables.exp module_body.exp namespaces.exp noncopyable.exp operators.exp operators_bug.exp optional.exp optional_bug.exp pointer_as_arg.exp pointer_to_function_as_argument.exp private_assign.exp recursive.exp regression1.exp regression2.exp regression3.exp smart_pointers.exp special_operators.exp statics.exp temprorary_variable.exp unnamed_enums.exp user_text.exp abstract.lib call_policies.lib casting.lib class_order2.lib class_order3.lib class_order4.lib class_order.lib classes.lib enums.lib factory.lib finalizables.lib free_function_ignore_bug.lib free_functions.lib free_operators.lib global_variables.lib index_operator.lib internal_classes.lib member_functions.lib member_variables.lib module_body.lib namespaces.lib noncopyable.lib operators.lib operators_bug.lib optional.lib optional_bug.lib pointer_as_arg.lib pointer_to_function_as_argument.lib private_assign.lib recursive.lib regression1.lib regression2.lib regression3.lib smart_pointers.lib special_operators.lib statics.lib temprorary_variable.lib unnamed_enums.lib user_text.lib abstract.obj call_policies.obj casting.obj class_order2.obj class_order3.obj class_order4.obj class_order.obj classes.obj enums.obj factory.obj finalizables.obj free_function_ignore_bug.obj free_functions.obj free_operators.obj global_variables.obj index_operator.obj internal_classes.obj member_functions.obj member_variables.obj module_body.obj namespaces.obj noncopyable.obj operators.obj operators_bug.obj optional.obj optional_bug.obj pointer_as_arg.obj pointer_to_function_as_argument.obj private_assign.obj recursive.obj regression1.obj regression2.obj regression3.obj smart_pointers.obj special_operators.obj statics.obj temprorary_variable.obj unnamed_enums.obj user_text.obj abstract.scons call_policies.scons casting.scons class_order2.scons class_order3.scons class_order4.scons class_order.scons classes.scons enums.scons factory.scons finalizables.scons free_function_ignore_bug.scons free_functions.scons free_operators.scons global_variables.scons index_operator.scons internal_classes.scons member_functions.scons member_variables.scons module_body.scons namespaces.scons noncopyable.scons operators.scons operators_bug.scons optional.scons optional_bug.scons pointer_as_arg.scons pointer_to_function_as_argument.scons private_assign.scons recursive.scons regression1.scons regression2.scons regression3.scons smart_pointers.scons special_operators.scons statics.scons temprorary_variable.scons unnamed_enums.scons user_text.scons abstract.dll call_policies.dll casting.dll class_order2.dll class_order3.dll class_order4.dll class_order.dll classes.dll enums.dll factory.dll finalizables.dll free_function_ignore_bug.dll free_functions.dll free_operators.dll global_variables.dll index_operator.dll .sconsign.dblite __array_1.pypp.hpp classes.cpp enums.cpp free_functions.cpp module_body.cpp namespaces.cpp unnamed_enums.cpp + internal_classes.dll member_functions.dll member_variables.dll module_body.dll namespaces.dll noncopyable.dll operators.dll operators_bug.dll optional.dll optional_bug.dll pointer_as_arg.dll pointer_to_function_as_argument.dll private_assign.dll recursive.dll regression1.dll regression2.dll regression3.dll smart_pointers.dll special_operators.dll statics.dll temprorary_variable.dll unnamed_enums.dll user_text.dll abstract.cpp~ call_policies.cpp~ casting.cpp~ class_order2.cpp~ class_order3.cpp~ class_order4.cpp~ class_order.cpp~ classes.cpp~ enums.cpp~ factory.cpp~ finalizables.cpp~ free_functions.cpp~ free_operators.cpp~ global_variables.cpp~ index_operator.cpp~ internal_classes.cpp~ member_functions.cpp~ member_variables.cpp~ noncopyable.cpp~ operators_bug.cpp~ optional.cpp~ optional_bug.cpp~ pointer_as_arg.cpp~ pointer_to_function_as_argument.cpp~ private_assign.cpp~ recursive.cpp~ regression1.cpp~ regression2.cpp~ regression3.cpp~ smart_pointers.cpp~ special_operators.cpp~ statics.cpp~ temprorary_variable.cpp~ unnamed_enums.cpp~ user_text.cpp~ abstract.exp call_policies.exp casting.exp class_order2.exp class_order3.exp class_order4.exp class_order.exp classes.exp enums.exp factory.exp finalizables.exp free_function_ignore_bug.exp free_functions.exp free_operators.exp global_variables.exp index_operator.exp internal_classes.exp member_functions.exp member_variables.exp module_body.exp namespaces.exp noncopyable.exp operators.exp operators_bug.exp optional.exp optional_bug.exp pointer_as_arg.exp pointer_to_function_as_argument.exp private_assign.exp recursive.exp regression1.exp regression2.exp regression3.exp smart_pointers.exp special_operators.exp statics.exp temprorary_variable.exp unnamed_enums.exp user_text.exp abstract.lib call_policies.lib casting.lib class_order2.lib class_order3.lib class_order4.lib class_order.lib classes.lib enums.lib factory.lib finalizables.lib free_function_ignore_bug.lib free_functions.lib free_operators.lib global_variables.lib index_operator.lib internal_classes.lib member_functions.lib member_variables.lib module_body.lib namespaces.lib noncopyable.lib operators.lib operators_bug.lib optional.lib optional_bug.lib pointer_as_arg.lib pointer_to_function_as_argument.lib private_assign.lib recursive.lib regression1.lib regression2.lib regression3.lib smart_pointers.lib special_operators.lib statics.lib temprorary_variable.lib unnamed_enums.lib user_text.lib abstract.obj call_policies.obj casting.obj class_order2.obj class_order3.obj class_order4.obj class_order.obj classes.obj enums.obj factory.obj finalizables.obj free_function_ignore_bug.obj free_functions.obj free_operators.obj global_variables.obj index_operator.obj internal_classes.obj member_functions.obj member_variables.obj module_body.obj namespaces.obj noncopyable.obj operators.obj operators_bug.obj optional.obj optional_bug.obj pointer_as_arg.obj pointer_to_function_as_argument.obj private_assign.obj recursive.obj regression1.obj regression2.obj regression3.obj smart_pointers.obj special_operators.obj statics.obj temprorary_variable.obj unnamed_enums.obj user_text.obj abstract.scons call_policies.scons casting.scons class_order2.scons class_order3.scons class_order4.scons class_order.scons classes.scons enums.scons factory.scons finalizables.scons free_function_ignore_bug.scons free_functions.scons free_operators.scons global_variables.scons index_operator.scons internal_classes.scons member_functions.scons member_variables.scons module_body.scons namespaces.scons noncopyable.scons operators.scons operators_bug.scons optional.scons optional_bug.scons pointer_as_arg.scons pointer_to_function_as_argument.scons private_assign.scons recursive.scons regression1.scons regression2.scons regression3.scons smart_pointers.scons special_operators.scons statics.scons temprorary_variable.scons unnamed_enums.scons user_text.scons abstract.dll call_policies.dll casting.dll class_order2.dll class_order3.dll class_order4.dll class_order.dll classes.dll enums.dll factory.dll finalizables.dll free_function_ignore_bug.dll free_functions.dll free_operators.dll global_variables.dll index_operator.dll .sconsign.dblite __array_1.pypp.hpp classes.cpp enums.cpp free_functions.cpp module_body.cpp namespaces.cpp unnamed_enums.cpp abstract.cpp call_policies.cpp casting.cpp class_order.cpp class_order2.cpp class_order3.cpp class_order4.cpp factory.cpp finalizables.cpp free_function_ignore_bug.cpp free_operators.cpp global_variables.cpp index_operator.cpp internal_classes.cpp member_functions.cpp member_variables.cpp noncopyable.cpp operators.cpp operators_bug.cpp optional.cpp optional_bug.cpp pointer_as_arg.cpp pointer_to_function_as_argument.cpp private_assign.cpp protected.cpp recursive.cpp regression1.cpp regression2.cpp regression3.cpp smart_pointers.cpp special_operators.cpp statics.cpp temprorary_variable.cpp user_text.cpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:34:51
|
Revision: 55 Author: roman_yakovenko Date: 2006-05-01 22:34:40 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=55&view=rev Log Message: ----------- place holder Added Paths: ----------- pyplusplus_dev/docs/apidocs/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:31:20
|
Revision: 54 Author: roman_yakovenko Date: 2006-05-01 22:31:09 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=54&view=rev Log Message: ----------- Removed Paths: ------------- release_manager/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:25:29
|
Revision: 53 Author: roman_yakovenko Date: 2006-05-01 22:25:23 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=53&view=rev Log Message: ----------- updating writer to use free_function_t code creator, instead of "function_t" one Modified Paths: -------------- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-05-02 05:24:01 UTC (rev 52) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-05-02 05:25:23 UTC (rev 53) @@ -227,8 +227,8 @@ def split_free_functions( self ): """Write all free functions into a separate .h/.cpp file. """ - creators = filter( lambda x: isinstance(x, code_creators.function_t ) - , self.extmodule.body.creators ) + creators = filter( lambda x: isinstance(x, code_creators.free_function_t ) + , self.extmodule.body.creators ) self.split_creators( creators, '_free_functions', 'register_free_functions', -1 ) #TODO: move write_main to __init__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:24:15
|
Revision: 52 Author: roman_yakovenko Date: 2006-05-01 22:24:01 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=52&view=rev Log Message: ----------- updating "creator_t" class to use functionality provided by decl_wrapper classes Modified Paths: -------------- pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-05-02 05:22:43 UTC (rev 51) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-05-02 05:24:01 UTC (rev 52) @@ -10,6 +10,9 @@ import types_database from pyplusplus import code_repository from sets import Set as set + +ACCESS_TYPES = declarations.ACCESS_TYPES +VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES #TODO: don't export functions that returns non const pointer to fundamental types #TODO: add print decl_wrapper.readme messages @@ -82,8 +85,8 @@ decls = declarations.make_flatten( decls ) self.__decls = self._filter_decls( self._reorder_decls( self._prepare_decls( decls ) ) ) - self.__curr_parent = self.__module_body - self.__curr_decl = None + self.curr_code_creator = self.__module_body + self.curr_decl = None self.__cr_array_1_included = False self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] @@ -122,69 +125,24 @@ new_ordered.extend( others ) new_ordered.extend( variables ) return new_ordered # - - def _is_calldef_exposable(self, declaration): - #see http://www.boost.org/libs/python/doc/v2/faq.html#funcptr - if len( declaration.arguments ) > 10: - return False #boost.tuple can not contain more than 10 args - all_types = [ arg.type for arg in declaration.arguments ] - all_types.append( declaration.return_type ) - for some_type in all_types: - units = declarations.decompose_type( some_type ) - ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) - , units ) - if ptr2functions: - return False - #Function that take as agrument some instance of non public class - #will not be exported. Same to the return variable - if isinstance( units[-1], declarations.declarated_t ): - dtype = units[-1] - if isinstance( dtype.declaration.parent, declarations.class_t ): - if dtype.declaration not in dtype.declaration.parent.public_members: - return False - - if isinstance( declaration, declarations.operator_t ): - if isinstance( declaration, declarations.casting_operator_t ): - return True - if isinstance( declaration, declarations.member_operator_t ) \ - and declaration.symbol in ( '()', '[]' ): - return True - if not code_creators.operator_t.supported.is_supported( declaration ): - #see http://www.boost.org/libs/python/doc/v2/operators.html#introduction - return False - if isinstance( declaration, declarations.constructor_t ) \ - and declaration.is_artificial: - return False - return True def _exportable_class_members( self, class_decl ): assert isinstance( class_decl, declarations.class_t ) - members = [] - for member in class_decl.public_members: - if isinstance( member, declarations.variable_t ) : - if member.bits == 0 and member.name == "": - continue #alignement bit - type_ = declarations.remove_const( member.type ) - if declarations.is_pointer( type_ ) \ - and member.type_qualifiers.has_static: - continue #right now I don't know what code should be generated in this case - members.append( member ) + members = filter( lambda mv: mv.ignore == False, class_decl.public_members ) #protected and private virtual functions that not overridable and not pure #virtual should not be exported for member in class_decl.protected_members: if not isinstance( member, declarations.calldef_t ): continue - if member.virtuality != declarations.VIRTUALITY_TYPES.VIRTUAL: + else: members.append( member ) - if self._is_overridable( member ): - members.append( member ) - + vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \ - and member.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL + and member.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL members.extend( filter( vfunction_selector, class_decl.private_members ) ) #now lets filter out none public operators: pyplusplus does not support them right now members = filter( lambda decl: not isinstance( decl, declarations.member_operator_t ) - or decl.access_type == declarations.ACCESS_TYPES.PUBLIC + or decl.access_type == ACCESS_TYPES.PUBLIC , members ) #-#if declarations.has_destructor( class_decl ) \ #-# and not declarations.has_public_destructor( class_decl ): @@ -199,11 +157,6 @@ def _does_class_have_smth_to_export(self, exportable_members ): return bool( self._filter_decls( self._reorder_decls( exportable_members ) ) ) - def _is_public_class( self, class_decl ): - if isinstance( class_decl.parent, declarations.namespace_t ): - return True - return class_decl in class_decl.parent.public_members - def _is_constructor_of_abstract_class( self, decl ): assert isinstance( decl, declarations.constructor_t ) return decl.parent.is_abstract @@ -214,26 +167,63 @@ decls = filter( lambda x: not (x.is_artificial and not (isinstance(x, ( declarations.class_t, declarations.enumeration_t)))) , decls ) - # Filter out internal compiler methods - decls = filter( lambda x: not x.name.startswith( '__' ), decls ) - decls = filter( lambda x: x.location.file_name != "<internal>", decls ) # Filter out type defs decls = filter( lambda x: not isinstance( x, declarations.typedef_t ), decls ) - # Filter out non-exposable calls - decls = filter( lambda x: not isinstance( x, declarations.calldef_t) - or self._is_calldef_exposable(x) - , decls ) - decls = filter( lambda x: not isinstance( x, declarations.class_t) - or self._is_public_class( x ) - , decls ) + return decls - def _is_wrapper_needed(self, exportable_members): - if isinstance( self.__curr_decl, declarations.class_t ) \ - and self.__curr_decl.wrapper_user_code: + def __is_same_func( self, f1, f2 ): + if not f1.__class__ is f2.__class__: + return False + if isinstance( f1, declarations.member_calldef_t ) and f1.has_const != f2.has_const: + return False + if f1.name != f2.name: + return False + if f1.return_type != f2.return_type: + return False + if len( f1.arguments ) != len(f2.arguments): + return False + for f1_arg, f2_arg in zip( f1.arguments, f2.arguments ): + if f1_arg.type != f2_arg.type: + return False + return True + + def redefined_funcs( self, cls ): + all_included = declarations.custom_matcher_t( lambda decl: decl.ignore == False ) + all_protected = declarations.access_type_matcher_t( 'protected' ) & all_included + all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) + + query = all_protected | all_pure_virtual + + funcs = set() + for base in cls.recursive_bases: + if base.access == ACCESS_TYPES.PRIVATE: + continue + base_cls = base.related_class + funcs.update( base_cls.member_functions( query, allow_empty=True ) ) + funcs.update( base_cls.member_operators( query, allow_empty=True ) ) + + not_reimplemented_funcs = set() + for f in funcs: + cls_fs = cls.calldefs( name=f.name, recursive=False, allow_empty=True ) + for cls_f in cls_fs: + if self.__is_same_func( f, cls_f ): + break + else: + #should test whether this function has been added or not + for f_impl in not_reimplemented_funcs: + if self.__is_same_func( f, f_impl ): + break + else: + not_reimplemented_funcs.add( f ) + return not_reimplemented_funcs + + def _is_wrapper_needed(self, class_inst, exportable_members): + if isinstance( self.curr_decl, declarations.class_t ) \ + and self.curr_decl.wrapper_user_code: return True - elif isinstance( self.__curr_parent, declarations.class_t ) \ - and self.__curr_parent.wrapper_user_code: + elif isinstance( self.curr_code_creator, declarations.class_t ) \ + and self.curr_code_creator.wrapper_user_code: return True else: pass @@ -250,12 +240,12 @@ return True if isinstance( member, declarations.class_t ): return True - if isinstance( member, declarations.member_calldef_t ): - if member.access_type != declarations.ACCESS_TYPES.PUBLIC: - return True - if self._is_overridable( member ): - return True - return False + if isinstance( member, declarations.calldef_t ): + if member.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: + return True #virtual and pure virtual functions requieres wrappers. + if member.access_type in ( ACCESS_TYPES.PROTECTED, ACCESS_TYPES.PRIVATE ): + return True #we already decided that those functions should be exposed, so I need wrapper for them + return bool( self.redefined_funcs(class_inst) ) def _adopt_free_operator( self, operator ): def adopt_operator_impl( operator, found_creators ): @@ -350,7 +340,7 @@ self.__extmodule.adopt_include(code_creators.include_t(header=h)) # Invoke the appropriate visit_*() method on all decls for decl in self.__decls: - self.__curr_decl = decl + self.curr_decl = decl declarations.apply_visitor( self, decl ) for operator in self.__free_operators: self._adopt_free_operator( operator ) @@ -366,175 +356,205 @@ include = code_creators.include_t( header=fn ) self.__extmodule.adopt_include(include) - def _is_overridable( self, decl ): - #virtual functions that returns const reference to something - #could not be overriden by Python. The reason is simple: - #in boost::python::override::operator(...) result of marshaling - #(Python 2 C++) is saved on stack, after functions returns the result - #will be reference to no where - access violetion. - #For example see temporal variable tester - assert isinstance( decl, declarations.member_calldef_t ) - if decl.virtuality == declarations.VIRTUALITY_TYPES.VIRTUAL \ - and decl.access_type == declarations.ACCESS_TYPES.PROTECTED \ - and declarations.is_reference( decl.return_type ): - return True - if decl.virtuality == declarations.VIRTUALITY_TYPES.VIRTUAL \ - and declarations.is_reference( decl.return_type ): - return False - if decl.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL: - return True - if decl.access_type != declarations.ACCESS_TYPES.PUBLIC: - return True - if declarations.is_reference( decl.return_type ): - return False - return decl.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL \ - or decl in decl.parent.protected_members - + + def guess_functions_code_creators( self ): + maker_cls = None + fwrapper_cls = None + access_level = self.curr_decl.parent.find_out_member_access_type( self.curr_decl ) + if access_level == ACCESS_TYPES.PUBLIC: + if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + maker_cls = code_creators.mem_fun_t + elif self.curr_decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = code_creators.mem_fun_pv_wrapper_t + maker_cls = code_creators.mem_fun_pv_t + else: + if self.curr_decl.overridable: + fwrapper_cls = code_creators.mem_fun_v_wrapper_t + maker_cls = code_creators.mem_fun_v_t + elif access_level == ACCESS_TYPES.PROTECTED: + if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + if self.curr_decl.has_static: + fwrapper_cls = code_creators.mem_fun_protected_s_wrapper_t + maker_cls = code_creators.mem_fun_protected_s_t + else: + fwrapper_cls = code_creators.mem_fun_protected_wrapper_t + maker_cls = code_creators.mem_fun_protected_t + elif self.curr_decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: + if self.curr_decl.overridable: + fwrapper_cls = code_creators.mem_fun_protected_v_wrapper_t + maker_cls = code_creators.mem_fun_protected_v_t + else: + fwrapper_cls = code_creators.mem_fun_protected_pv_wrapper_t + maker_cls = code_creators.mem_fun_protected_pv_t + else: #private + if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + pass#in general we should not come here + elif self.curr_decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = code_creators.mem_fun_private_pv_wrapper_t + else: + if self.curr_decl.overridable: + fwrapper_cls = code_creators.mem_fun_v_wrapper_t + maker_cls = code_creators.mem_fun_v_t + return ( maker_cls, fwrapper_cls ) + def visit_member_function( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - if self.__curr_decl.name == 'invert_sign': - i = 0 fwrapper = None - self.__types_db.update( self.__curr_decl ) - access_level = self.__curr_decl.parent.find_out_member_access_type( self.__curr_decl ) - if self._is_overridable( self.__curr_decl ) or access_level == declarations.ACCESS_TYPES.PROTECTED: - class_wrapper = self.__curr_parent.wrapper - fwrapper = code_creators.function_wrapper_t( function=self.__curr_decl ) + self.__types_db.update( self.curr_decl ) + if None is self.curr_decl.call_policies: + self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + + maker_cls, fwrapper_cls = self.guess_functions_code_creators() + + maker = None + fwrapper = None + if fwrapper_cls: + fwrapper = fwrapper_cls( function=self.curr_decl ) + class_wrapper = self.curr_code_creator.wrapper class_wrapper.adopt_creator( fwrapper ) - if access_level == declarations.ACCESS_TYPES.PRIVATE: - return - maker = code_creators.function_t( function=self.__curr_decl, wrapper=fwrapper ) - if None is maker.call_policies: - maker.call_policies = self.__call_policies_resolver( self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) - if self.__curr_decl.has_static: + + if maker_cls: + if fwrapper: + maker = maker_cls( function=self.curr_decl, wrapper=fwrapper ) + else: + maker = maker_cls( function=self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) + + if self.curr_decl.has_static: #static_method should be created only once. found = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) - and creator.declaration.name == self.__curr_decl.name - , self.__curr_parent.creators ) + and creator.declaration.name == self.curr_decl.name + , self.curr_code_creator.creators ) if not found: - static_method = code_creators.static_method_t( function=self.__curr_decl + static_method = code_creators.static_method_t( function=self.curr_decl , function_code_creator=maker ) - self.__curr_parent.adopt_creator( static_method ) + self.curr_code_creator.adopt_creator( static_method ) def visit_constructor( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - if self.__curr_decl.is_copy_constructor: + if self.curr_decl.is_copy_constructor: return - self.__types_db.update( self.__curr_decl ) - if not self._is_constructor_of_abstract_class( self.__curr_decl ) \ - and 1 == len( self.__curr_decl.arguments ) \ + self.__types_db.update( self.curr_decl ) + if not self._is_constructor_of_abstract_class( self.curr_decl ) \ + and 1 == len( self.curr_decl.arguments ) \ and self.__create_castinig_constructor \ - and self.__curr_decl.access_type == declarations.ACCESS_TYPES.PUBLIC: - maker = code_creators.casting_constructor_t( constructor=self.__curr_decl ) + and self.curr_decl.access_type == ACCESS_TYPES.PUBLIC: + maker = code_creators.casting_constructor_t( constructor=self.curr_decl ) self.__module_body.adopt_creator( maker ) cwrapper = None - exportable_members = self._exportable_class_members(self.__curr_parent.declaration) - if self._is_wrapper_needed( exportable_members ): - class_wrapper = self.__curr_parent.wrapper - cwrapper = code_creators.constructor_wrapper_t( constructor=self.__curr_decl ) + exportable_members = self._exportable_class_members(self.curr_code_creator.declaration) + if self._is_wrapper_needed( self.curr_decl.parent, exportable_members ): + class_wrapper = self.curr_code_creator.wrapper + cwrapper = code_creators.constructor_wrapper_t( constructor=self.curr_decl ) class_wrapper.adopt_creator( cwrapper ) - maker = code_creators.constructor_t( constructor=self.__curr_decl, wrapper=cwrapper ) + maker = code_creators.constructor_t( constructor=self.curr_decl, wrapper=cwrapper ) if None is maker.call_policies: - maker.call_policies = self.__call_policies_resolver( self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) + maker.call_policies = self.__call_policies_resolver( self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) def visit_destructor( self ): pass def visit_member_operator( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - if self.__curr_decl.symbol in ( '()', '[]' ): + if self.curr_decl.symbol in ( '()', '[]' ): self.visit_member_function() else: - self.__types_db.update( self.__curr_decl ) - maker = code_creators.operator_t( operator=self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) + self.__types_db.update( self.curr_decl ) + maker = code_creators.operator_t( operator=self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) def visit_casting_operator( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - if not declarations.is_fundamental( self.__curr_decl.return_type ) \ - and not self.__curr_decl.has_const: + if not declarations.is_fundamental( self.curr_decl.return_type ) \ + and not self.curr_decl.has_const: return #only const casting operators can generate implicitly_convertible - - self.__types_db.update( self.__curr_decl ) - if not self.__curr_decl.parent.is_abstract \ - and not declarations.is_reference( self.__curr_decl.return_type ): - maker = code_creators.casting_operator_t( operator=self.__curr_decl ) + + if None is self.curr_decl.call_policies: + self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + + self.__types_db.update( self.curr_decl ) + if not self.curr_decl.parent.is_abstract \ + and not declarations.is_reference( self.curr_decl.return_type ): + maker = code_creators.casting_operator_t( operator=self.curr_decl ) self.__module_body.adopt_creator( maker ) #what to do if class is abstract - if self.__curr_decl.access_type == declarations.ACCESS_TYPES.PUBLIC: - maker = code_creators.casting_member_operator_t( operator=self.__curr_decl ) - if None is maker.call_policies: - maker.call_policies = self.__call_policies_resolver( self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) + if self.curr_decl.access_type == ACCESS_TYPES.PUBLIC: + maker = code_creators.casting_member_operator_t( operator=self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) def visit_free_function( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - self.__types_db.update( self.__curr_decl ) - maker = code_creators.function_t( function=self.__curr_decl ) - if None is maker.call_policies: - maker.call_policies = self.__call_policies_resolver( self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) + self.__types_db.update( self.curr_decl ) + maker = code_creators.free_function_t( function=self.curr_decl ) + if None is self.curr_decl.call_policies: + self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) def visit_free_operator( self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - self.__types_db.update( self.__curr_decl ) - self.__free_operators.append( self.__curr_decl ) + self.__types_db.update( self.curr_decl ) + self.__free_operators.append( self.curr_decl ) def visit_class_declaration(self ): pass def visit_class(self ): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - assert isinstance( self.__curr_decl, declarations.class_t ) - temp_curr_decl = self.__curr_decl - temp_curr_parent = self.__curr_parent - exportable_members = self._exportable_class_members(self.__curr_decl) + assert isinstance( self.curr_decl, declarations.class_t ) + temp_curr_decl = self.curr_decl + temp_curr_parent = self.curr_code_creator + exportable_members = self._exportable_class_members(self.curr_decl) wrapper = None - class_inst = code_creators.class_t( class_inst=self.__curr_decl ) + class_inst = code_creators.class_t( class_inst=self.curr_decl ) - if self._is_wrapper_needed( exportable_members ): - wrapper = code_creators.class_wrapper_t( declaration=self.__curr_decl + if self._is_wrapper_needed( self.curr_decl, exportable_members ): + wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl , class_creator=class_inst ) class_inst.wrapper = wrapper #insert wrapper before module body - if isinstance( self.__curr_decl.parent, declarations.class_t ): + if isinstance( self.curr_decl.parent, declarations.class_t ): #we deal with internal class - self.__curr_parent.wrapper.adopt_creator( wrapper ) + self.curr_code_creator.wrapper.adopt_creator( wrapper ) else: self.__extmodule.adopt_creator( wrapper, self.__extmodule.creators.index( self.__module_body ) ) - if declarations.has_trivial_copy( self.__curr_decl ): + if declarations.has_trivial_copy( self.curr_decl ): #I don't know but sometimes boost.python requieres #to construct wrapper from wrapped classe - if not declarations.is_noncopyable( self.__curr_decl ): - scons = code_creators.special_constructor_wrapper_t( class_inst=self.__curr_decl ) + if not declarations.is_noncopyable( self.curr_decl ): + scons = code_creators.special_constructor_wrapper_t( class_inst=self.curr_decl ) wrapper.adopt_creator( scons ) - trivial_constr = declarations.find_trivial_constructor(self.__curr_decl) + trivial_constr = declarations.find_trivial_constructor(self.curr_decl) if trivial_constr and trivial_constr.is_artificial: #this constructor is not going to be exposed - tcons = code_creators.trivial_constructor_wrapper_t( class_inst=self.__curr_decl ) + tcons = code_creators.trivial_constructor_wrapper_t( class_inst=self.curr_decl ) wrapper.adopt_creator( tcons ) - self.__curr_parent.adopt_creator( class_inst ) - self.__curr_parent = class_inst + self.curr_code_creator.adopt_creator( class_inst ) + self.curr_code_creator = class_inst for decl in self._filter_decls( self._reorder_decls( exportable_members ) ): - self.__curr_decl = decl + self.curr_decl = decl declarations.apply_visitor( self, decl ) + for redefined_func in self.redefined_funcs( temp_curr_decl ): + if isinstance( redefined_func, declarations.operator_t ): + continue + self.curr_decl = redefined_func + declarations.apply_visitor( self, redefined_func ) + #all static_methods_t should be moved to the end #better approach is to move them after last def of relevant function static_methods = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) @@ -542,21 +562,21 @@ for static_method in static_methods: class_inst.remove_creator( static_method ) class_inst.adopt_creator( static_method ) - - self.__curr_decl = temp_curr_decl - self.__curr_parent = temp_curr_parent + self.curr_decl = temp_curr_decl + self.curr_code_creator = temp_curr_parent + def visit_enumeration(self): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - assert isinstance( self.__curr_decl, declarations.enumeration_t ) + assert isinstance( self.curr_decl, declarations.enumeration_t ) maker = None - if self.__curr_decl.name: - maker = code_creators.enum_t( enum=self.__curr_decl ) + if self.curr_decl.name: + maker = code_creators.enum_t( enum=self.curr_decl ) else: - maker = code_creators.unnamed_enum_t( unnamed_enum=self.__curr_decl ) - self.__curr_parent.adopt_creator( maker ) + maker = code_creators.unnamed_enum_t( unnamed_enum=self.curr_decl ) + self.curr_code_creator.adopt_creator( maker ) def visit_namespace(self): pass @@ -573,45 +593,45 @@ return True def visit_variable(self): - if self.__curr_decl.ignore: + if self.curr_decl.ignore: return - self.__types_db.update( self.__curr_decl ) + self.__types_db.update( self.curr_decl ) - if declarations.is_array( self.__curr_decl.type ): + if declarations.is_array( self.curr_decl.type ): if not self.__cr_array_1_included: self.__extmodule.adopt_creator( code_creators.include_t( code_repository.array_1.file_name ) , self.__extmodule.first_include_index() + 1) self.__cr_array_1_included = True - if self._register_array_1( self.__curr_decl.type ): - array_1_registrator = code_creators.array_1_registrator_t( array_type=self.__curr_decl.type ) - self.__curr_parent.adopt_creator( array_1_registrator ) + if self._register_array_1( self.curr_decl.type ): + array_1_registrator = code_creators.array_1_registrator_t( array_type=self.curr_decl.type ) + self.curr_code_creator.adopt_creator( array_1_registrator ) - if isinstance( self.__curr_decl.parent, declarations.namespace_t ): + if isinstance( self.curr_decl.parent, declarations.namespace_t ): maker = None wrapper = None - if declarations.is_array( self.__curr_decl.type ): - wrapper = code_creators.array_gv_wrapper_t( variable=self.__curr_decl ) - maker = code_creators.array_gv_t( variable=self.__curr_decl, wrapper=wrapper ) + if declarations.is_array( self.curr_decl.type ): + wrapper = code_creators.array_gv_wrapper_t( variable=self.curr_decl ) + maker = code_creators.array_gv_t( variable=self.curr_decl, wrapper=wrapper ) else: - maker = code_creators.global_variable_t( variable=self.__curr_decl ) + maker = code_creators.global_variable_t( variable=self.curr_decl ) if wrapper: self.__extmodule.adopt_creator( wrapper , self.__extmodule.creators.index( self.__module_body ) ) else: maker = None wrapper = None - if self.__curr_decl.bits != None: - wrapper = code_creators.bit_field_wrapper_t( variable=self.__curr_decl ) - maker = code_creators.bit_field_t( variable=self.__curr_decl, wrapper=wrapper ) - elif declarations.is_array( self.__curr_decl.type ): - wrapper = code_creators.array_mv_wrapper_t( variable=self.__curr_decl ) - maker = code_creators.array_mv_t( variable=self.__curr_decl, wrapper=wrapper ) - elif declarations.is_pointer( self.__curr_decl.type ): - wrapper = code_creators.member_variable_wrapper_t( variable=self.__curr_decl ) - maker = code_creators.member_variable_t( variable=self.__curr_decl, wrapper=wrapper ) + if self.curr_decl.bits != None: + wrapper = code_creators.bit_field_wrapper_t( variable=self.curr_decl ) + maker = code_creators.bit_field_t( variable=self.curr_decl, wrapper=wrapper ) + elif declarations.is_array( self.curr_decl.type ): + wrapper = code_creators.array_mv_wrapper_t( variable=self.curr_decl ) + maker = code_creators.array_mv_t( variable=self.curr_decl, wrapper=wrapper ) + elif declarations.is_pointer( self.curr_decl.type ): + wrapper = code_creators.member_variable_wrapper_t( variable=self.curr_decl ) + maker = code_creators.member_variable_t( variable=self.curr_decl, wrapper=wrapper ) else: - maker = code_creators.member_variable_t( variable=self.__curr_decl ) + maker = code_creators.member_variable_t( variable=self.curr_decl ) if wrapper: - self.__curr_parent.wrapper.adopt_creator( wrapper ) - self.__curr_parent.adopt_creator( maker ) + self.curr_code_creator.wrapper.adopt_creator( wrapper ) + self.curr_code_creator.adopt_creator( maker ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:22:51
|
Revision: 51 Author: roman_yakovenko Date: 2006-05-01 22:22:43 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=51&view=rev Log Message: ----------- removing references to "function_t" and "function_wrapper_t" code creators adding references to new code creators Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-05-02 05:21:40 UTC (rev 50) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-05-02 05:22:43 UTC (rev 51) @@ -41,11 +41,29 @@ from enum import enum_t +from calldef import free_function_t +from calldef import mem_fun_t + +from calldef import mem_fun_pv_t +from calldef import mem_fun_pv_wrapper_t +from calldef import mem_fun_v_t +from calldef import mem_fun_v_wrapper_t + +from calldef import mem_fun_protected_t +from calldef import mem_fun_protected_wrapper_t +from calldef import mem_fun_protected_s_t +from calldef import mem_fun_protected_s_wrapper_t +from calldef import mem_fun_protected_v_t +from calldef import mem_fun_protected_v_wrapper_t +from calldef import mem_fun_protected_pv_t +from calldef import mem_fun_protected_pv_wrapper_t + +from calldef import mem_fun_private_v_wrapper_t +from calldef import mem_fun_private_pv_wrapper_t + from calldef import operator_t -from calldef import function_t from calldef import constructor_t from calldef import static_method_t -from calldef import function_wrapper_t from calldef import casting_operator_t from calldef import casting_constructor_t from calldef import constructor_wrapper_t This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:21:50
|
Revision: 50 Author: roman_yakovenko Date: 2006-05-01 22:21:40 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=50&view=rev Log Message: ----------- removing function_t and function_wrapper_t classes instead of this new code creators have been created Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-05-02 05:20:07 UTC (rev 49) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-05-02 05:21:40 UTC (rev 50) @@ -9,226 +9,403 @@ import class_declaration from pygccxml import declarations -class function_t( declaration_based.declaration_based_t): - """ - Creates boost.python code needed to expose free/member function. - """ - _PARAM_SEPARATOR = ', ' +#virtual functions that returns const reference to something +#could not be overriden by Python. The reason is simple: +#in boost::python::override::operator(...) result of marshaling +#(Python 2 C++) is saved on stack, after functions returns the result +#will be reference to no where - access violetion. +#For example see temporal variable tester + + +#TODO: +#Add to docs: +#public memebr functions - call, override, call base implementation +#protected member functions - call, override +#private - override + +class calldef_t( declaration_based.declaration_based_t): def __init__(self, function, wrapper=None, parent=None ): declaration_based.declaration_based_t.__init__( self , declaration=function , parent=parent ) - self._wrapper = wrapper - - def _get_call_policies(self): - return self.declaration.call_policies - def _set_call_policies(self, call_policies): - self.declaration.call_policies = call_policies - call_policies = property( _get_call_policies, _set_call_policies ) - - def _get_use_keywords(self): - return self.declaration.use_keywords - def _set_use_keywords(self, use_keywords): - self.declaration.use_keywords = use_keywords - use_keywords = property( _get_use_keywords, _set_use_keywords ) - - def _get_create_with_signature(self): - return self.declaration.create_with_signature - def _set_create_with_signature(self, create_with_signature): - self.declaration.create_with_signature = create_with_signature - create_with_signature = property( _get_create_with_signature, _set_create_with_signature) - - def _get_use_default_arguments(self): - return self.declaration.use_default_arguments - def _set_use_default_arguments(self, use_default_arguments): - self.declaration.use_default_arguments = use_default_arguments - use_default_arguments = property( _get_use_default_arguments, _set_use_default_arguments ) - + self._wrapper = wrapper + def _get_wrapper( self ): return self._wrapper def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - def _keywords_args(self): + def def_identifier( self ): + return algorithm.create_identifier( self, '::boost::python::def' ) + + def pure_virtual_identifier( self ): + return algorithm.create_identifier( self, '::boost::python::pure_virtual' ) + + def param_sep(self): + return os.linesep + self.indent( self.PARAM_SEPARATOR, 2 ) + + def keywords_args(self): boost_arg = algorithm.create_identifier( self, '::boost::python::arg' ) boost_obj = algorithm.create_identifier( self, '::boost::python::object' ) result = ['( '] for arg in self.declaration.arguments: if 1 < len( result ): - result.append( self._PARAM_SEPARATOR ) + result.append( self.PARAM_SEPARATOR ) result.append( boost_arg ) result.append( '("%s")' % arg.name ) - if self.use_default_arguments and arg.default_value: + if self.declaration.use_default_arguments and arg.default_value: if not declarations.is_pointer( arg.type ) or arg.default_value != '0': result.append( '=%s' % arg.default_value ) else: result.append( '=%s()' % boost_obj ) result.append( ' )' ) return ''.join( result ) + +class calldef_wrapper_t( declaration_based.declaration_based_t): + def __init__(self, function, parent=None ): + declaration_based.declaration_based_t.__init__( self + , declaration=function + , parent=parent ) - def is_class_function(self): - return isinstance( self.parent, class_declaration.class_t ) + def argument_name( self, index ): + arg = self.declaration.arguments[ index ] + if arg.name: + return arg.name + else: + return 'p%d' % index + + def args_declaration( self ): + args = [] + for index, arg in enumerate( self.declaration.arguments ): + args.append( arg.type.decl_string + ' ' + self.argument_name(index) ) + if len( args ) == 1: + return args[ 0 ] + return ', '.join( args ) - def _generate_functions_ref( self ): - result = [] + def override_identifier(self): + return algorithm.create_identifier( self, '::boost::python::override' ) - virtuality = None - access_type = None - if isinstance( self.declaration, declarations.member_calldef_t ): - virtuality = self.declaration.virtuality - access_type = self.declaration.parent.find_out_member_access_type( self.declaration ) - create_with_signature = bool( self.declaration.overloads ) or self.create_with_signature + def function_call_args( self ): + params = [] + for index in range( len( self.declaration.arguments ) ): + arg_type = declarations.remove_alias( self.declaration.arguments[index].type ) + arg_base_type = declarations.base_type( arg_type ) + if declarations.is_fundamental( arg_base_type ): + params.append( self.argument_name( index ) ) + elif declarations.is_reference( arg_type ) \ + and not declarations.is_const( arg_type ) \ + and not declarations.is_enum( arg_base_type ): + params.append( 'boost::ref(%s)' % self.argument_name( index ) ) + elif declarations.is_pointer( arg_type ) \ + and not declarations.is_fundamental( arg_type.base ) \ + and not declarations.is_enum( arg_base_type ): + params.append( 'boost::python::ptr(%s)' % self.argument_name( index ) ) + else: + params.append( self.argument_name( index ) ) + return ', '.join( params ) + + def wrapped_class_identifier( self ): + return algorithm.create_identifier( self, self.declaration.parent.decl_string ) + + def unoverriden_function_body( self ): + msg = r'This function could not be overriden in Python!' + msg = msg + 'Reason: function returns reference to local variable!' + return 'throw std::logic_error("%s");' % msg + + +class free_function_t( calldef_t ): + def __init__( self, function, parent=None ): + calldef_t.__init__( self, function=function, parent=parent ) + + def _create_impl(self): + param_sep = self.param_sep() - fdname = algorithm.create_identifier( self - , declarations.full_name( self.declaration ) ) + result = [ self.def_identifier() ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)( &%s )' + %( self.declaration.function_type().decl_string + , declarations.full_name( self.declaration ) ) ) + else: + result.append( '&%s' % declarations.full_name( self.declaration ) ) - if virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL: - pure_virtual = algorithm.create_identifier( self - , '::boost::python::pure_virtual' ) - if create_with_signature: - if self.wrapper and access_type != declarations.ACCESS_TYPES.PUBLIC: - result.append( '%s( (%s)(&%s) )' - % ( pure_virtual - , self.wrapper.function_type() - , self.wrapper.full_name() ) ) - else: - result.append( '%s( (%s)(&%s) )' - % ( pure_virtual - , self.declaration.function_type().decl_string - , declarations.full_name( self.declaration ) ) ) - else: - if self.wrapper and access_type != declarations.ACCESS_TYPES.PUBLIC: - result.append( '%s( &%s )' - % ( pure_virtual, self.wrapper.full_name() ) ) - else: - result.append( '%s( &%s )' - % ( pure_virtual, declarations.full_name( self.declaration ) ) ) + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) else: - if isinstance( self.declaration, declarations.member_function_t ) \ - and self.declaration.has_static: - if self.wrapper: - result.append( '(%s)(&%s)' - % ( self.wrapper.static_function_type(), self.wrapper.static_full_name() ) ) - else: - result.append( '(%s)(&%s)' % ( self.declaration.decl_string, fdname ) ) + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' );' ) + return ''.join( result ) - else: - if create_with_signature: - if access_type == declarations.ACCESS_TYPES.PROTECTED: - result.append( '(%s)(&%s)' % ( self.wrapper.function_type(), self.wrapper.full_name() ) ) - else: - result.append( '(%s)(&%s)' % ( self.declaration.decl_string, fdname ) ) - else: - if access_type == declarations.ACCESS_TYPES.PROTECTED: - result.append( '&%s' % self.wrapper.full_name() ) - else: - result.append( '&%s' % fdname ) - if self.wrapper and access_type != declarations.ACCESS_TYPES.PROTECTED: - result.append( self._PARAM_SEPARATOR ) - if create_with_signature: - result.append( '(%s)(&%s)' - % ( self.wrapper.default_function_type(), self.wrapper.default_full_name() ) ) - else: - result.append( '&%s' % self.wrapper.default_full_name() ) - return result +class mem_fun_t( calldef_t ): + def __init__( self, function, parent=None ): + calldef_t.__init__( self, function=function, parent=parent ) - def _generate_def_code(self): - indent_param = os.linesep + self.indent( self.indent( self._PARAM_SEPARATOR ) ) - result = [] - if self.is_class_function(): - result.append( 'def' ) + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)( &%s )' + %( self.declaration.function_type().decl_string + , declarations.full_name( self.declaration ) ) ) else: - result.append( algorithm.create_identifier( self, '::boost::python::def' ) ) - result.append( '( ' ) + result.append( '&%s' % declarations.full_name( self.declaration ) ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) + + +class mem_fun_pv_t( calldef_t ): + def __init__( self, function, wrapper, parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) + + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) result.append( '"%s"' % self.alias ) - result.append( indent_param ) - result.extend( self._generate_functions_ref() ) - if self.declaration.arguments and self.use_keywords: - result.append( indent_param ) - result.append( self._keywords_args() ) - if self.call_policies: - result.append( indent_param ) - result.append( self.call_policies.create( self ) ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '%s( (%s)(&%s) )' + % ( self.pure_virtual_identifier() + , self.declaration.function_type().decl_string + , declarations.full_name( self.declaration ) ) ) else: - result.append( '/*, undefined call policies */' ) + result.append( '%s( &%s )' + % ( self.pure_virtual_identifier() + , declarations.full_name( self.declaration ) ) ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) result.append( ' )' ) return ''.join( result ) + +class mem_fun_pv_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def create_declaration(self): + template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' - def _create_impl( self ): - code = self._generate_def_code() - if not self.is_class_function(): - code = code + ';' - return code + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : self.declaration.name + , 'args' : self.args_declaration() + , 'constness' : constness + } -class function_wrapper_t( declaration_based.declaration_based_t ): - """ - Creates C++ code that builds wrapper arround exposed function. There are - usecases when more then one function is created, for example virtual function. - """ - def __init__( self, function, parent=None ): - declaration_based.declaration_based_t.__init__( self, declaration=function, parent=parent ) - if self._is_call_operator(): - self.default_function_name = 'default_call' - elif self._is_index_operator(): - self.default_function_name = 'default_get_item' - else: - self.default_function_name = 'default_' + self.declaration.name - self._wrapped_class_inst_name = 'inst' + def create_body( self ): + if declarations.is_reference( self.declaration.return_type ): + return self.unoverriden_function_body() + template = [] + template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' ) + template.append( '%(return_)sfunc_%(alias)s( %(args)s );') + template = os.linesep.join( template ) + + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' - def _is_call_operator(self): - return isinstance( self.declaration, declarations.member_operator_t ) \ - and self.declaration.symbol == '()' + return template % { + 'override' : self.override_identifier() + , 'alias' : self.declaration.alias + , 'return_' : return_ + , 'args' : self.function_call_args() + } + + def _create_impl(self): + answer = [ self.create_declaration() + '{' ] + answer.append( self.indent( self.create_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + +class mem_fun_v_t( calldef_t ): + def __init__( self, function, wrapper=None, parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) - def _is_index_operator(self): - return isinstance( self.declaration, declarations.member_operator_t ) \ - and self.declaration.symbol == '[]' + def _create_impl(self): + param_sep = self.param_sep() - def _get_default_function_name(self): - return self._default_function_name - def _set_default_function_name( self, new_name ): - self._default_function_name = new_name - default_function_name = property( _get_default_function_name, _set_default_function_name ) + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.declaration.function_type().decl_string + , declarations.full_name( self.declaration ) ) ) + if self.wrapper: + result.append( param_sep ) + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string, self.wrapper.default_full_name() ) ) + else: + result.append( '&%s'% declarations.full_name( self.declaration ) ) + if self.wrapper: + result.append( param_sep ) + result.append( '&%s' % self.wrapper.default_full_name() ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) - def function_type(self): - return declarations.member_function_type_t.create_decl_string( +class mem_fun_v_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def default_full_name(self): + return self.parent.full_name + '::default_' + self.declaration.alias + + def function_type(self): + return declarations.member_function_type_t( return_type=self.declaration.return_type - , class_decl_string=self.parent.full_name + , class_inst=declarations.dummy_type_t( self.parent.full_name ) , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) , has_const=self.declaration.has_const ) + + def create_declaration(self, name): + template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : name + , 'args' : self.args_declaration() + , 'constness' : constness + } - def static_function_type(self): - arg_types = map( lambda arg: arg.type, self.declaration.arguments ) - return declarations.free_function_type_t.create_decl_string( - return_type=self.declaration.return_type - , arguments_types=arg_types) + def create_virtual_body(self): + template = [] + template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) + template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) + template.append( 'else' ) + template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) + template = os.linesep.join( template ) + + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' + + return template % { + 'override' : self.override_identifier() + , 'name' : self.declaration.name + , 'alias' : self.declaration.alias + , 'return_' : return_ + , 'args' : self.function_call_args() + , 'wrapped_class' : self.wrapped_class_identifier() + } + + def create_default_body(self): + function_call = declarations.call_invocation.join( self.declaration.name + , [ self.function_call_args() ] ) + body = self.wrapped_class_identifier() + '::' + function_call + ';' + if not declarations.is_void( self.declaration.return_type ): + body = 'return ' + body + return body - def default_function_type( self ): - return self.function_type() - - def full_name(self): - return self.parent.full_name + '::' + self.declaration.name + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_virtual_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) - def default_full_name(self): - return self.parent.full_name + '::' + self.default_function_name + def create_default_function( self ): + answer = [ self.create_declaration('default_' + self.declaration.alias) + '{' ] + answer.append( self.indent( self.create_default_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _create_impl(self): + answer = [ self.create_function() ] + answer.append( os.linesep ) + answer.append( self.create_default_function() ) + return os.linesep.join( answer ) - def static_full_name(self): - return self.parent.full_name + '::' + self.declaration.name - def _argument_name( self, index ): - arg = self.declaration.arguments[ index ] - if arg.name: - return arg.name +class mem_fun_protected_t( calldef_t ): + def __init__( self, function, wrapper, parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) + + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string + , self.wrapper.full_name() ) ) else: - return 'p%d' % index + result.append( '&%s' % self.wrapper.full_name() ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) - def _create_declaration_impl(self, name): - template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' +class mem_fun_protected_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def full_name(self): + return '::'.join( [self.parent.full_name, self.declaration.name] ) + + def function_type(self): + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self, name): + template = '%(return_type)s %(name)s( %(args)s )%(constness)s' - args = [] - for index, arg in enumerate( self.declaration.arguments ): - args.append( arg.type.decl_string + ' ' + self._argument_name(index) ) - constness = '' if self.declaration.has_const: constness = ' const ' @@ -236,184 +413,350 @@ return template % { 'return_type' : self.declaration.return_type.decl_string , 'name' : name - , 'args' : ', '.join( args ) + , 'args' : self.args_declaration() , 'constness' : constness - } + } + + def create_body(self): + tmpl = '%(return_)s%(wrapped_class)s::%(name)s( %(args)s );' + + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' + + return tmpl % { + 'name' : self.declaration.name + , 'return_' : return_ + , 'args' : self.function_call_args() + , 'wrapped_class' : self.wrapped_class_identifier() + } + + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) - def _create_declaration(self): - return self._create_declaration_impl( self.declaration.name ) + def _create_impl(self): + return self.create_function() + + + +class mem_fun_protected_s_t( calldef_t ): + def __init__( self, function, wrapper, parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) - def _create_default_declaration(self): - return self._create_declaration_impl( self.default_function_name ) + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string + , self.wrapper.full_name() ) ) + else: + result.append( '&%s' % self.wrapper.full_name() ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) + +class mem_fun_protected_s_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def full_name(self): + return '::'.join( [self.parent.full_name, self.declaration.name] ) - def _create_static_declaration( self ): + def function_type(self): + return declarations.free_function_type_t( + return_type=self.declaration.return_type + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) + + def create_declaration(self, name): template = 'static %(return_type)s %(name)s( %(args)s )' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : name + , 'args' : self.args_declaration() + } - args = [] - for index, arg in enumerate( self.declaration.arguments ): - args.append( arg.type.decl_string + ' ' + self._argument_name(index) ) + def create_body(self): + tmpl = '%(return_)s%(wrapped_class)s::%(name)s( %(args)s );' - args_str = ', '.join( args ) + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' - return template % { - 'return_type' : self.declaration.return_type.decl_string - , 'name' : self.declaration.name - , 'args' : args_str + return tmpl % { + 'name' : self.declaration.name + , 'return_' : return_ + , 'args' : self.function_call_args() + , 'wrapped_class' : self.wrapped_class_identifier() } - def _create_args_list( self ): - params = [] - for index in range( len( self.declaration.arguments ) ): - arg_type = declarations.remove_alias( self.declaration.arguments[index].type ) - arg_base_type = declarations.base_type( arg_type ) - if declarations.is_fundamental( arg_base_type ): - params.append( self._argument_name( index ) ) - elif declarations.is_reference( arg_type ) \ - and not declarations.is_const( arg_type ) \ - and not declarations.is_enum( arg_base_type ): - params.append( 'boost::ref(%s)' % self._argument_name( index ) ) - elif declarations.is_pointer( arg_type ) \ - and not declarations.is_fundamental( arg_type.base ) \ - and not declarations.is_enum( arg_base_type ): - params.append( 'boost::python::ptr(%s)' % self._argument_name( index ) ) - else: - params.append( self._argument_name( index ) ) - answer = ', '.join( params ) - if params: - answer = answer + ' ' - return answer + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) - def _create_function_call( self ): - answer = [ self.declaration.name ] - answer.append( '( ' ) - answer.append( self._create_args_list() ) - answer.append( ');' ) - return ''.join( answer ) + def _create_impl(self): + return self.create_function() + +class mem_fun_protected_v_t( calldef_t ): + def __init__( self, function, wrapper, parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) - def _create_virtual_body(self): + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string, self.wrapper.full_name() ) ) + else: + result.append( '&%s' % self.wrapper.full_name() ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) + + +class mem_fun_protected_v_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def full_name(self): + return self.parent.full_name + '::' + self.declaration.name + + def function_type(self): + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self, name): + template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : name + , 'args' : self.args_declaration() + , 'constness' : constness + } + + def create_virtual_body(self): template = [] - template.append( 'if( %(override)s %(variable_name)s = this->get_override( "%(name)s" ) )' ) - template.append( self.indent('%(return_)s%(variable_name)s( %(args)s );') ) + template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) + template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) template.append( 'else' ) - template.append( self.indent('%(return_)s%(wrapped_class)s::%(original_name)s( %(args)s );') ) + template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) template = os.linesep.join( template ) return_ = '' if not declarations.is_void( self.declaration.return_type ): return_ = 'return ' - if self._is_call_operator(): - name = '__call__' - variable_name = 'call' - elif self._is_index_operator(): - name = '__getitem__' - variable_name = 'getitem' - else: - name = self.declaration.name - variable_name = self.declaration.name return template % { - 'override' : algorithm.create_identifier( self, '::boost::python::override' ) - , 'name' : name - , 'variable_name' : variable_name - , 'original_name' : self.declaration.name + 'override' : self.override_identifier() + , 'name' : self.declaration.name + , 'alias' : self.declaration.alias , 'return_' : return_ - , 'args' : self._create_args_list() - , 'wrapped_class' : algorithm.create_identifier( self, self.declaration.parent.decl_string ) + , 'args' : self.function_call_args() + , 'wrapped_class' : self.wrapped_class_identifier() } - def _create_pure_virtual_body(self): + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_virtual_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _create_impl(self): + return self.create_function() + +class mem_fun_protected_pv_t( calldef_t ): + def __init__( self, function, wrapper,parent=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper, parent=parent ) + + def _create_impl(self): + param_sep = self.param_sep() + + result = [ 'def' ] + result.append( '(' ) + result.append( '"%s"' % self.alias ) + result.append( param_sep ) + if self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string + , self.wrapper.full_name() ) ) + else: + result.append( '&%s' % self.wrapper.full_name() ) + + if self.declaration.use_keywords: + result.append( param_sep ) + result.append( self.keywords_args() ) + if self.declaration.call_policies: + result.append( param_sep ) + result.append( self.declaration.call_policies.create( self ) ) + else: + result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + result.append( ' )' ) + return ''.join( result ) + +class mem_fun_protected_pv_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) + + def full_name(self): + return self.parent.full_name + '::' + self.declaration.name + + def function_type(self): + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self): + template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : self.declaration.name + , 'args' : self.args_declaration() + , 'constness' : constness + } + + def create_body( self ): if declarations.is_reference( self.declaration.return_type ): - return 'throw std::logic_error("Function, that returns reference to some object, could not be overriden from Python.");' - + return self.unoverriden_function_body() + template = [] - template.append( '%(override)s %(variable_name)s = this->get_override( "%(name)s" );' ) - template.append( '%(return_)s%(variable_name)s( %(args)s );') + template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' ) + template.append( '%(return_)sfunc_%(alias)s( %(args)s );') template = os.linesep.join( template ) return_ = '' if not declarations.is_void( self.declaration.return_type ): return_ = 'return ' - - if self._is_call_operator(): - name = '__call__' - variable_name = 'call' - elif self._is_index_operator(): - name = '__getitem__' - variable_name = 'getitem' - else: - name = self.declaration.name - variable_name = self.declaration.name + return template % { - 'override' : algorithm.create_identifier( self, '::boost::python::override' ) - , 'name' : name - , 'variable_name' : variable_name + 'override' : self.override_identifier() + , 'alias' : self.declaration.alias , 'return_' : return_ - , 'args' : self._create_args_list() + , 'args' : self.function_call_args() } + + def _create_impl(self): + answer = [ self.create_declaration() + '{' ] + answer.append( self.indent( self.create_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) - def _create_default_body(self): - function_call = self._create_function_call() - wrapped_class_name = algorithm.create_identifier( self, self.declaration.parent.decl_string ) - body = 'this->' + wrapped_class_name + '::' + function_call - if not declarations.is_void( self.declaration.return_type ): - body = 'return ' + body - return body +class mem_fun_private_v_wrapper_t( calldef_wrapper_t ): + def __init__( self, function, parent=None): + calldef_wrapper_t.__init__( self, function=function, parent=parent ) - def _create_non_virtual_body(self): - function_call = self._create_function_call() - wrapped_class_name = algorithm.create_identifier( self, self.declaration.parent.decl_string ) - body = 'this->' + wrapped_class_name + '::' + function_call + def full_name(self): + return self.parent.full_name + '::' + self.declaration.name + + def function_type(self): + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self): + template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'return_type' : self.declaration.return_type.decl_string + , 'name' : self.declaration.name + , 'args' : self.args_declaration() + , 'constness' : constness + } + + def create_body( self ): + if declarations.is_reference( self.declaration.return_type ): + return self.unoverriden_function_body() + + template = [] + template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' ) + template.append( '%(return_)sfunc_%(alias)s( %(args)s );') + template = os.linesep.join( template ) + + return_ = '' if not declarations.is_void( self.declaration.return_type ): - body = 'return ' + body - return body + return_ = 'return ' - def _create_static_body(self): - assert isinstance( self.declaration, declarations.member_function_t ) - fcall = '%s( %s );' % ( declarations.full_name( self.declaration ) - , self._create_args_list() ) - if not declarations.is_same( self.declaration.return_type, declarations.void_t() ): - fcall = 'return ' + fcall - return fcall - - def _create_function(self): - answer = [ self._create_declaration() + '{' ] - if self.declaration.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL: - answer.append( self.indent( self._create_pure_virtual_body() ) ) - elif self.declaration.virtuality == declarations.VIRTUALITY_TYPES.VIRTUAL: - answer.append( self.indent( self._create_virtual_body() ) ) - else: - answer.append( self.indent( self._create_non_virtual_body() ) ) + return template % { + 'override' : self.override_identifier() + , 'alias' : self.declaration.alias + , 'return_' : return_ + , 'args' : self.function_call_args() + } + + def _create_impl(self): + answer = [ self.create_declaration() + '{' ] + answer.append( self.indent( self.create_body() ) ) answer.append( '}' ) return os.linesep.join( answer ) - - def _create_default_function( self ): - answer = [ self._create_default_declaration() + '{' ] - answer.append( self.indent( self._create_default_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - - def _create_static_function(self): - answer = [] - answer.append( self._create_static_declaration() + '{' ) - answer.append( self.indent( self._create_static_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - - def _create_impl(self): - if self.declaration.name == 'invert_sign': - i = 0 - answer = [] - if self.declaration.has_static: - #we will come here only in case the function is protected - answer.append( self._create_static_function() ) - else: - answer.append( self._create_function() ) - - if self.declaration.virtuality == declarations.VIRTUALITY_TYPES.VIRTUAL: - answer.append('') - answer.append( self._create_default_function() ) - return os.linesep.join( answer ) +mem_fun_private_pv_wrapper_t = mem_fun_private_v_wrapper_t + + +#class protected_helper_t( object ): + #def __init__( self ): + #object.__init__( self ) + + #def wclass_inst_arg_type( self ): + #inst_arg_type = declarations.declarated_t( self.declaration.parent ) + #if self.declaration.has_const: + #inst_arg_type = declarations.const_t(inst_arg_type) + #inst_arg_type = declarations.reference_t(inst_arg_type) + #return inst_arg_type + + #def wclass_inst_arg( self ): + #return self.wclass_inst_arg_type().decl_string + ' wcls_inst' + + class constructor_t( declaration_based.declaration_based_t ): """ Creates boost.python code needed to expose constructor. @@ -541,7 +884,7 @@ , declaration=constructor , parent=parent ) - def _argument_name( self, index ): + def argument_name( self, index ): arg = self.declaration.arguments[ index ] if arg.name: return arg.name @@ -556,7 +899,7 @@ if self.parent.held_type and not self.target_configuration.boost_python_has_wrapper_held_type: args.append( 'PyObject*' ) for index, arg in enumerate( self.declaration.arguments ): - arg_text = arg.type.decl_string + ' ' + self._argument_name(index) + arg_text = arg.type.decl_string + ' ' + self.argument_name(index) if arg.default_value: arg_text = arg_text + '=%s' % arg.default_value args.append( arg_text ) @@ -569,7 +912,7 @@ answer.append( '( ' ) params = [] for index in range( len( self.declaration.arguments ) ): - params.append( self._argument_name( index ) ) + params.append( self.argument_name( index ) ) answer.append( ', '.join( params ) ) if params: answer.append(' ') @@ -655,21 +998,6 @@ SECOND = 'second' BOTH = 'both' - class supported: - inplace = [ '+=', '-=', '*=', '/=', '%=', '>>=', '<<=', '&=', '^=', '|=' ] - comparison = [ '==', '!=', '<', '>', '<=', '>=' ] - non_member = [ '+', '-', '*', '/', '%', '&', '^', '|' ] #'>>', '<<', not implemented - unary = [ '!', '~', '+', '-' ] - - all = inplace + comparison + non_member + unary - - def is_supported( oper ): - if oper.symbol == '*' and len( oper.arguments ) == 0: - #dereference does not make sense - return False - return oper.symbol in operator_t.supported.all - is_supported = staticmethod( is_supported ) - def __init__(self, operator, parent=None ): declaration_based.declaration_based_t.__init__( self , declaration=operator @@ -761,67 +1089,13 @@ Creates boost.python code needed to register casting operators. For some operators Pythonic name is given: __int__, __long__, __float__, __str__ """ - - def prepare_special_cases(): - special_cases = {} - const_t = declarations.const_t - pointer_t = declarations.pointer_t - for type_ in declarations.FUNDAMENTAL_TYPES.values(): - alias = None - if declarations.is_same( type_, declarations.bool_t() ): - alias = '__int__' - elif declarations.is_integral( type_ ): - if 'long' in type_.decl_string: - alias = '__long__' - else: - alias = '__int__' - elif declarations.is_floating_point( type_ ): - alias = '__float__' - else: - continue #void - if alias: - special_cases[ type_ ] = alias - special_cases[ const_t( type_ ) ] = alias - special_cases[ pointer_t( const_t( declarations.char_t() ) ) ] = '__str__' - std_string = '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' - std_wstring = '::std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >' - special_cases[ std_string ] = '__str__' - special_cases[ std_wstring ] = '__str__' - special_cases[ '::std::string' ] = '__str__' - special_cases[ '::std::wstring' ] = '__str__' - - #TODO: add - # std::complex<SomeType> some type should be converted to double - return special_cases - SPECIAL_CASES = prepare_special_cases() - #casting_member_operator_t.prepare_special_cases() - + def __init__( self, operator, parent=None ): declaration_based.declaration_based_t.__init__( self , declaration=operator , parent=parent ) self._call_policies = None - self.alias = self._find_out_alias() - def _find_out_alias( self ): - return_type = declarations.remove_alias( self.declaration.return_type ) - decl_string = return_type.decl_string - for type_, alias in self.SPECIAL_CASES.items(): - if isinstance( type_, declarations.type_t ): - if declarations.is_same( return_type, type_ ): - return alias - else: - if decl_string == type_: - return alias - else: - return 'as_' + self._generate_valid_name(self.declaration.return_type.decl_string) - - def _get_call_policies(self): - return self.declaration.call_policies - def _set_call_policies(self, call_policies): - self.declaration.call_policies = call_policies - call_policies = property( _get_call_policies, _set_call_policies ) - def _create_impl(self): template = 'def( "%(function_name)s", &%(class_name)s::operator %(destination_type)s %(call_policies)s )' @@ -829,10 +1103,10 @@ , declarations.full_name( self.declaration.parent ) ) policies = '/*, undefined call policies */' - if self.call_policies: - policies = ',' + self.call_policies.create( self ) + if self.declaration.call_policies: + policies = ',' + self.declaration.call_policies.create( self ) - return template % { 'function_name' : self.alias + return template % { 'function_name' : self.declaration.alias , 'class_name' : class_name , 'destination_type' : self.declaration.return_type.decl_string , 'call_policies' : policies This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:20:16
|
Revision: 49 Author: roman_yakovenko Date: 2006-05-01 22:20:07 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=49&view=rev Log Message: ----------- code cleanup moving treatment of pure virtual functions to module_creator/creator.py Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-05-02 05:18:50 UTC (rev 48) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-05-02 05:20:07 UTC (rev 49) @@ -24,24 +24,12 @@ , declaration=class_inst ) self._wrapper = wrapper - def _get_always_expose_using_scope( self ): - return self.declaration.always_expose_using_scope - def _set_always_expose_using_scope( self, value ): - self.declaration.always_expose_using_scope = value - always_expose_using_scope = property( _get_always_expose_using_scope, _set_always_expose_using_scope ) - def _get_wrapper( self ): return self._wrapper def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - def _get_redefine_operators( self ): - return self.declaration.redefine_operators - def _set_redefine_operators( self, new_value ): - self.declaration.redefine_operators = new_value - redefine_operators = property( _get_redefine_operators, _set_redefine_operators ) - def _get_held_type(self): return self.declaration.held_type def _set_held_type(self, held_type): @@ -173,7 +161,7 @@ class_constructor, used_init = self._generate_constructor() result.append( class_constructor ) creators = self.creators - if self.redefine_operators: + if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators(base_classes, base_creators) for x in creators: if not ( x is used_init ): @@ -220,7 +208,7 @@ result[-1] = result[-1] + '( %s );' % self.class_var_name creators = self.creators - if self.redefine_operators: + if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators(base_classes, base_creators) for x in creators: @@ -243,7 +231,7 @@ def is_exposed_using_scope(self): scoped_exporters = filter( lambda x: self._should_creator_be_exported_under_scope( x ) , self.creators ) - return bool( self.always_expose_using_scope or scoped_exporters ) + return bool( self.declaration.always_expose_using_scope or scoped_exporters ) def _create_impl(self): if self.is_exposed_using_scope(): @@ -314,28 +302,11 @@ def _create_bases(self): return ', '.join( [self.exposed_identifier, self.boost_wrapper_identifier] ) - - def _get_pure_virtual_function_creators( self ): - creators = [] - for base_wrapper in self.base_wrappers: - for creator in base_wrapper.creators: - if not isinstance( creator, declaration_based.declaration_based_t ): - continue - if not isinstance( creator.declaration, declarations.member_calldef_t ): - continue - if creator.declaration.virtuality != declarations.VIRTUALITY_TYPES.PURE_VIRTUAL: - continue - creators.append( creator ) - return creators - + def _create_impl(self): answer = ['struct %s : %s {' % ( self.wrapper_alias, self._create_bases() )] answer.append( '' ) answer.append( self.create_internal_code( self.creators ) ) - pvcreators = self._get_pure_virtual_function_creators() - if pvcreators: - answer.append( '' ) - answer.append( self.create_internal_code( pvcreators ) ) answer.append( '' ) answer.append( '};' ) return os.linesep.join( answer ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:19:00
|
Revision: 48 Author: roman_yakovenko Date: 2006-05-01 22:18:50 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=48&view=rev Log Message: ----------- dummy_type_t class has been moved to pygccxml package Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/member_variable.py Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-02 05:17:57 UTC (rev 47) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-02 05:18:50 UTC (rev 48) @@ -382,7 +382,7 @@ , str( declarations.array_size( self.declaration.type ) ) ]) - return algorithm.dummy_type_t( decl_string ) + return declarations.dummy_type_t( decl_string ) wrapper_type = property( _get_wrapper_type ) def _get_wrapper_creator_type(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:18:10
|
Revision: 47 Author: roman_yakovenko Date: 2006-05-01 22:17:57 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=47&view=rev Log Message: ----------- adding exportable functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-05-02 05:17:01 UTC (rev 46) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-05-02 05:17:57 UTC (rev 47) @@ -86,4 +86,10 @@ def add_wrapper_code( self, code ): self.wrapper_user_code.append( user_text.user_text_t( code ) ) - \ No newline at end of file + + def _exportable_impl( self ): + if isinstance( self.parent, declarations.namespace_t ): + return '' + if not self in self.parent.public_members: + return 'pyplusplus can not expose private class.' + return '' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:17:12
|
Revision: 46 Author: roman_yakovenko Date: 2006-05-01 22:17:01 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=46&view=rev Log Message: ----------- adding exportable functionality adding overridable property Virtual functions, that returns [const]reference, could not be overriden from Python. The reason is simple: in boost::python::override::operator(...) result of marshaling (Python 2 C++) is saved on stack, after function exit, the result will be reference to no where - access violetion. For example see temporal variable tester. Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-05-02 05:04:56 UTC (rev 45) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-05-02 05:17:01 UTC (rev 46) @@ -22,6 +22,7 @@ self._use_keywords = True self._use_default_arguments = True self._create_with_signature = False + self._overridable = None def get_call_policies(self): return self._call_policies @@ -30,13 +31,13 @@ call_policies = property( get_call_policies, set_call_policies ) def _get_use_keywords(self): - return self._use_keywords + return self._use_keywords and bool( self.arguments ) def _set_use_keywords(self, use_keywords): self._use_keywords = use_keywords use_keywords = property( _get_use_keywords, _set_use_keywords ) def _get_create_with_signature(self): - return self._create_with_signature + return self._create_with_signature or bool( self.overloads ) def _set_create_with_signature(self, create_with_signature): self._create_with_signature = create_with_signature create_with_signature = property( _get_create_with_signature, _set_create_with_signature) @@ -67,7 +68,52 @@ else: pass - def readme( self ): + def get_overridable( self ): + """ + Virtual functions, that returns const reference, could not be overriden + from Python. The reason is simple: in boost::python::override::operator(...) + result of marshaling (Python 2 C++) is saved on stack, after function + exit, the result will be reference to no where - access violetion. + For example see temporal variable tester + """ + if None is self._overridable: + if isinstance( self, declarations.member_calldef_t ) \ + and self.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL \ + and declarations.is_reference( self.return_type ): + self._overridable = False + else: + self._overridable = True + return self._overridable + + def set_overridable( self, overridable ): + self._overridable = overridable + + overridable = property( get_overridable, set_overridable + , doc = get_overridable.__doc__ ) + + def _exportable_impl( self ): + #see http://www.boost.org/libs/python/doc/v2/faq.html#funcptr + if len( self.arguments ) > 10: + return "boost.python can not expose function with more then 10 arguments. ( impl details: boost.tuple is limited to 10 args )." + all_types = [ arg.type for arg in self.arguments ] + all_types.append( self.return_type ) + for some_type in all_types: + units = declarations.decompose_type( some_type ) + ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) + , units ) + if ptr2functions: + return "boost.python can not expose function, which takes as argument/returns pointer to function." \ + + " See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." + #Function that take as agrument some instance of non public class + #will not be exported. Same to the return variable + if isinstance( units[-1], declarations.declarated_t ): + dtype = units[-1] + if isinstance( dtype.declaration.parent, declarations.class_t ): + if dtype.declaration not in dtype.declaration.parent.public_members: + return "pyplusplus can not expose fuction that takes as argument/returns instance of non public class. Generated code will not compile." + return '' + + def _readme_impl( self ): def suspicious_type( type_ ): if not declarations.is_reference( self.return_type ): return False @@ -83,23 +129,57 @@ + 'non-const reference to C++ fundamental type - ' \ + 'function could not be called from Python.' msg.append( tmpl % ( str( self ), arg.name, index ) ) + + if False == self.overridable: + msg.append( self.get_overridable.__doc__ ) return msg - + class member_function_t( declarations.member_function_t, calldef_t ): def __init__(self, *arguments, **keywords): declarations.member_function_t.__init__( self, *arguments, **keywords ) calldef_t.__init__( self ) - + class constructor_t( declarations.constructor_t, calldef_t ): def __init__(self, *arguments, **keywords): declarations.constructor_t.__init__( self, *arguments, **keywords ) calldef_t.__init__( self ) + + def _exportable_impl( self ): + if self.is_artificial: + return 'pyplusplus does not exports compiler generated constructors' + return '' + class destructor_t( declarations.destructor_t, calldef_t ): def __init__(self, *arguments, **keywords): declarations.destructor_t.__init__( self, *arguments, **keywords ) calldef_t.__init__( self ) - + +class operators_helper: + + inplace = [ '+=', '-=', '*=', '/=', '%=', '>>=', '<<=', '&=', '^=', '|=' ] + comparison = [ '==', '!=', '<', '>', '<=', '>=' ] + non_member = [ '+', '-', '*', '/', '%', '&', '^', '|' ] #'>>', '<<', not implemented + unary = [ '!', '~', '+', '-' ] + + all = inplace + comparison + non_member + unary + + def is_supported( oper ): + if oper.symbol == '*' and len( oper.arguments ) == 0: + #dereference does not make sense + return False + return oper.symbol in operators_helper.all + is_supported = staticmethod( is_supported ) + + def exportable( oper ): + if isinstance( oper, declarations.member_operator_t ) and oper.symbol in ( '()', '[]' ): + return '' + if not operators_helper.is_supported( oper ): + #see http://www.boost.org/libs/python/doc/v2/operators.html#introduction + return 'operator %s is not supported. Please take a look on http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' + return '' + exportable = staticmethod( exportable ) + class member_operator_t( declarations.member_operator_t, calldef_t ): def __init__(self, *arguments, **keywords): declarations.member_operator_t.__init__( self, *arguments, **keywords ) @@ -117,11 +197,72 @@ return alias alias = property( _get_alias, decl_wrapper.decl_wrapper_t._set_alias ) + def _exportable_impl( self ): + return operators_helper.exportable( self ) + + class casting_operator_t( declarations.casting_operator_t, calldef_t ): + + def prepare_special_cases(): + """ + Creates a map of special cases ( aliases ) for casting operator. + """ + special_cases = {} + const_t = declarations.const_t + pointer_t = declarations.pointer_t + for type_ in declarations.FUNDAMENTAL_TYPES.values(): + alias = None + if declarations.is_same( type_, declarations.bool_t() ): + alias = '__int__' + elif declarations.is_integral( type_ ): + if 'long' in type_.decl_string: + alias = '__long__' + else: + alias = '__int__' + elif declarations.is_floating_point( type_ ): + alias = '__float__' + else: + continue #void + if alias: + special_cases[ type_ ] = alias + special_cases[ const_t( type_ ) ] = alias + special_cases[ pointer_t( const_t( declarations.char_t() ) ) ] = '__str__' + std_string = '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' + std_wstring = '::std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >' + special_cases[ std_string ] = '__str__' + special_cases[ std_wstring ] = '__str__' + special_cases[ '::std::string' ] = '__str__' + special_cases[ '::std::wstring' ] = '__str__' + + #TODO: add + # std::complex<SomeType> some type should be converted to double + return special_cases + + SPECIAL_CASES = prepare_special_cases() + #casting_member_operator_t.prepare_special_cases() + def __init__(self, *arguments, **keywords): declarations.casting_operator_t.__init__( self, *arguments, **keywords ) calldef_t.__init__( self ) + def _get_alias( self): + if not self._alias or self.name == super( member_operator_t, self )._get_alias(): + return_type = declarations.remove_alias( self.return_type ) + decl_string = return_type.decl_string + for type_, alias in self.SPECIAL_CASES.items(): + if isinstance( type_, declarations.type_t ): + if declarations.is_same( return_type, type_ ): + self._alias = alias + break + else: + if decl_string == type_: + self._alias = alias + break + else: + self._alias = 'as_' + self._generate_valid_name(self.return_type.decl_string) + return self._alias + alias = property( _get_alias, decl_wrapper.decl_wrapper_t._set_alias ) + class free_function_t( declarations.free_function_t, calldef_t ): def __init__(self, *arguments, **keywords): declarations.free_function_t.__init__( self, *arguments, **keywords ) @@ -131,3 +272,6 @@ def __init__(self, *arguments, **keywords): declarations.free_operator_t.__init__( self, *arguments, **keywords ) calldef_t.__init__( self ) + + def _exportable_impl( self ): + return operators_helper.exportable( self ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:05:04
|
Revision: 45 Author: roman_yakovenko Date: 2006-05-01 22:04:56 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=45&view=rev Log Message: ----------- adding exportable functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-05-02 05:03:50 UTC (rev 44) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-05-02 05:04:56 UTC (rev 45) @@ -9,4 +9,18 @@ class variable_t(decl_wrapper.decl_wrapper_t, declarations.variable_t): def __init__(self, *arguments, **keywords): declarations.variable_t.__init__(self, *arguments, **keywords ) - decl_wrapper.decl_wrapper_t.__init__( self ) \ No newline at end of file + decl_wrapper.decl_wrapper_t.__init__( self ) + + def _exportable_impl( self ): + if not isinstance( self.parent, declarations.class_t ): + return '' + if self.bits == 0 and self.name == "": + return "pyplusplus can not expose alignement bit." + type_ = declarations.remove_const( self.type ) + if declarations.is_pointer( type_ ): + if self.type_qualifiers.has_static: + return "pyplusplus, right now, can not expose static pointer member variables. This could be changed in future." + if declarations.is_fundamental( type_.base ): + return "pyplusplus, right now, can not expose pointer to fundamental member variables. This could be changed in future." + return '' + \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:03:57
|
Revision: 44 Author: roman_yakovenko Date: 2006-05-01 22:03:50 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=44&view=rev Log Message: ----------- decl_wrapper_t class has new functionality: exportable - boolean property, that tells user whether this declaration can be exported to Python or not why_not_exportable - function, that will explain the reason why the declaration can not be exported. Sometimes link to the relevant piece of documentation will be provided. Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-05-02 05:01:00 UTC (rev 43) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-05-02 05:03:50 UTC (rev 44) @@ -35,6 +35,8 @@ object.__init__(self) self._alias = None self._ignore = False + self._exportable = None + self._exportable_reason = None def _generate_valid_name(self, name=None): if name == None: @@ -62,11 +64,13 @@ self.alias = new_name def _get_ignore( self ): - return self._ignore + return self._ignore or not self.exportable + def _set_ignore( self, value ): self._ignore = value ignore = property( _get_ignore, _set_ignore ,doc="If you set ignore to True then this declaration will not be exported." ) + def exclude( self ): """Exclude "self" and child declarations from being exposed.""" self.ignore = True @@ -75,6 +79,31 @@ """Include "self" and child declarations to be exposed.""" self.ignore = False + def why_not_exportable( self ): + if None is self._exportable_reason: + self.get_exportable() + return self._exportable_reason + + def _exportable_impl( self ): + return '' + + def get_exportable( self ): + if self._exportable is None: + if self.name.startswith( '__' ): + self._exportable_reason = 'pyplusplus, by default, does not exposes internal compilers declarations. Names of those declarations starts with "__".' + elif self.location and self.location.file_name == "<internal>": + self._exportable_reason = 'pyplusplus, by default, does not exposes declarations, that belongs to "<internal>" header.' + else: + self._exportable_reason = self._exportable_impl( ) + self._exportable = not bool( self._exportable_reason ) + return self._exportable + + def set_exportable( self, exportable ): + self._exportable = exportable + + exportable = property( get_exportable, set_exportable + , doc="Returns True if declaration could be exported to Python, otherwise False" ) + #TODO: #I think that almost every declaration could have some wrapper. This is the #main reason why those 3 functions does not have some well defined interface. @@ -92,6 +121,8 @@ #print 'Unable to finalize declaration: ', str( error ) #else: #raise + def _readme_impl( self ): + return [] def readme( self ): """This function will returns some hints/tips/description of problems @@ -99,4 +130,8 @@ reference to some fundamental type could be exported, but could not be called from Python """ - return [] + text = [] + if not self.exportable: + text.append( 'WARNING: ' + self.why_not_exportable() ) + text.extend( self._readme_impl() ) + return text This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 05:01:08
|
Revision: 43 Author: roman_yakovenko Date: 2006-05-01 22:01:00 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=43&view=rev Log Message: ----------- moving dummy_type_t class to pygccxml package Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-05-02 04:59:48 UTC (rev 42) +++ pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-05-02 05:01:00 UTC (rev 43) @@ -93,15 +93,3 @@ return new_name else: return full_name - -class dummy_type_t( pygccxml.declarations.type_t ): - #This class is very usefull for code generation - def __init__( self, decl_string ): - pygccxml.declarations.type_t.__init__( self ) - self._decl_string = decl_string - - def _create_decl_string(self): - return self._decl_string - - def _clone_impl( self ): - return dummy_type_t( self._decl_string ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-05-02 04:59:56
|
Revision: 42 Author: roman_yakovenko Date: 2006-05-01 21:59:48 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=42&view=rev Log Message: ----------- adding *.obj filter Property Changed: ---------------- pyplusplus_dev/unittests/data/ Property changes on: pyplusplus_dev/unittests/data ___________________________________________________________________ Name: svn:ignore + *.obj This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |