add support for parsing typedefs
MODIFY
gen_rust.py
gen_rust.py
@@ -662,7 +662,13 @@ class GeneralInfo:
returns: (fullname, namespace, classpath, classname, name)
fullname clean of prefix like "const, class, ..."
"""
- name = name.replace("const ", "").replace("struct ", "").replace("class ", "").replace(".", "::")
+ name = name \
+ .replace("const ", "") \
+ .replace("struct ", "") \
+ .replace("class ", "") \
+ .replace("typedef ", "") \
+ .replace("callback ", "") \
+ .replace(".", "::")
space_name, local_name = split_known_namespace(name, namespaces)
pieces = local_name.split("::")
if len(pieces) > 2: # <class>.<class>.<class>.<name>
@@ -760,6 +766,12 @@ class FuncInfo(GeneralInfo):
}
def __init__(self, gen, module, decl, namespaces=frozenset()): # [ funcname, return_ctype, [modifiers], [args] ]
+ """
+ :type gen: RustWrapperGenerator
+ :type module: str
+ :type decl: list
+ :type namespaces: frozenset
+ """
GeneralInfo.__init__(self, gen, decl[0], namespaces)
self.module = module
@@ -1084,6 +1096,12 @@ class ClassPropInfo:
class ClassInfo(GeneralInfo):
def __init__(self, gen, module, decl, namespaces): # [ 'class/struct cname', ': base', [modlist] ]
+ """
+ :type gen: RustWrapperGenerator
+ :type module: str
+ :type decl: list
+ :type namespaces: frozenset
+ """
GeneralInfo.__init__(self, gen, decl[0], namespaces)
self.methods = [] # type: list[FuncInfo]
self.namespaces = namespaces
@@ -1208,6 +1226,11 @@ class ConstInfo(GeneralInfo):
}
def __init__(self, gen, decl, namespaces):
+ """
+ :type gen: RustWrapperGenerator
+ :type decl: list
+ :type namespaces: frozenset
+ """
GeneralInfo.__init__(self, gen, decl[0], namespaces)
_, self.rustname = split_known_namespace(self.fullname, namespaces)
self.rustname = self.rustname.replace("::", "_")
@@ -1264,6 +1287,37 @@ class ConstInfo(GeneralInfo):
return ConstInfo.TEMPLATES["cpp_int"].substitute(name=self.rustname, full_name=self.fullname)
+class TypedefInfo(GeneralInfo):
+ def __init__(self, gen, decl, namespaces):
+ """
+ :type gen: RustWrapperGenerator
+ :type decl: list
+ :type namespaces: frozenset
+ """
+ GeneralInfo.__init__(self, gen, decl[0], namespaces)
+ self.alias = decl[1]
+ self.comment = ""
+ if len(decl) > 5:
+ self.comment = decl[5].encode("ascii", "ignore")
+
+ def typ(self):
+ return self.gen.get_type_info(self.name)
+
+ def alias_typ(self):
+ return self.gen.get_type_info(self.alias)
+
+
+class CallbackInfo(GeneralInfo):
+ def __init__(self, gen, decl, namespaces):
+ """
+ :type gen: RustWrapperGenerator
+ :type decl: list
+ :type namespaces: frozenset
+ """
+ GeneralInfo.__init__(self, gen, decl[0], namespaces)
+ pass
+
+
class TypeInfo(object):
def __init__(self, gen, typeid):
"""
@@ -2142,6 +2196,10 @@ class RustWrapperGenerator(object):
return c
return None
+ def set_type_info(self, typeid, type_info):
+ typeid = typeid.strip()
+ self.type_infos[typeid] = type_info
+
def get_type_info(self, typeid):
"""
:type typeid: str
@@ -2172,6 +2230,10 @@ class RustWrapperGenerator(object):
ClassInfo(self, module, decl, frozenset(self.namespaces))
elif name.startswith("const"):
ConstInfo(self, decl, frozenset(self.namespaces))
+ elif name.startswith("typedef"):
+ TypedefInfo(self, decl, frozenset(self.namespaces))
+ elif name.startswith("callback"):
+ CallbackInfo(self, decl, frozenset(self.namespaces))
else:
FuncInfo(self, module, decl, frozenset(self.namespaces))

MODIFY
hdr_parser.py
hdr_parser.py
@@ -671,6 +671,28 @@ class CppHeaderParser(object):
n = "cv.Algorithm"
return n
+ def parse_typedef(self, decl_str, docstring=""):
+ # callback, e.g. typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata )
+ m = re.match(r"typedef\s+(.+?)\s*\(\s*.*\*\s*(\w+?)\s*\)\s*\(\s*(.+?)\s*\)\s*$", decl_str)
+ if m:
+ args = []
+ for x in (x.strip() for x in m.group(3).split(",")):
+ ma = re.match(r"\s*(.+)\s+(\w+)\s*$", x) # type with name, e.g. const void* a
+ if ma:
+ args.append([ma.group(1), ma.group(2)])
+ else:
+ ma = re.match(r"\s*(.+)\s*$", x) # type w/o name, e.g. const void*
+ if ma:
+ args.append([ma.group(1), ""])
+ else:
+ return None
+ return ["callback {}".format(self.get_dotted_name(m.group(2))), m.group(1), "", args, None, docstring]
+ # type alias, e.g. typedef Affine3<float> Affine3f
+ m = re.match(r"typedef\s+(.+)\s+(\w+)$", decl_str)
+ if m:
+ return ["typedef {}".format(self.get_dotted_name(m.group(2))), m.group(1), "", [], None, docstring]
+ return None
+
def parse_stmt(self, stmt, end_token, use_umat=False, docstring=""):
"""
parses the statement (ending with ';' or '}') or a block head (ending with '{')
@@ -759,8 +781,10 @@ class CppHeaderParser(object):
return "enum", "", False, decl
if end_token == ";" and stmt.startswith("typedef"):
- # TODO: handle typedef's more intelligently
+ decl = self.parse_typedef(stmt, docstring)
+ if decl is None:
return stmt_type, "", False, None
+ return "typedef", "", False, decl
paren_pos = stmt.find("(")
if paren_pos >= 0:

add support for parsing typedefs