Update of /cvsroot/pygccxml/source/pyplusplus/experimental
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2910
Modified Files:
declwrapper.py pypp_api.py
Log Message:
1) Activated the cdef, staticmethod (and addMethod) functions using the new add_code() decoration functions. 2) During selection a set of overloads counts as 1 declaration (i.e. calling Method() may return several declarations without generating an error). 3) Added the option to write a query log file that contains all queries (with a reference to the source line) and the results of the queries. This file can be used to check if a multi query really did what it was supposed to do.
Index: pypp_api.py
===================================================================
RCS file: /cvsroot/pygccxml/source/pyplusplus/experimental/pypp_api.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** pypp_api.py 14 Mar 2006 10:22:10 -0000 1.8
--- pypp_api.py 20 Mar 2006 09:32:24 -0000 1.9
***************
*** 53,56 ****
--- 53,58 ----
from pyplusplus.decl_wrappers import return_value_policy
+ import declwrapper
+
PUBLIC = ACCESS_TYPES.PUBLIC
PROTECTED = ACCESS_TYPES.PROTECTED
***************
*** 192,198 ****
--- 194,206 ----
In normal usage the user will not call this directly.
Return the base of the creator tree.
+
+ @rtype: module_t
"""
if None == self.mDeclRoot:
self.parse()
+
+ # Lock the decoration interface (an attempt to decorate after this
+ # call will lead to an error)
+ declwrapper.decl_lock = True
if self.mVerbose:
***************
*** 217,221 ****
# maker = module_creator.creator_t(self.mFinalDecls, module_name=moduleName)
extmodule = maker.create(decl_headers=self.mHeaderFiles)
!
# Handle the extra creators that need added
mod_body = extmodule.body
--- 225,229 ----
# maker = module_creator.creator_t(self.mFinalDecls, module_name=moduleName)
extmodule = maker.create(decl_headers=self.mHeaderFiles)
!
# Handle the extra creators that need added
mod_body = extmodule.body
Index: declwrapper.py
===================================================================
RCS file: /cvsroot/pygccxml/source/pyplusplus/experimental/declwrapper.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** declwrapper.py 15 Mar 2006 17:16:39 -0000 1.4
--- declwrapper.py 20 Mar 2006 09:32:24 -0000 1.5
***************
*** 9,13 ****
"""
! import types
from filters import *
import decltypes
--- 9,13 ----
"""
! import sys, os.path, inspect, types
from filters import *
import decltypes
***************
*** 21,24 ****
--- 21,29 ----
allow_empty_queries = False
default_recursive = False
+ query_log = None
+
+ # If this is set to True an attempt to decorate a declaration will
+ # result in an error (this is set after the code creators have been created)
+ decl_lock = False
# IDecl
***************
*** 39,48 ****
"""
! def __init__(self, decls):
"""Constructor.
@param decls: One or more declarations that should be stored in this instance
@type decls: declaration_t or list of declaration_t
"""
if type(decls)!=list:
--- 44,56 ----
"""
! def __init__(self, decls, filter=None):
"""Constructor.
@param decls: One or more declarations that should be stored in this instance
@type decls: declaration_t or list of declaration_t
+ @param filter: Filter string (only for informational purposes)
+ @type filter: str
"""
+ global query_log
if type(decls)!=list:
***************
*** 53,56 ****
--- 61,91 ----
self.decl_handles = decls
+ # Determine where this instance was created...
+ filename,funcname,linenr,sourceline = self._sourceInfo()
+ self.filename = filename
+ self.funcname = funcname
+ self.linenr = linenr
+ self.sourceline = sourceline
+
+ # Dump info about this query...
+ if query_log:
+ print >>query_log, 70*"-"
+ if funcname==None:
+ print >>query_log, "%s, %d: %s"%(self.filename, self.linenr, self.sourceline)
+ else:
+ print >>query_log, "%s, %s(), %d: %s"%(self.filename, self.funcname, self.linenr, self.sourceline)
+ if filter!=None:
+ print >>query_log, "Filter: %s"%filter
+ for decl in self.decl_handles:
+ declstr = getattr(decl, "decl_string", "[no decl_string] "+pygccxml.declarations.full_name(decl))
+ # declstr = pygccxml.declarations.full_name(decl)
+ clsstr = decl.__class__.__name__.replace("_t", "")
+ print >>query_log, " -> %s [%s]"%(declstr, clsstr)
+ if len(self.decl_handles)==0:
+ print >>query_log, " <no result>"
+ elif len(self.decl_handles)>1:
+ print >>query_log, " (%d declarations)"%len(self.decl_handles)
+
+
def __str__(self):
"""Return a descriptive string."""
***************
*** 87,90 ****
--- 122,126 ----
@see: L{ignore()}
"""
+ self._checkLock()
for d in self._iterContained():
d.include()
***************
*** 103,106 ****
--- 139,143 ----
@see: L{expose()}
"""
+ self._checkLock()
for d in self._iterContained():
d.exclude()
***************
*** 126,129 ****
--- 163,167 ----
@type name: str
"""
+ self._checkLock()
for decl in self._iterContained(recursive=False):
decl.rename(name)
***************
*** 136,139 ****
--- 174,178 ----
Prevents the generation of wrappers for virtual member functions.
"""
+ self._checkLock()
for decl in self._iterContained():
decl.finalize()
***************
*** 147,150 ****
--- 186,190 ----
@type policy: ...policy...
"""
+ self._checkLock()
for decl in self._iterContained():
decl.call_policies = policy
***************
*** 156,159 ****
--- 196,200 ----
Ex: C{setHeldType("boost::shared_ptr<Class>")}
"""
+ self._checkLock()
for decl in self._iterContained():
decl.held_type = heldType
***************
*** 165,168 ****
--- 206,210 ----
"""
+ self._checkLock()
for decl in self._iterContained():
decl.use_keywords = False
***************
*** 185,195 ****
@param name: The method name as it will appear in the Python module
! @type name: str:
@param impl: The name of the C/C++ function that implements the method.
@type impl: str
- @returns: Returns a Decl object containing the newly created method.
"""
! raise NotImplementedError, "addMethod() isn't implemented yet"
! pass
# def
--- 227,236 ----
@param name: The method name as it will appear in the Python module
! @type name: str
@param impl: The name of the C/C++ function that implements the method.
@type impl: str
"""
! self.cdef(name, impl)
!
# def
***************
*** 213,238 ****
"""
! raise NotImplementedError, "cdef() isn't implemented yet"
!
! ## doc,policies,keywords = self._parseDefArgs(args)
! ## args = ['"%s"'%name, fn]
! ## if policies!=None:
! ## pass # todo
! ## if keywords!=None:
! ## args.append("(%s)"%", ".join(map(lambda x: "bp::"+str(x), keywords)))
! ## if doc!=None:
! ## a = map(lambda x: "%s\\n"%x, doc.split("\n"))
! ## while len(a)>0 and a[-1]=="\\n":
! ## a = a[:-1]
! ## if len(a)>0:
! ## # Remove the newline in the last line
! ## a[-1] = a[-1][:-2]
! ## args.append('%s'%"\n".join(map(lambda x: '"%s"'%x, a)))
! ## src = 'def( %s )'%(", ".join(args))
! ## for decl in self._iterContained(no_children=True):
! ## # Add the 'def' source code line to the list of defs...
! ## if not hasattr(decl, "_user_defs"):
! ## decl._user_defs = []
! ## decl._user_defs.append(src)
return self
--- 254,276 ----
"""
! self._checkLock()
! doc,policies,keywords = self._parseDefArgs(args)
! args = ['"%s"'%name, fn]
! if policies!=None:
! pass # todo
! if keywords!=None:
! args.append("(%s)"%", ".join(map(lambda x: "bp::"+str(x), keywords)))
! if doc!=None:
! a = map(lambda x: "%s\\n"%x, doc.split("\n"))
! while len(a)>0 and a[-1]=="\\n":
! a = a[:-1]
! if len(a)>0:
! # Remove the newline in the last line
! a[-1] = a[-1][:-2]
! args.append('%s'%"\n".join(map(lambda x: '"%s"'%x, a)))
! src = 'def( %s )'%(", ".join(args))
! for decl in self._iterContained(recursive=False):
! # Add the 'def' source code...
! decl.add_code(src)
return self
***************
*** 247,256 ****
"""
! raise NotImplementedError, "staticmethod() isn't implemented yet"
!
! # for decl in self._iterContained(no_children=True):
! # if not hasattr(decl, "_user_defs"):
! # decl._user_defs = []
! # decl._user_defs.append('staticmethod( "%s" )'%name)
return self
--- 285,292 ----
"""
! self._checkLock()
! for decl in self._iterContained(recursive=False):
! src = 'staticmethod( "%s" )'%name
! decl.add_code(src)
return self
***************
*** 415,419 ****
decls = selection.select(self.decl_handles, filter)
! res = IDecl(decls)
count = res.count
if allow_empty and count==0:
--- 451,455 ----
decls = selection.select(self.decl_handles, filter)
! res = IDecl(decls, str(filter))
count = res.count
if allow_empty and count==0:
***************
*** 421,427 ****
if count==0:
raise RuntimeError, "Query produced no results (filter: %s)"%filter
if assert_count!=None:
! if res.count!=assert_count:
! raise RuntimeError, "Query produced the wrong number of results (%d instead of %d)"%(res.count, assert_count)
return res
--- 457,468 ----
if count==0:
raise RuntimeError, "Query produced no results (filter: %s)"%filter
+ res_count = res.count
+ # If all contained declarations are from one single set of overloads
+ # then treat that as one single declaration
+ if res._checkOverloads():
+ res_count = 1
if assert_count!=None:
! if res_count!=assert_count:
! raise RuntimeError, "Query produced the wrong number of results (%d instead of %d)"%(res_count, assert_count)
return res
***************
*** 514,517 ****
--- 555,587 ----
totalcount = property(_getTotalCount, None, None, "The total number of contained declarations.")
+ def _checkLock(self):
+ """Check that the decoration is not locked.
+
+ If it is locked, an exception is thrown.
+ """
+ global decl_lock
+ if decl_lock:
+ raise RuntimeError, "You have to decorate the declarations before the code creators have been built."
+
+ def _checkOverloads(self):
+ """Check if all contained declarations are from the same set of overloads.
+
+ @returns: True if all contained declarations are from the same set of overloads.
+ @rtype: bool
+ """
+ if len(self.decl_handles)==0:
+ return False
+ # Get a list with the overloaded functions
+ overloads = getattr(self.decl_handles[0], "overloads", None)
+ if overloads==None:
+ return False
+
+ # Check if the decls are all contained in overloads...
+ for decl in self.decl_handles[1:]:
+ if decl not in overloads:
+ return False
+
+ return True
+
def _parseDefArgs(self, args):
"""Determine which of the args is the doc string, call policies and keywords argument.
***************
*** 584,587 ****
--- 654,693 ----
yield node
+ # _sourceInfo
+ def _sourceInfo(self):
+ """Determine where in the user's source code this instance was created.
+
+ Returns a tuple (filename, funcname, linenr, sourceline) that
+ describes the source code line that created this instance.
+ funcname is None if the source code is not located inside a function.
+
+ @returns: (filename, funcname, linenr, sourceline)
+ @rtype: 4-tuple
+ """
+ frame = inspect.currentframe()
+ try:
+ records = inspect.getouterframes(frame)
+ # Determine the directory where this source file is located
+ apidir = os.path.dirname(records[0][1])
+ for rec in records[1:]:
+ file = rec[1]
+ dir = os.path.dirname(file)
+ # Return the first record that is not within the API directory
+ # (this must then be code from the user)
+ if dir!=apidir:
+ linenr = rec[2]
+ funcname = rec[3]
+ srcindex = rec[5]
+ sourceline = rec[4][srcindex]
+ sourceline = sourceline.strip()
+ if funcname=="?":
+ funcname = None
+ return file,funcname,linenr,sourceline
+ finally:
+ del frame
+
+ # We should never get here...
+ return "?", None, 0, "?"
+
# This value is used to determine if a declaration was already visited or not
|