From 1cfdd03032d7c308d35901b73155835b1100e69e Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Sat, 11 Jul 2026 13:53:32 +0200 Subject: [PATCH] Attribute multiply-declared public symbols to their umbrella header A MEOS public symbol may be declared both in its public umbrella meos_.h header (the surface MobilityDB installs and a binding includes) and in a family-internal implementation header; cbuffer, pose, rgeo and h3 all do this. The parser deduplicated by keeping the first declaration seen in the amalgamation, which follows header sort order, so 18 public symbols (15 in meos_h3.h, 3 in meos_internal_geo.h) were attributed to an internal header instead of their umbrella. A binding that keys on the installed public headers then silently dropped them. Deduplicate by preferring the declaration in a top-level meos*.h umbrella header over an internal one, independent of amalgamation order, so every umbrella-exposed function is attributed to the header it is published through. Function count is unchanged (4545); only the file attribution of the 18 symbols is corrected. --- parser/parser.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/parser/parser.py b/parser/parser.py index b16dfc2..6cae814 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -176,15 +176,28 @@ def parse_meos(entry: Path, include_dir: Path) -> dict: enums.append(extract_enum(node)) - # Deduplicate by name (keep first occurrence) + # Deduplicate by name. A public symbol may be declared in more than one + # header — its public umbrella ``meos_.h`` AND a family-internal + # implementation header (cbuffer, pose, rgeo and h3 all do this). Each symbol + # is attributed to the PUBLIC umbrella header MobilityDB installs + # (meos/CMakeLists.txt) — the surface a binding ``#include``s — independent of + # amalgamation/sort order, so a binding keying on the umbrella never drops a + # function that also appears in an internal header. The top-level ``meos*.h`` + # in ``include_dir`` are that installed public set; subdir headers are internal. + public_headers = {p.name for p in include_dir.glob("meos*.h")} + def _dedup(items: list) -> list: - seen: set[str] = set() - result = [] + by_name: dict[str, dict] = {} + order: list[str] = [] for item in items: - if item["name"] not in seen: - seen.add(item["name"]) - result.append(item) - return result + name = item["name"] + if name not in by_name: + by_name[name] = item + order.append(name) + elif (item.get("file") in public_headers + and by_name[name].get("file") not in public_headers): + by_name[name] = item + return [by_name[name] for name in order] functions = _dedup(functions) structs = _dedup(structs)