import sys
import re

#from ctypeslib.codegen.gccxmlparser import parse
from gccxmlparser import parse
from ctypeslib.codegen import typedesc
from codegenlib import Func, parse_type

def query_items(xml, filter=None):
    # XXX: support filter
    xml_items = parse(xml)
    #items = {}
    keep = set()
    named = {}
    locations = {}
    for it in xml_items:
        #items[it] = it
        keep.add(it)

        if hasattr(it, 'name'):
            named[it] = it.name

        if hasattr(it, 'location'):
            locations[it] = it.location

    return keep, named, locations

def classify(items, locations):
    # Dictionaries name -> typedesc instances
    funcs = {}
    tpdefs = {}
    enumvals = {}
    enums = {}
    structs = {}
    vars = {}

    for it in items:
        try:
            origin = locations[it][0]
            if header_matcher.search(origin):
                if isinstance(it, typedesc.Function):
                    funcs[it.name] = it
                elif isinstance(it, typedesc.EnumValue):
                    enumvals[it.name] = it
                elif isinstance(it, typedesc.Enumeration):
                    enums[it.name] = it
                elif isinstance(it, typedesc.Typedef):
                    tpdefs[it.name] = it
                elif isinstance(it, typedesc.Structure):
                    structs[it.name] = it
                elif isinstance(it, typedesc.Variable):
                    vars[it.name] = it
                else:
                    print "Do not itnow how to handle", str(it)
        except KeyError:
            print "No location for item %s, ignoring" % str(it)

    return funcs, tpdefs, enumvals, enums, structs, vars

def find_named_type(tp):
    if hasattr(tp, 'name'):
        return tp.name
    elif isinstance(tp, typedesc.CvQualifiedType) or \
         isinstance(tp, typedesc.PointerType):
        return find_named_type(tp.typ)
    elif isinstance(tp, typedesc.FunctionType):
        return None
    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.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 signature_types(func):
    types = []
    for a in func.iterArgTypes():
        #namedtype = find_named_type(a)
        #if namedtype:
        #    types.append(namedtype)
        types.append(a)

    return types

def funcs_dependencies(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:
        types = signature_types(f)
        for t in types:
            ut = find_unqualified_type(t)
            if ut in items:
                arguments.add(ut)

    return arguments

root = 'foo'
header_name = '%s.h' % root
header_matcher = re.compile(header_name)
xml_name = '%s.xml' % root
if sys.platform[:7] == 'darwin':
    so_name = root
else:
    so_name = 'lib%s.so' % root

items, named, locations = query_items(xml_name)
funcs, tpdefs, enumvals, enums, structs, vars = classify(items, locations)

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

@@ -2539,234 +2539,13 @@
 ture
+s
 _typ
-es(func):%0A    types = %5B%5D%0A    for a in func.iterArgTypes():%0A        #namedtype = find_named_type(a)%0A        #if namedtype:%0A        #    types.append(namedtype)%0A        types.append(a)%0A%0A    return types%0A%0Adef funcs_dependenci
 es(f
@@ -2733,43 +2733,8 @@
 cs:%0A
-        types = signature_types(f)%0A
     
@@ -2746,21 +2746,32 @@
 or t in 
-t
+f.iterArgT
 ypes
+()
 :%0A      
@@ -3231,24 +3231,22 @@
 s = 
-funcs_dependenci
+signatures_typ
 es(f

Simplify code for pulling out function signatures types + rename the main function.