summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild-aux/stack.c.gen57
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]: