"""Shared helpers for the HALCON runner scripts.""" import re _INT_RE = re.compile(r"^[+-]?\d+$") _FLOAT_RE = re.compile(r"^[+-]?(\d+\.\d*|\.\d+|\d+)([eE][+-]?\d+)?$") def coerce(value: str): """Turn a CLI string into int/float/str, or a list for comma-separated input. Absolute paths (C:/..., /mnt/...) and anything non-numeric stay strings. Use a trailing comma or commas to force a tuple, e.g. '1,2,3' -> [1,2,3]. """ if "," in value: return [coerce(v) for v in value.split(",") if v != ""] if _INT_RE.match(value): return int(value) if _FLOAT_RE.match(value) and not value.strip().startswith(("C:", "c:")): return float(value) return value def jsonable(v): """Make a HALCON output control value JSON-serializable.""" if isinstance(v, (list, tuple)): return [jsonable(x) for x in v] if isinstance(v, (int, float, str, bool)) or v is None: return v return str(v) def parse_set(pairs): """['Name=Value', ...] -> [(name, coerced_value), ...].""" out = [] for p in pairs or []: if "=" not in p: raise SystemExit(f"--set expects Name=Value, got: {p!r}") name, _, raw = p.partition("=") out.append((name.strip(), coerce(raw))) return out