makealias.py revision a4e54154
1#!/usr/bin/env python3
2
3import os
4import re
5import sys
6import argparse
7from collections import OrderedDict
8
9# cat fontconfig/fontconfig.h | grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$//'
10
11def extract(fname):
12    with open(fname, 'r', encoding='utf-8') as f:
13        for l in f.readlines():
14            l = l.rstrip()
15            m = re.match(r'^(Fc[^ ]*)[\s\w]*\(.*', l)
16
17            if m and m.group(1) not in ['FcCacheDir', 'FcCacheSubdir']:
18                yield m.group(1)
19
20if __name__=='__main__':
21    parser = argparse.ArgumentParser()
22    parser.add_argument('srcdir')
23    parser.add_argument('head')
24    parser.add_argument('tail')
25    parser.add_argument('headers', nargs='+')
26
27    args = parser.parse_args()
28
29    definitions = {}
30
31    for fname in os.listdir(args.srcdir):
32        define_name, ext = os.path.splitext(fname)
33        if ext != '.c':
34            continue
35
36        define_name = '__%s__' % os.path.basename(define_name)
37
38        for definition in extract(os.path.join(args.srcdir, fname)):
39            definitions[definition] = define_name
40
41    declarations = OrderedDict()
42
43    for fname in args.headers:
44        for declaration in extract(fname):
45            try:
46                define_name = definitions[declaration]
47            except KeyError:
48                print ('error: could not locate %s in src/*.c' % declaration)
49                sys.exit(1)
50
51            declarations[declaration] = define_name
52
53    with open(args.head, 'w') as head:
54        with open(args.tail, 'w') as tail:
55            tail.write('#if HAVE_GNUC_ATTRIBUTE\n')
56            last = None
57            for name, define_name in declarations.items():
58                alias = 'IA__%s' % name
59                hattr = 'FC_ATTRIBUTE_VISIBILITY_HIDDEN'
60                head.write('extern __typeof (%s) %s %s;\n' % (name, alias, hattr))
61                head.write('#define %s %s\n' % (name, alias))
62                if define_name != last:
63                    if last is not None:
64                        tail.write('#endif /* %s */\n' % last)
65                    tail.write('#ifdef %s\n' % define_name)
66                    last = define_name
67                tail.write('# undef %s\n' % name)
68                cattr = '__attribute((alias("%s"))) FC_ATTRIBUTE_VISIBILITY_EXPORT' % alias
69                tail.write('extern __typeof (%s) %s %s;\n' % (name, name, cattr))
70            tail.write('#endif /* %s */\n' % last)
71            tail.write('#endif /* HAVE_GNUC_ATTRIBUTE */\n')
72