summaryrefslogtreecommitdiff
path: root/build-aux/kicad-sym-extract
blob: e8d28dd0bd8a216421f468988513bf129b55602d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python3
# build-aux/kicad-sym-extract - Extract a single symbol from a KiCad symbol library
#
# Copyright (C) 2025  Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later

import os.path
import sys

common = os.path.abspath(os.path.dirname(__file__))
if common not in sys.path:
    sys.path.insert(0, common)

import kicad_sexpr  # pylint: disable=wrong-import-position


def get_extends(obj: kicad_sexpr.Expr) -> str | None:
    if not (
        isinstance(obj, list)
        and len(obj) > 1
        and obj[0] == kicad_sexpr.Symbol("symbol")
    ):
        return None
    for child in obj[1:]:
        if (
            isinstance(child, list)
            and len(child) == 2
            and child[0] == kicad_sexpr.Symbol("extends")
            and isinstance(child[1], str)
        ):
            return child[1]
    return None


def should_include(obj: kicad_sexpr.Expr, symnames: list[str]) -> bool:
    if (
        isinstance(obj, list)
        and len(obj) > 1
        and obj[0] == kicad_sexpr.Symbol("symbol")
    ):
        return obj[1] in symnames
    return True


def main(symnames: list[str]) -> None:
    old_sym_lib = kicad_sexpr.unmarshal(sys.stdin.read())
    assert isinstance(old_sym_lib, list)
    assert len(old_sym_lib) > 1
    assert old_sym_lib[0] == kicad_sexpr.Symbol("kicad_symbol_lib")

    while True:
        new_sym_lib = [
            member for member in old_sym_lib if should_include(member, symnames)
        ]
        again = False
        for member in new_sym_lib:
            extends = get_extends(member)
            if extends and extends not in symnames:
                symnames.append(extends)
                again = True
        if not again:
            print(kicad_sexpr.marshal(new_sym_lib))
            return


if __name__ == "__main__":
    main(sys.argv[1:])