xref: /openbsd-src/gnu/llvm/libcxx/utils/generate_iwyu_mapping.py (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1*4bdff4beSrobert#!/usr/bin/env python
2*4bdff4beSrobert
3*4bdff4beSrobertimport os, pathlib, sys
4*4bdff4beSrobert
5*4bdff4beSrobertdef generate(private, public):
6*4bdff4beSrobert    return f'{{ include: [ "{private}", "private", "<{public}>", "public" ] }}'
7*4bdff4beSrobert
8*4bdff4beSrobert
9*4bdff4beSrobertdef panic(file):
10*4bdff4beSrobert    print(f'========== {__file__} error ==========', file=sys.stderr)
11*4bdff4beSrobert    print(f'\tFile \'{file}\' is a top-level detail header without a mapping', file=sys.stderr)
12*4bdff4beSrobert    sys.exit(1)
13*4bdff4beSrobert
14*4bdff4beSrobert
15*4bdff4beSrobertdef generate_map(include):
16*4bdff4beSrobert    detail_files = []
17*4bdff4beSrobert    detail_directories = []
18*4bdff4beSrobert    c_headers = []
19*4bdff4beSrobert
20*4bdff4beSrobert    for i in include.iterdir():
21*4bdff4beSrobert        if i.is_dir() and i.name.startswith('__'):
22*4bdff4beSrobert            detail_directories.append(f'{i.name}')
23*4bdff4beSrobert            continue
24*4bdff4beSrobert
25*4bdff4beSrobert        if i.name.startswith('__'):
26*4bdff4beSrobert            detail_files.append(i.name)
27*4bdff4beSrobert            continue
28*4bdff4beSrobert
29*4bdff4beSrobert        if i.name.endswith('.h'):
30*4bdff4beSrobert            c_headers.append(i.name)
31*4bdff4beSrobert
32*4bdff4beSrobert    result = []
33*4bdff4beSrobert    temporary_mappings = {'__tuple_dir': 'tuple'}
34*4bdff4beSrobert    for i in detail_directories:
35*4bdff4beSrobert        public_header = temporary_mappings.get(i, i.lstrip('_'))
36*4bdff4beSrobert        result.append(f'{generate(f"@<{i}/.*>", public_header)},')
37*4bdff4beSrobert
38*4bdff4beSrobert    for i in detail_files:
39*4bdff4beSrobert        public = []
40*4bdff4beSrobert        if   i == '__assert': continue
41*4bdff4beSrobert        elif i == '__availability': continue
42*4bdff4beSrobert        elif i == '__bit_reference': continue
43*4bdff4beSrobert        elif i == '__bits': public = ['bits']
44*4bdff4beSrobert        elif i == '__bsd_locale_defaults.h': continue
45*4bdff4beSrobert        elif i == '__bsd_locale_fallbacks.h': continue
46*4bdff4beSrobert        elif i == '__config_site.in': continue
47*4bdff4beSrobert        elif i == '__config': continue
48*4bdff4beSrobert        elif i == '__debug': continue
49*4bdff4beSrobert        elif i == '__errc': continue
50*4bdff4beSrobert        elif i == '__hash_table': public = ['unordered_map', 'unordered_set']
51*4bdff4beSrobert        elif i == '__locale': public = ['locale']
52*4bdff4beSrobert        elif i == '__mbstate_t.h': continue
53*4bdff4beSrobert        elif i == '__mutex_base': continue
54*4bdff4beSrobert        elif i == '__node_handle': public = ['map', 'set', 'unordered_map', 'unordered_set']
55*4bdff4beSrobert        elif i == '__split_buffer': public = ['deque', 'vector']
56*4bdff4beSrobert        elif i == '__std_stream': public = ['iostream']
57*4bdff4beSrobert        elif i == '__threading_support': public = ['atomic', 'mutex', 'semaphore', 'thread']
58*4bdff4beSrobert        elif i == '__tree': public = ['map', 'set']
59*4bdff4beSrobert        elif i == '__undef_macros': continue
60*4bdff4beSrobert        elif i == '__verbose_abort': continue
61*4bdff4beSrobert        else: panic()
62*4bdff4beSrobert
63*4bdff4beSrobert        for p in public:
64*4bdff4beSrobert            result.append(f'{generate(f"<{i}>", p)},')
65*4bdff4beSrobert
66*4bdff4beSrobert    result.sort()
67*4bdff4beSrobert    return result
68*4bdff4beSrobert
69*4bdff4beSrobertdef main():
70*4bdff4beSrobert    monorepo_root = pathlib.Path(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
71*4bdff4beSrobert    assert(monorepo_root.exists())
72*4bdff4beSrobert    include = pathlib.Path(os.path.join(monorepo_root, 'libcxx', 'include'))
73*4bdff4beSrobert
74*4bdff4beSrobert    mapping = generate_map(include)
75*4bdff4beSrobert    data = '[\n  ' + '\n  '.join(mapping) + '\n]\n'
76*4bdff4beSrobert    with open(f'{include}/libcxx.imp', 'w') as f:
77*4bdff4beSrobert        f.write(data)
78*4bdff4beSrobert
79*4bdff4beSrobert
80*4bdff4beSrobertif __name__ == '__main__':
81*4bdff4beSrobert    main()
82