]> Pileus Git - ~andy/gtk/blob - build/win32/gen-file-list-gtk.py
Visual Studio Builds: Support Building Introspection Files
[~andy/gtk] / build / win32 / gen-file-list-gtk.py
1 #!/usr/bin/python
2 # vim: encoding=utf-8
3 # Generate the file lists for processing with g-ir-scanner
4 import os
5 import sys
6 import re
7 import string
8 import subprocess
9 import optparse
10
11 def gen_gdk_filelist(srcroot, subdir, dest):
12     vars = read_vars_from_AM(os.path.join(srcroot, subdir, 'Makefile.am'),
13                              vars = {},
14                              conds = {},
15                              filters = ['gdk_public_h_sources', 'gdk_c_sources'])
16
17     vars['gdk_enums'] = 'gdkenumtypes.c gdkenumtypes.h'
18
19     files = vars['gdk_public_h_sources'].split() + \
20             vars['gdk_c_sources'].split() + \
21             vars['gdk_enums'].split()
22
23     sources = [i for i in files if (i != 'gdkkeysyms-compat.h')]
24
25     with open(dest, 'w') as d:
26         for i in sources:
27             d.write(srcroot + '\\' + subdir + '\\' + i.replace('/', '\\') + '\n')
28
29 def gen_filelist_gtk(srcroot, subdir, dest):
30     vars = read_vars_from_AM(os.path.join(srcroot, 'gtk', 'Makefile.am'),
31                              vars = {},
32                              conds = {'USE_WIN32':True},
33                              filters = ['gtkinclude_HEADERS',
34                                         'deprecatedinclude_HEADERS',
35                                         'gtk_base_c_sources'])
36
37     vars['gtk_other_src'] = 'gtkprintoperation-win32.c gtktypebuiltins.h gtktypebuiltins.c'
38
39     files = vars['gtkinclude_HEADERS'].split() + \
40             vars['deprecatedinclude_HEADERS'].split() + \
41             vars['gtk_base_c_sources'].split() + \
42             vars['gtk_other_src'].split()
43
44     sources = [i for i in files if not (i.endswith('private.h')) and i != 'gtktextdisplay.h' and i != 'gtktextlayout.h']
45
46     with open(dest, 'w') as d:
47         for i in sources:
48             d.write(srcroot + '\\' + subdir + '\\' + i.replace('/', '\\') + '\n')
49
50 def read_vars_from_AM(path, vars = {}, conds = {}, filters = None):
51     '''
52     path: path to the Makefile.am
53     vars: predefined variables
54     conds: condition variables for Makefile
55     filters: if None, all variables defined are returned,
56              otherwise, it is a list contains that variables should be returned
57     '''
58     cur_vars = vars.copy()
59     RE_AM_VAR_REF = re.compile(r'\$\((\w+?)\)')
60     RE_AM_VAR = re.compile(r'^\s*(\w+)\s*=(.*)$')
61     RE_AM_INCLUDE = re.compile(r'^\s*include\s+(\w+)')
62     RE_AM_CONTINUING = re.compile(r'\\\s*$')
63     RE_AM_IF = re.compile(r'^\s*if\s+(\w+)')
64     RE_AM_ELSE = re.compile(r'^\s*else')
65     RE_AM_ENDIF = re.compile(r'^\s*endif')
66     def am_eval(cont):
67         return RE_AM_VAR_REF.sub(lambda x: cur_vars.get(x.group(1), ''), cont)
68     with open(path, 'r') as f:
69         contents = f.readlines()
70     #combine continuing lines
71     i = 0
72     ncont = []
73     while i < len(contents):
74         line = contents[i]
75         if RE_AM_CONTINUING.search(line):
76             line = RE_AM_CONTINUING.sub('', line)
77             j = i + 1
78             while j < len(contents) and RE_AM_CONTINUING.search(contents[j]):
79                 line += RE_AM_CONTINUING.sub('', contents[j])
80                 j += 1
81             else:
82                 if j < len(contents):
83                     line += contents[j]
84             i = j
85         else:
86             i += 1
87         ncont.append(line)
88
89     #include, var define, var evaluation
90     i = -1
91     skip = False
92     oldskip = []
93     while i < len(ncont) - 1:
94         i += 1
95         line = ncont[i]
96         mo = RE_AM_IF.search(line)
97         if mo:
98             oldskip.append(skip)
99             skip = False if mo.group(1) in conds and conds[mo.group(1)] \
100                          else True
101             continue
102         mo = RE_AM_ELSE.search(line)
103         if mo:
104             skip = not skip
105             continue
106         mo = RE_AM_ENDIF.search(line)
107         if mo:
108             if oldskip:
109                 skip = oldskip.pop()
110             continue
111         if not skip:
112             mo = RE_AM_INCLUDE.search(line)
113             if mo:
114                 cur_vars.update(read_vars_from_AM(am_eval(mo.group(1)), cur_vars, conds, None))
115                 continue
116             mo = RE_AM_VAR.search(line)
117             if mo:
118                 cur_vars[mo.group(1)] = am_eval(mo.group(2).strip())
119                 continue
120
121     #filter:
122     if filters != None:
123         ret = {}
124         for i in filters:
125             ret[i] = cur_vars.get(i, '')
126         return ret
127     else:
128         return cur_vars
129
130 def main(argv):
131     srcroot = '..\\..'
132     subdir_gdk = 'gdk'
133     subdir_gtk = 'gtk'
134
135     gen_gdk_filelist(srcroot, subdir_gdk, 'gdk_list')
136     gen_filelist_gtk(srcroot, subdir_gtk, 'gtk_list')
137     return 0
138
139 if __name__ == '__main__':
140     sys.exit(main(sys.argv))