Skip to content

Commit

Permalink
Put TypePuller in its own module.
Browse files Browse the repository at this point in the history
  • Loading branch information
cournape committed Dec 1, 2008
1 parent 4b48916 commit c8a5771
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 186 deletions.
190 changes: 4 additions & 186 deletions cycodegen.py
@@ -1,13 +1,13 @@
import sys
import re
import copy

#from ctypeslib.codegen.gccxmlparser import parse
from gccxmlparser import parse
from ctypeslib.codegen import typedesc
from codegenlib import Func, parse_type
from funcs import generic_as_arg
from cytypes import generic_decl, generic_named_decl
from tp_puller import TypePuller

def query_items(xml, filter=None):
# XXX: support filter
Expand Down Expand Up @@ -80,188 +80,6 @@ def find_named_type(tp):
else:
raise ValueError("Unhandled type %s" % str(tp))

def find_unqualified_type(tp):
if isinstance(tp, typedesc.FundamentalType) or \
isinstance(tp, typedesc.Structure) or \
isinstance(tp, typedesc.Union) or \
isinstance(tp, typedesc.Enumeration) or \
isinstance(tp, typedesc.Typedef):
return tp
elif isinstance(tp, typedesc.CvQualifiedType) or \
isinstance(tp, typedesc.PointerType):
return find_unqualified_type(tp.typ)
elif isinstance(tp, typedesc.FunctionType):
return None
else:
raise ValueError("Unhandled type %s" % str(tp))

def signatures_types(funcs):
"""Given a sequence of typedesc.Function instances, generate a set of all
typedesc instances used in function declarations."""
arguments = set()

for f in funcs:
for t in f.iterArgTypes():
ut = find_unqualified_type(t)
if ut in items:
arguments.add(ut)
ut = find_unqualified_type(f.returns)
if ut in items:
arguments.add(ut)

return arguments

class TypePuller:
def __init__(self, all):
self._items = []
#self._all = sorted(all, cmpitems)
self._all = all
self._done = set()

# This list contains a list of struct names for which the puller will
# not pull the members. This is an hack to avoid some cycle in
# recursives structs declarations which refer one to each other.
self._STRUCTS_IGNORE = ['_IO_FILE', '_IO_marker', 'yoyo11', 'yoyo12']

def pull_fundamental(self, item):
pass

def pull_cv_qualified_type(self, item):
self.pull(item.typ)
#names.add(item.name)
self._items.append(item)

def pull_typedef(self, item):
# XXX: Generate the typdef itself
if not item in self._done:
self._done.add(item)
self.pull(item.typ)
#names.add(item.name)
self._items.append(item)

def pull_function(self, item):
# XXX: fix signatures_type for single item
types = signatures_types([item])
#names.append(item.name)
for t in types:
ut = find_unqualified_type(t)
if ut in self._all:
self.pull(ut)
self._items.append(item)

def pull_function_type(self, item):
# XXX: fix signatures_type for single item
types = signatures_types([item])
#self._items.append(item)
for t in types:
ut = find_unqualified_type(t)
if ut in self._all:
self.pull(ut)

def pull_structure(self, item):
#names.append(item.name)
if not item in self._done:
self._done.add(item)
if item.name in self._STRUCTS_IGNORE:
# XXX: hack. We remove all members of the ignored structures,
# to generate an opaque structure in the code genrator.
print "Ignoring", item, item.name
item.members = []
else:
for m in item.members:
if isinstance(m, typedesc.Field):
f = m.typ
# XXX: ugly hack. Cython does not support structures
# with members refering to itself through a typedef, so
# we "untypedef" the member if we detect such a case
if isinstance(f, typedesc.PointerType) \
and isinstance(f.typ, typedesc.Typedef) \
and isinstance(f.typ.typ, typedesc.Structure) \
and f.typ.typ == item:
newf = copy.deepcopy(f)
newf.typ = newf.typ.typ
m.typ = newf
self.pull(m)
self._items.append(item)

def pull_union(self, item):
#names.append(item.name)
for m in item.members:
g = self.pull(m)
if g:
self._items.append(pull(m))
self._items.append(item)

def pull_array_type(self, item):
#names.append(item.name)
self.pull(item.typ)
self._items.append(item)

def pull_enumeration(self, item):
#names.append(item.name)
for v in item.values:
self.pull(v)
self._items.append(item)

def pull_enum_value(self, item):
#names.append(item.name)
self._items.append(item)

def pull(self, item):
if isinstance(item, typedesc.FundamentalType):
#print "Fund Pulling", item, item.name
self.pull_fundamental(item)
return
elif isinstance(item, typedesc.Enumeration):
#print "Enumeration Pulling", item, item.name
self.pull_enumeration(item)
return
elif isinstance(item, typedesc.EnumValue):
#print "Enumeration Pulling", item, item.name
self.pull_enum_value(item)
return
elif isinstance(item, typedesc.Typedef):
#print "Typedef Pulling", item, item.name
self.pull_typedef(item)
return
elif isinstance(item, typedesc.Structure):
#print "Struct Pulling", item, item.name
self.pull_structure(item)
return
elif isinstance(item, typedesc.Union):
#print "FunctionType Pulling", item
self.pull_union(item)
return
elif isinstance(item, typedesc.Function):
#print "Func Pulling", item
self.pull_function(item)
return
elif isinstance(item, typedesc.Field):
#print "Field Pulling", item
self.pull(item.typ)
return
elif isinstance(item, typedesc.PointerType):
#print "Pointer Pulling", item
self.pull(item.typ)
return
elif isinstance(item, typedesc.FunctionType):
#print "FunctionType Pulling", item
self.pull_function_type(item)
return
elif isinstance(item, typedesc.CvQualifiedType):
#print "FunctionType Pulling", item
self.pull_cv_qualified_type(item)
return
elif isinstance(item, typedesc.ArrayType):
#print "FunctionType Pulling", item
self.pull_array_type(item)
return
else:
raise ValueError, ("item not handled:", item)

def values(self):
return self._items

def instance_puller(tp, all):
p = TypePuller(all)
p.pull(tp)
Expand Down Expand Up @@ -384,12 +202,12 @@ def cy_generate(item):
funcs, tpdefs, enumvals, enums, structs, vars, unions = \
classify(items, locations, ifilter=header_matcher.search)

arguments = signatures_types(funcs.values())
#arguments = signatures_types(funcs.values())
#print "Need to pull out arguments", [named[i] for i in arguments]

puller = TypePuller(items)
for a in arguments:
puller.pull(a)
for f in funcs.values():
puller.pull(f)

needed = puller.values()
#print "Pulled out items:", [named[i] for i in needed]
Expand Down
15 changes: 15 additions & 0 deletions funcs.py
Expand Up @@ -41,3 +41,18 @@ def generic_as_arg(tp):
else:
print "Argument not handled in generic_as_arg", tp
return None

def find_unqualified_type(tp):
if isinstance(tp, typedesc.FundamentalType) or \
isinstance(tp, typedesc.Structure) or \
isinstance(tp, typedesc.Union) or \
isinstance(tp, typedesc.Enumeration) or \
isinstance(tp, typedesc.Typedef):
return tp
elif isinstance(tp, typedesc.CvQualifiedType) or \
isinstance(tp, typedesc.PointerType):
return find_unqualified_type(tp.typ)
elif isinstance(tp, typedesc.FunctionType):
return None
else:
raise ValueError("Unhandled type %s" % str(tp))

0 comments on commit c8a5771

Please sign in to comment.