diff options
-rwxr-xr-x | build-aux/stack.c.gen | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen index bdac124..e7a647a 100755 --- a/build-aux/stack.c.gen +++ b/build-aux/stack.c.gen @@ -398,30 +398,49 @@ class PluginApplication: class LibObjPlugin: - objcalls: dict[str, set[str]] + objcalls: dict[str, set[str]] # method_name => {method_impls} def __init__(self, arg_c_fnames: typing.Collection[str]) -> None: - objcalls: dict[str, set[str]] = {} - re_vtable_start = re.compile(r"_vtable\s*=\s*\{") - re_vtable_entry = re.compile(r"^\s+\.(?P<meth>\S+)\s*=\s*(?P<impl>\S+),.*") + ifaces: dict[str, set[str]] = {} # iface_name => {method_names} + re_comment = re.compile(r"/\*.*?\*/") + re_ws = re.compile(r"\s+") + re_lo_iface = re.compile(r"^\s*#\s*define\s+(?P<name>\S+)_LO_IFACE") + re_lo_func = re.compile(r"LO_FUNC *\([^,]*, *(?P<name>[^,) ]+) *[,)]") + for fname in arg_c_fnames: + with open(fname, "r") as fh: + while line := fh.readline(): + if m := re_lo_iface.match(line): + iface_name = m.group("name") + if iface_name not in ifaces: + ifaces[iface_name] = set() + while line.endswith("\\\n"): + line += fh.readline() + line = line.replace("\\\n", " ") + line = re_comment.sub(" ", line) + line = re_ws.sub(" ", line) + for m2 in re_lo_func.finditer(line): + ifaces[iface_name].add(m2.group("name")) + + implementations: dict[str, set[str]] = {} # iface_name => {impl_names} + for iface_name in ifaces: + implementations[iface_name] = set() + re_lo_implementation = re.compile( + r"^LO_IMPLEMENTATION_[HC]\s*\(\s*(?P<iface>[^, ]+)\s*,\s*(?P<impl_typ>[^,]+)\s*,\s*(?P<impl_name>[^, ]+)\s*[,)].*" + ) for fname in arg_c_fnames: with open(fname, "r") as fh: - in_vtable = False for line in fh: - line = line.rstrip() - if in_vtable: - if m := re_vtable_entry.fullmatch(line): - meth = m.group("meth") - impl = m.group("impl") - if impl == "NULL": - continue - if m.group("meth") not in objcalls: - objcalls[meth] = set() - objcalls[meth].add(impl) - if "}" in line: - in_vtable = False - elif re_vtable_start.search(line): - in_vtable = True + line = line.strip() + if m := re_lo_implementation.match(line): + implementations[m.group("iface")].add(m.group("impl_name")) + + objcalls: dict[str, set[str]] = {} # method_name => {method_impls} + for iface_name in ifaces: + for method_name in ifaces[iface_name]: + if method_name not in objcalls: + objcalls[method_name] = set() + for impl_name in implementations[iface_name]: + objcalls[method_name].add(impl_name + "_" + method_name) self.objcalls = objcalls def extra_nodes(self) -> typing.Collection[Node]: |