1#!/usr/bin/env python3
2# Scan glib sources.
3#
4# meson _build
5# ninja -C _build
6# ./misc/update-glib-annotations.py <path-to-glib-git-checkout>
7
8import os
9import sys
10import subprocess
11
12
13SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
14SRC_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, ".."))
15
16
17def get_build_dir():
18    build_dir = os.path.join(SRC_DIR, "_build")
19    if not os.path.isdir(build_dir):
20        raise SystemExit(
21            "build dir not found: "
22            "build with meson in %r first" % build_dir)
23    return build_dir
24
25
26def get_tool_path():
27    build_dir = get_build_dir()
28    tool_path = os.path.join(build_dir, "tools", "g-ir-annotation-tool")
29    if not os.path.isfile(tool_path):
30        raise SystemExit(
31            "g-ir-annotation-tool not found: "
32            "build with meson in %r first" % build_dir)
33    return tool_path
34
35
36def extract_annotations(module_name, glib_srcdir, outfile):
37    sources = []
38
39    glib_subdir = os.path.join(glib_srcdir, module_name)
40    for sourcename in sorted(os.listdir(glib_subdir), reverse=True):
41        if sourcename.endswith('.c'):
42            sources.append(os.path.join(glib_subdir, sourcename))
43
44    env = os.environ.copy()
45    env['PYTHONPATH'] = os.path.join(get_build_dir(), 'giscanner')
46
47    tool_args = [sys.executable, get_tool_path(), '--extract'] + sources
48    return subprocess.check_call(tool_args, stdout=outfile, env=env)
49
50
51def update_module(module_name, glib_src_dir, target_path):
52    tmpname = target_path + '.tmp'
53
54    if os.path.isfile(tmpname):
55        os.unlink(tmpname)
56    with open(tmpname, 'wb') as target:
57        extract_annotations(module_name, glib_src_dir, target)
58    if os.path.isfile(target_path):
59        os.unlink(target_path)
60    os.rename(tmpname, target_path)
61
62    print("Updated '%s'" % (target_path, ))
63
64
65def main(argv):
66    if len(argv) != 2:
67        raise SystemExit("only pass the glib src dir")
68    glib_src_dir = argv[1]
69    if not os.path.exists(os.path.join(glib_src_dir, "glib.doap")):
70        raise SystemExit("%s isn't the glib source dir" % glib_src_dir)
71
72    print("Using source directory: '%s' build directory: '%s'" % (
73        glib_src_dir, get_build_dir()))
74
75    gir_dir = os.path.join(SRC_DIR, "gir")
76    modules = {
77        'glib': os.path.join(gir_dir, 'glib-2.0.c'),
78        'gmodule': os.path.join(gir_dir, 'gmodule-2.0.c'),
79        'gobject': os.path.join(gir_dir, 'gobject-2.0.c'),
80        'gio': os.path.join(gir_dir, 'gio-2.0.c'),
81    }
82
83    for module_name, target_path in modules.items():
84        update_module(module_name, glib_src_dir, target_path)
85
86    print("Done; run \"git diff\" to see any changes.")
87
88
89if __name__ == '__main__':
90    main(sys.argv)
91