3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
1 |
#!/usr/bin/python
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
2 |
import getopt, glob, os, sys, xml.dom.minidom |
3 |
||
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
4 |
### Constants ###
|
5 |
APPLICATION_TAG_NAME = 'application' |
|
6 |
APPLICATION_ATTR_NAME = 'name' |
|
7 |
APPLICATION_PATH_NAME = 'path' |
|
8 |
||
9 |
MODULES_DIR = 'modules' |
|
10 |
MODULE_INFO_FILE = 'module_info.xml' |
|
11 |
||
12 |
HEADER_FILE_DIR = MODULES_DIR |
|
13 |
HEADER_FILE_SUFFIX = '_modules.h' |
|
14 |
||
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
15 |
WARNING_STRING = 'WARNING This file was generated by ' + __file__ + ' - ' |
16 |
WARNING_STRING += 'DO NOT EDIT!' |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
17 |
|
18 |
# Parses the XML document at 'path' and returns a dictionary with module info
|
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
19 |
def parse_xml_info(path): |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
20 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
21 |
file = open(path, "r") |
22 |
dom = xml.dom.minidom.parse(file) |
|
23 |
file.close() |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
24 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
25 |
module_info = {} |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
26 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
27 |
module_name = str(dom.getElementsByTagName('module')[0].attributes['name'].value) |
28 |
module_info['version'] = str(dom.getElementsByTagName('module')[0].attributes['version'].value) |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
29 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
30 |
module_info['requires'] = [] |
31 |
if 0 < len(dom.getElementsByTagName('requires')): |
|
32 |
for node in dom.getElementsByTagName('requires')[0].getElementsByTagName('module'): |
|
33 |
current_req = {} |
|
34 |
current_req['name'] = str(node.attributes['name'].value) |
|
35 |
if 'minversion' in node.attributes.keys(): |
|
36 |
current_req['minversion'] = str(node.attributes['minversion'].value) |
|
37 |
if 'maxversion' in node.attributes.keys(): |
|
38 |
current_req['maxversion'] = str(node.attributes['maxversion'].value) |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
39 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
40 |
module_info['requires'].append(current_req) |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
41 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
42 |
module_info['conflicts'] = [] |
43 |
if 0 < len(dom.getElementsByTagName('conflicts')): |
|
44 |
for node in dom.getElementsByTagName('conflicts')[0].getElementsByTagName('module'): |
|
45 |
current_con = {} |
|
46 |
current_con['name'] = str(node.attributes['name'].value) |
|
47 |
if 'minversion' in node.attributes.keys(): |
|
48 |
current_con['minversion'] = str(node.attributes['minversion'].value) |
|
49 |
if 'maxversion' in node.attributes.keys(): |
|
50 |
current_con['maxversion'] = str(node.attributes['maxversion'].value) |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
51 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
52 |
module_info['conflicts'].append(current_con) |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
53 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
54 |
module_info['application'] = {} |
55 |
if 0 == len(dom.getElementsByTagName('application')): |
|
56 |
print '|\n| WARNING in configuration of ' + module_name + ':', |
|
57 |
print 'no application tag found' |
|
58 |
print '| Please check configuration file' |
|
59 |
raise Error() |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
60 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
61 |
for current_app in dom.getElementsByTagName('application'): |
62 |
app_info = {} |
|
63 |
name = str(current_app.attributes['name'].value) |
|
64 |
app_info['header_file'] = str(current_app.attributes['header_file'].value) |
|
65 |
app_info['init_function'] = str(current_app.attributes['init_function'].value) |
|
66 |
module_info['application'][name] = app_info |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
67 |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
68 |
return (module_name, module_info) |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
69 |
|
70 |
# Tries to read the XML configuration files for all sub-folders in the given
|
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
71 |
# directory and returns a dictionary containing the module information
|
3486.1.254
by Tim Just
Removed project_info.xml and added some missing files to EXTRA_DIST. |
72 |
def read_module_info(MODULES_DIR, disabled_modules): |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
73 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
74 |
# Initialize output variable
|
75 |
module_info = {} |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
76 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
77 |
# Iterate through all sub directories in MODULES_DIR
|
78 |
for current_module in glob.glob(MODULES_DIR + '/*/'): |
|
79 |
cont = False |
|
3486.1.254
by Tim Just
Removed project_info.xml and added some missing files to EXTRA_DIST. |
80 |
print '| found module: ' + current_module |
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
81 |
# Check if current_module is disabled
|
82 |
for disabled in disabled_modules: |
|
83 |
if current_module == os.path.join(MODULES_DIR, disabled) + '/': |
|
84 |
cont = True |
|
3486.1.206
by Tim Just
Improved ouput of process_modules. |
85 |
print '| state: ' + 'DISABLED' |
3486.1.254
by Tim Just
Removed project_info.xml and added some missing files to EXTRA_DIST. |
86 |
print '| (ignoring this directory)\n|' |
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
87 |
if True == cont: |
88 |
continue
|
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
89 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
90 |
try: |
91 |
path = os.path.join(current_module, MODULE_INFO_FILE) |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
92 |
(module_name, info) = parse_xml_info(path) |
3486.1.206
by Tim Just
Improved ouput of process_modules. |
93 |
print '| state: ' + 'ENABLED' |
94 |
print '| version: ' + info['version'] + '\n|' |
|
3486.1.254
by Tim Just
Removed project_info.xml and added some missing files to EXTRA_DIST. |
95 |
module_info[module_name] = info |
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
96 |
except: |
97 |
print '|\n| WARNING parsing of module info file', |
|
98 |
print '\'' + path + '\' failed!' |
|
99 |
print '| ...ignoring this directory\n|' |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
100 |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
101 |
return (module_info) |
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
102 |
|
103 |
# Checks the module_info data structure for missing dependencies and conflicts
|
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
104 |
# between modules. Returns a
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
105 |
def check_dependencies(module_info): |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
106 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
107 |
for current_module in module_info.keys(): |
108 |
# Check for dependencies
|
|
109 |
for require in module_info[current_module]['requires']: |
|
110 |
if False == (require['name'] in module_info.keys()): |
|
111 |
print '|\n| ERROR ' + current_module, |
|
112 |
print 'requires module ' + require['name'] |
|
113 |
sys.exit('| ...abort current run. Please check module configuration\n|') |
|
114 |
else: |
|
115 |
req_version = module_info[require['name']]['version'] |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
116 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
117 |
if require.has_key('minversion') and req_version < require['minversion']: |
118 |
print '|\n| ERROR ' + current_module + ' requires module', |
|
119 |
print require['name'] + ' at least in version ' + require['minversion'] |
|
120 |
sys.exit('| ...abort current run. Please check module configuration\n|') |
|
121 |
if require.has_key('maxversion') and req_version > require['maxversion']: |
|
122 |
print '|\n| ERROR ' + current_module + ' requires module', |
|
123 |
print require['name'] + ' at most in version ' + require['maxversion'] |
|
124 |
sys.exit('| ...abort current run. Please check module configuration\n|') |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
125 |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
126 |
# Check for conflicts
|
127 |
for conflict in module_info[current_module]['conflicts']: |
|
128 |
if conflict['name'] in module_info.keys(): |
|
129 |
con_version = module_info[conflict['name']]['version'] |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
130 |
|
131 |
if False == ((conflict.has_key('minversion') and |
|
132 |
con_version < conflict['minversion']) or |
|
133 |
(conflict.has_key('maxversion') and |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
134 |
con_version > conflict['maxversion'])): |
135 |
print '| ERROR ' + current_module + ' conflicts with module ' + conflict['name'] + ' (version ' + con_version + ')' |
|
136 |
sys.exit('| ...abort current run. Please check module configuration\n|') |
|
137 |
||
138 |
# Creates a C header file with the given filename an the needed includes,
|
|
139 |
# the number of init functions per application and an array of function
|
|
140 |
# pointers for each application
|
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
141 |
def create_header_files(applications, module_info): |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
142 |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
143 |
if False == os.path.isdir(HEADER_FILE_DIR): |
144 |
os.mkdir(HEADER_FILE_DIR) |
|
3486.1.198
by Tim Just
Fixed bug in process_modules.py |
145 |
|
3486.1.254
by Tim Just
Removed project_info.xml and added some missing files to EXTRA_DIST. |
146 |
for current_app in applications: |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
147 |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
148 |
hdr_file_path = os.path.join(HEADER_FILE_DIR, |
149 |
current_app + HEADER_FILE_SUFFIX) |
|
3486.1.202
by Tim Just
process_modules.py now returns errors and these are handled by configure. |
150 |
|
151 |
try: |
|
152 |
hdr_file = open(hdr_file_path, 'w') |
|
153 |
try: |
|
3486.1.259
by Tim Just
Added warning to files generated by process_modules.py. |
154 |
app_string = 'HIP_MODULES_' + current_app.upper() + '_MODULES_H' |
155 |
hdr_file.write('/* ' + WARNING_STRING + ' */\n') |
|
3486.1.202
by Tim Just
process_modules.py now returns errors and these are handled by configure. |
156 |
hdr_file.write('#ifndef ' + app_string + '\n') |
157 |
hdr_file.write('#define ' + app_string + '\n') |
|
158 |
||
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
159 |
info_string = 'struct module_info ' + current_app |
160 |
info_string += '_modules[] = {' |
|
161 |
first_loop = True |
|
162 |
num_spaces = len(info_string) |
|
163 |
num_modules = 0 |
|
164 |
max_required_modules = 0 |
|
165 |
||
166 |
for current_module in module_info: |
|
167 |
if module_info[current_module]['application'].has_key(current_app): |
|
168 |
app_info = module_info[current_module]['application'][current_app] |
|
169 |
num_modules += 1 |
|
170 |
hdr_file.write('\n#include \"' + app_info['header_file'] + '\"') |
|
171 |
||
172 |
num_required_modules = len(module_info[current_module]['requires']) |
|
173 |
if num_required_modules > max_required_modules: |
|
174 |
max_required_modules = num_required_modules |
|
175 |
if first_loop != True: |
|
176 |
info_string += ',\n' |
|
177 |
for i in range(num_spaces): |
|
178 |
info_string += ' ' |
|
179 |
info_string += '{"' + current_module + '", ' |
|
180 |
info_string += str(num_required_modules) + ', ' |
|
181 |
||
182 |
first_loop_1 = True |
|
183 |
info_string += '{' |
|
184 |
for required_module in module_info[current_module]['requires']: |
|
185 |
if first_loop_1 != True: |
|
186 |
info_string += ', ' |
|
187 |
info_string += '"' + required_module['name'] + '"' |
|
188 |
first_loop_1 = False |
|
189 |
info_string += '}' |
|
190 |
info_string += ', &' + app_info['init_function'] + '}' |
|
191 |
first_loop = False |
|
192 |
||
193 |
info_string += '};' |
|
194 |
||
195 |
info_struct = '\n\n#define MAX_REQUIRED_MODULES ' |
|
196 |
info_struct += str(max_required_modules) |
|
197 |
info_struct += '\n\nstruct module_info {\n' |
|
198 |
info_struct += ' const char *name;\n' |
|
199 |
info_struct += ' const int num_required_moduels;\n' |
|
200 |
info_struct += ' const char *required_modules_hipd[' |
|
201 |
info_struct += 'MAX_REQUIRED_MODULES];\n' |
|
202 |
info_struct += ' int (*init_function)(void);\n' |
|
203 |
info_struct += '};\n\n' |
|
204 |
hdr_file.write(info_struct) |
|
205 |
hdr_file.write('/* Number of modules - determined during build process. */') |
|
206 |
hdr_file.write('\nconst int ' + current_app + '_num_modules') |
|
207 |
hdr_file.write(' = ' + str(num_modules) + ';\n\n') |
|
208 |
||
209 |
hdr_file.write(info_string) |
|
3486.1.202
by Tim Just
process_modules.py now returns errors and these are handled by configure. |
210 |
|
3486.1.241
by Tim Just
Uses commas instead of spaces for separation of modules. |
211 |
hdr_file.write('\n\n#endif /* ' + app_string + ' */\n') |
3486.1.202
by Tim Just
process_modules.py now returns errors and these are handled by configure. |
212 |
print '| created file: ' + hdr_file_path |
213 |
finally: |
|
214 |
hdr_file.close() |
|
215 |
except IOError: |
|
216 |
sys.exit('Error on creating header files') |
|
3486.1.23
by Tim Just
Applied modularization concept on tiny branch. |
217 |
|
218 |
### Main program ###
|
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
219 |
def main(): |
220 |
srcdir = None |
|
221 |
disabled_modules = None |
|
3486.1.261
by Tim Just
Fixed build with all modules disabled. |
222 |
applications = set(['hipd']) |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
223 |
|
224 |
try: |
|
225 |
opts, args = getopt.getopt(sys.argv[1:], |
|
226 |
"s:d:", |
|
227 |
["srcdir=", "disabled_modules="]) |
|
228 |
except getopt.GetoptError, err: |
|
229 |
print str(err) |
|
230 |
sys.exit(2) |
|
231 |
for o, a in opts: |
|
232 |
if o in ("-s", "--srcdir"): |
|
233 |
srcdir = a |
|
234 |
elif o in ("-d", "--disabled_modules"): |
|
235 |
disabled_modules = a |
|
236 |
else: |
|
237 |
assert False, "unhandled option" |
|
238 |
||
3486.1.198
by Tim Just
Fixed bug in process_modules.py |
239 |
if disabled_modules: |
3486.1.241
by Tim Just
Uses commas instead of spaces for separation of modules. |
240 |
disabled_modules = disabled_modules.rsplit(',') |
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
241 |
|
3486.1.275
by Tim Just
Improved dependency check on daemon startup. |
242 |
(module_info) = read_module_info(os.path.join(srcdir, MODULES_DIR), |
243 |
disabled_modules) |
|
244 |
||
245 |
check_dependencies(module_info) |
|
246 |
||
247 |
create_header_files(applications, module_info) |
|
3486.1.195
by Tim Just
Added command line arguments and main function to process_modules.py |
248 |
|
249 |
if __name__ == "__main__": |
|
250 |
main() |