blob: b0b368650eccf8ec3c75987d3a78f65d8e8179ba [file] [log] [blame]
Mohammad Azim Khanfff49042017-03-28 01:48:31 +01001"""
Azim Khan4b543232017-06-30 09:35:21 +01002mbed TLS
3Copyright (c) 2017 ARM Limited
Mohammad Azim Khanfff49042017-03-28 01:48:31 +01004
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16"""
17
18import os
19import re
20import argparse
21import shutil
22
23
24"""
25Generates code in following structure.
26
27<output dir>/
Azim Khan4b543232017-06-30 09:35:21 +010028 |-- mbedtls/
29 | |-- <test suite #1>/
30 | | |-- main.c
31 | | |-- *.data files
32 | ...
33 | |-- <test suite #n>/
34 | | |-- main.c
35 | | |-- *.data files
36 | |
Mohammad Azim Khanfff49042017-03-28 01:48:31 +010037"""
38
39
40BEGIN_HEADER_REGEX = '/\*\s*BEGIN_HEADER\s*\*/'
41END_HEADER_REGEX = '/\*\s*END_HEADER\s*\*/'
42
43BEGIN_DEP_REGEX = 'BEGIN_DEPENDENCIES'
44END_DEP_REGEX = 'END_DEPENDENCIES'
45
46BEGIN_CASE_REGEX = '/\*\s*BEGIN_CASE\s*(.*?)\s*\*/'
47END_CASE_REGEX = '/\*\s*END_CASE\s*\*/'
48
49
50class InvalidFileFormat(Exception):
51 """
52 Exception to indicate invalid file format.
53 """
54 pass
55
56
Azim Khan4b543232017-06-30 09:35:21 +010057class FileWrapper(file):
58 """
59 File wrapper class. Provides reading with line no. tracking.
60 """
61
62 def __init__(self, file_name):
63 """
64 Init file handle.
65
66 :param file_name:
67 """
68 super(FileWrapper, self).__init__(file_name, 'r')
69 self.line_no = 0
70
71 def next(self):
72 """
73 Iterator return impl.
74 :return:
75 """
76 line = super(FileWrapper, self).next()
77 if line:
78 self.line_no += 1
79 return line
80
81 def readline(self, limit=0):
82 """
83 Wrap the base class readline.
84
85 :param limit:
86 :return:
87 """
88 return self.next()
89
90
91def split_dep(dep):
92 return ('!', dep[1:]) if dep[0] == '!' else ('', dep)
93
94
Mohammad Azim Khanfff49042017-03-28 01:48:31 +010095def gen_deps(deps):
96 """
97 Generates dependency i.e. if def and endif code
98
99 :param deps:
100 :return:
101 """
Azim Khan4b543232017-06-30 09:35:21 +0100102 dep_start = ''.join(['#if %sdefined(%s)\n' % split_dep(x) for x in deps])
103 dep_end = ''.join(['#endif /* %s */\n' % x for x in reversed(deps)])
104
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100105 return dep_start, dep_end
106
107
108def gen_deps_one_line(deps):
109 """
110 Generates dependency checks in one line. Useful for writing code in #else case.
111
112 :param deps:
113 :return:
114 """
Azim Khan4b543232017-06-30 09:35:21 +0100115 defines = ('#if ' if len(deps) else '') + ' && '.join(['%sdefined(%s)' % split_dep(x) for x in deps])
116 return defines
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100117
118
Azim Khan4b543232017-06-30 09:35:21 +0100119def gen_function_wrapper(name, locals, args_dispatch):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100120 """
121 Creates test function code
122
123 :param name:
Azim Khan4b543232017-06-30 09:35:21 +0100124 :param locals:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100125 :param args_dispatch:
126 :return:
127 """
128 # Then create the wrapper
129 wrapper = '''
130void {name}_wrapper( void ** params )
131{{
132 {unused_params}
Azim Khan2397bba2017-06-09 04:35:03 +0100133{locals}
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100134 {name}( {args} );
135}}
Azim Khan4b543232017-06-30 09:35:21 +0100136'''.format(name=name, unused_params='(void)params;' if len(args_dispatch) == 0 else '',
137 args=', '.join(args_dispatch),
138 locals=locals)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100139 return wrapper
140
141
142def gen_dispatch(name, deps):
143 """
144 Generates dispatch condition for the functions.
145
146 :param name:
147 :param deps:
148 :return:
149 """
150 if len(deps):
151 ifdef = gen_deps_one_line(deps)
152 dispatch_code = '''
153{ifdef}
154 {name}_wrapper,
155#else
156 NULL,
157#endif
158'''.format(ifdef=ifdef, name=name)
159 else:
160 dispatch_code = '''
161 {name}_wrapper,
162'''.format(name=name)
163
164 return dispatch_code
165
166
Azim Khan4b543232017-06-30 09:35:21 +0100167def parse_suite_headers(funcs_f):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100168 """
169 Parses function headers.
170
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100171 :param funcs_f:
172 :return:
173 """
Azim Khan4b543232017-06-30 09:35:21 +0100174 headers = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100175 for line in funcs_f:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100176 if re.search(END_HEADER_REGEX, line):
177 break
178 headers += line
179 else:
180 raise InvalidFileFormat("file: %s - end header pattern [%s] not found!" % (funcs_f.name, END_HEADER_REGEX))
181
Azim Khan4b543232017-06-30 09:35:21 +0100182 return headers
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100183
184
Azim Khan4b543232017-06-30 09:35:21 +0100185def parse_suite_deps(funcs_f):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100186 """
187 Parses function dependencies.
188
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100189 :param funcs_f:
190 :return:
191 """
192 deps = []
193 for line in funcs_f:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100194 m = re.search('depends_on\:(.*)', line.strip())
195 if m:
196 deps += [x.strip() for x in m.group(1).split(':')]
197 if re.search(END_DEP_REGEX, line):
198 break
199 else:
200 raise InvalidFileFormat("file: %s - end dependency pattern [%s] not found!" % (funcs_f.name, END_DEP_REGEX))
201
Azim Khan4b543232017-06-30 09:35:21 +0100202 return deps
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100203
204
205def parse_function_deps(line):
206 """
207
208 :param line:
209 :return:
210 """
211 deps = []
212 m = re.search(BEGIN_CASE_REGEX, line)
213 dep_str = m.group(1)
214 if len(dep_str):
215 m = re.search('depends_on:(.*)', dep_str)
216 if m:
Azim Khan4b543232017-06-30 09:35:21 +0100217 deps = [x.strip() for x in m.group(1).strip().split(':')]
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100218 return deps
219
220
221def parse_function_signature(line):
222 """
223 Parsing function signature
224
225 :param line:
226 :return:
227 """
228 args = []
Azim Khan2397bba2017-06-09 04:35:03 +0100229 locals = ''
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100230 args_dispatch = []
231 m = re.search('\s*void\s+(\w+)\s*\(', line, re.I)
232 if not m:
233 raise ValueError("Test function should return 'void'\n%s" % line)
234 name = m.group(1)
235 line = line[len(m.group(0)):]
236 arg_idx = 0
237 for arg in line[:line.find(')')].split(','):
238 arg = arg.strip()
239 if arg == '':
240 continue
241 if re.search('int\s+.*', arg.strip()):
242 args.append('int')
243 args_dispatch.append('*( (int *) params[%d] )' % arg_idx)
244 elif re.search('char\s*\*\s*.*', arg.strip()):
245 args.append('char*')
246 args_dispatch.append('(char *) params[%d]' % arg_idx)
Azim Khan2397bba2017-06-09 04:35:03 +0100247 elif re.search('HexParam_t\s*\*\s*.*', arg.strip()):
Azim Khana57a4202017-05-31 20:32:32 +0100248 args.append('hex')
Azim Khan2397bba2017-06-09 04:35:03 +0100249 # create a structure
250 locals += """ HexParam_t hex%d = {%s, %s};
251""" % (arg_idx, '(uint8_t *) params[%d]' % arg_idx, '*( (uint32_t *) params[%d] )' % (arg_idx + 1))
252
253 args_dispatch.append('&hex%d' % arg_idx)
254 arg_idx += 1
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100255 else:
Azim Khan4b543232017-06-30 09:35:21 +0100256 raise ValueError("Test function arguments can only be 'int', 'char *' or 'HexParam_t'\n%s" % line)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100257 arg_idx += 1
258
Azim Khan4b543232017-06-30 09:35:21 +0100259 return name, args, locals, args_dispatch
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100260
261
Azim Khan4b543232017-06-30 09:35:21 +0100262def parse_function_code(funcs_f, deps, suite_deps):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100263 """
264
265 :param line_no:
266 :param funcs_f:
267 :param deps:
268 :param suite_deps:
269 :return:
270 """
Azim Khan4b543232017-06-30 09:35:21 +0100271 code = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100272 for line in funcs_f:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100273 # Check function signature
274 m = re.match('.*?\s+(\w+)\s*\(', line, re.I)
275 if m:
276 # check if we have full signature i.e. split in more lines
277 if not re.match('.*\)', line):
278 for lin in funcs_f:
279 line += lin
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100280 if re.search('.*?\)', line):
281 break
Azim Khan4b543232017-06-30 09:35:21 +0100282 name, args, locals, args_dispatch = parse_function_signature(line)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100283 code += line.replace(name, 'test_' + name)
284 name = 'test_' + name
285 break
286 else:
287 raise InvalidFileFormat("file: %s - Test functions not found!" % funcs_f.name)
288
289 for line in funcs_f:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100290 if re.search(END_CASE_REGEX, line):
291 break
292 code += line
293 else:
294 raise InvalidFileFormat("file: %s - end case pattern [%s] not found!" % (funcs_f.name, END_CASE_REGEX))
295
296 # Add exit label if not present
297 if code.find('exit:') == -1:
298 s = code.rsplit('}', 1)
299 if len(s) == 2:
Azim Khan4b543232017-06-30 09:35:21 +0100300 code = """exit:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100301 ;;
Azim Khan4b543232017-06-30 09:35:21 +0100302}""".join(s)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100303
Azim Khan4b543232017-06-30 09:35:21 +0100304 code += gen_function_wrapper(name, locals, args_dispatch)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100305 ifdef, endif = gen_deps(deps)
306 dispatch_code = gen_dispatch(name, suite_deps + deps)
Azim Khan4b543232017-06-30 09:35:21 +0100307 return name, args, ifdef + code + endif, dispatch_code
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100308
309
310def parse_functions(funcs_f):
311 """
312 Returns functions code pieces
313
314 :param funcs_f:
315 :return:
316 """
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100317 suite_headers = ''
318 suite_deps = []
319 suite_functions = ''
320 func_info = {}
321 function_idx = 0
322 dispatch_code = ''
323 for line in funcs_f:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100324 if re.search(BEGIN_HEADER_REGEX, line):
Azim Khan4b543232017-06-30 09:35:21 +0100325 headers = parse_suite_headers(funcs_f)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100326 suite_headers += headers
327 elif re.search(BEGIN_DEP_REGEX, line):
Azim Khan4b543232017-06-30 09:35:21 +0100328 deps = parse_suite_deps(funcs_f)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100329 suite_deps += deps
330 elif re.search(BEGIN_CASE_REGEX, line):
331 deps = parse_function_deps(line)
Azim Khan4b543232017-06-30 09:35:21 +0100332 func_name, args, func_code, func_dispatch = parse_function_code(funcs_f, deps, suite_deps)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100333 suite_functions += func_code
334 # Generate dispatch code and enumeration info
335 assert func_name not in func_info, "file: %s - function %s re-declared at line %d" % \
Azim Khan4b543232017-06-30 09:35:21 +0100336 (funcs_f.name, func_name, funcs_f.line_no)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100337 func_info[func_name] = (function_idx, args)
338 dispatch_code += '/* Function Id: %d */\n' % function_idx
339 dispatch_code += func_dispatch
340 function_idx += 1
341
342 ifdef, endif = gen_deps(suite_deps)
Azim Khan13c6bfb2017-06-15 14:45:56 +0100343 func_code = ifdef + suite_headers + suite_functions + endif
344 return suite_deps, dispatch_code, func_code, func_info
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100345
346
347def escaped_split(str, ch):
348 """
349 Split str on character ch but ignore escaped \{ch}
350
351 :param str:
352 :param ch:
353 :return:
354 """
355 if len(ch) > 1:
356 raise ValueError('Expected split character. Found string!')
357 out = []
358 part = ''
359 escape = False
360 for i in range(len(str)):
361 if not escape and str[i] == ch:
362 out.append(part)
363 part = ''
364 else:
365 part += str[i]
366 escape = not escape and str[i] == '\\'
367 if len(part):
368 out.append(part)
369 return out
370
371
372def parse_test_data(data_f):
373 """
374 Parses .data file
375
376 :param data_f:
377 :return:
378 """
379 STATE_READ_NAME = 0
380 STATE_READ_ARGS = 1
381 state = STATE_READ_NAME
382 deps = []
383
384 for line in data_f:
385 line = line.strip()
386 if len(line) and line[0] == '#': # Skip comments
387 continue
388
389 # skip blank lines
390 if len(line) == 0:
391 continue
392
393 if state == STATE_READ_NAME:
394 # Read test name
395 name = line
396 state = STATE_READ_ARGS
397 elif state == STATE_READ_ARGS:
398 # Check dependencies
399 m = re.search('depends_on\:(.*)', line)
400 if m:
401 deps = m.group(1).split(':')
402 else:
403 # Read test vectors
404 parts = escaped_split(line, ':')
405 function = parts[0]
406 args = parts[1:]
407 yield name, function, deps, args
408 deps = []
409 state = STATE_READ_NAME
410
411
412def gen_dep_check(dep_id, dep):
413 """
414 Generate code for the dependency.
415
416 :param dep_id:
417 :param dep:
418 :return:
419 """
420 if dep[0] == '!':
421 noT = '!'
422 dep = dep[1:]
423 else:
424 noT = ''
425 dep_check = '''
426if ( dep_id == {id} )
427{{
428#if {noT}defined({macro})
429 return( DEPENDENCY_SUPPORTED );
430#else
431 return( DEPENDENCY_NOT_SUPPORTED );
432#endif
433}}
434else
435'''.format(noT=noT, macro=dep, id=dep_id)
436
437 return dep_check
438
439
440def gen_expression_check(exp_id, exp):
441 """
442 Generates code for expression check
443
444 :param exp_id:
445 :param exp:
446 :return:
447 """
448 exp_code = '''
449if ( exp_id == {exp_id} )
450{{
451 *out_value = {expression};
452}}
453else
454'''.format(exp_id=exp_id, expression=exp)
455 return exp_code
456
457
Azim Khan13c6bfb2017-06-15 14:45:56 +0100458def gen_from_test_data(data_f, out_data_f, func_info, suite_deps):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100459 """
460 Generates dependency checks, expression code and intermediate data file from test data file.
461
462 :param data_f:
463 :param out_data_f:
464 :param func_info:
Azim Khan13c6bfb2017-06-15 14:45:56 +0100465 :param suite_deps:
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100466 :return:
467 """
468 unique_deps = []
469 unique_expressions = []
470 dep_check_code = ''
471 expression_code = ''
472 for test_name, function_name, test_deps, test_args in parse_test_data(data_f):
473 out_data_f.write(test_name + '\n')
474
475 func_id, func_args = func_info['test_' + function_name]
476 if len(test_deps):
477 out_data_f.write('depends_on')
478 for dep in test_deps:
479 if dep not in unique_deps:
480 unique_deps.append(dep)
481 dep_id = unique_deps.index(dep)
482 dep_check_code += gen_dep_check(dep_id, dep)
483 else:
484 dep_id = unique_deps.index(dep)
485 out_data_f.write(':' + str(dep_id))
486 out_data_f.write('\n')
487
488 assert len(test_args) == len(func_args), \
489 "Invalid number of arguments in test %s. See function %s signature." % (test_name, function_name)
490 out_data_f.write(str(func_id))
491 for i in xrange(len(test_args)):
492 typ = func_args[i]
493 val = test_args[i]
494
495 # check if val is a non literal int val
496 if typ == 'int' and not re.match('\d+', val): # its an expression # FIXME: Handle hex format. Tip: instead try converting int(str, 10) and int(str, 16)
497 typ = 'exp'
498 if val not in unique_expressions:
499 unique_expressions.append(val)
500 # exp_id can be derived from len(). But for readability and consistency with case of existing let's
501 # use index().
502 exp_id = unique_expressions.index(val)
503 expression_code += gen_expression_check(exp_id, val)
504 val = exp_id
505 else:
506 val = unique_expressions.index(val)
507 out_data_f.write(':' + typ + ':' + str(val))
508 out_data_f.write('\n\n')
509
510 # void unused params
511 if len(dep_check_code) == 0:
512 dep_check_code = '(void) dep_id;\n'
513 if len(expression_code) == 0:
514 expression_code = '(void) exp_id;\n'
515 expression_code += '(void) out_value;\n'
Azim Khan13c6bfb2017-06-15 14:45:56 +0100516 ifdef = gen_deps_one_line(suite_deps)
517 if len(suite_deps):
518 dep_check_code = '''
519{ifdef}
520{code}
521#else
522(void) dep_id;
523#endif
524'''.format(ifdef=ifdef, code=dep_check_code)
525 expression_code = '''
526{ifdef}
527{code}
528#else
529(void) exp_id;
530(void) out_value;
531#endif
532'''.format(ifdef=ifdef, code=expression_code)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100533 return dep_check_code, expression_code
534
535
Azim Khan1de892b2017-06-09 15:02:36 +0100536def generate_code(funcs_file, data_file, template_file, platform_file, help_file, suites_dir, c_file, out_data_file):
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100537 """
538 Generate mbed-os test code.
539
540 :param funcs_file:
541 :param dat a_file:
542 :param template_file:
543 :param platform_file:
544 :param help_file:
545 :param suites_dir:
546 :param c_file:
547 :param out_data_file:
548 :return:
549 """
550 for name, path in [('Functions file', funcs_file),
551 ('Data file', data_file),
552 ('Template file', template_file),
553 ('Platform file', platform_file),
554 ('Help code file', help_file),
555 ('Suites dir', suites_dir)]:
556 if not os.path.exists(path):
557 raise IOError("ERROR: %s [%s] not found!" % (name, path))
558
559 snippets = {'generator_script' : os.path.basename(__file__)}
560
561 # Read helpers
562 with open(help_file, 'r') as help_f, open(platform_file, 'r') as platform_f:
563 snippets['test_common_helper_file'] = help_file
564 snippets['test_common_helpers'] = help_f.read()
565 snippets['test_platform_file'] = platform_file
566 snippets['platform_code'] = platform_f.read().replace('DATA_FILE',
567 out_data_file.replace('\\', '\\\\')) # escape '\'
568
569 # Function code
570 with open(funcs_file, 'r') as funcs_f, open(data_file, 'r') as data_f, open(out_data_file, 'w') as out_data_f:
Azim Khan13c6bfb2017-06-15 14:45:56 +0100571 suite_deps, dispatch_code, func_code, func_info = parse_functions(funcs_f)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100572 snippets['functions_code'] = func_code
573 snippets['dispatch_code'] = dispatch_code
Azim Khan13c6bfb2017-06-15 14:45:56 +0100574 dep_check_code, expression_code = gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100575 snippets['dep_check_code'] = dep_check_code
576 snippets['expression_code'] = expression_code
577
578 snippets['test_file'] = c_file
579 snippets['test_main_file'] = template_file
580 snippets['test_case_file'] = funcs_file
581 snippets['test_case_data_file'] = data_file
582 # Read Template
583 # Add functions
584 #
585 with open(template_file, 'r') as template_f, open(c_file, 'w') as c_f:
586 line_no = 1
587 for line in template_f.readlines():
588 snippets['line_no'] = line_no + 1 # Increment as it sets next line number
589 code = line.format(**snippets)
590 c_f.write(code)
591 line_no += 1
592
593
594def check_cmd():
595 """
596 Command line parser.
597
598 :return:
599 """
600 parser = argparse.ArgumentParser(description='Generate code for mbed-os tests.')
601
602 parser.add_argument("-f", "--functions-file",
603 dest="funcs_file",
604 help="Functions file",
605 metavar="FUNCTIONS",
606 required=True)
607
608 parser.add_argument("-d", "--data-file",
609 dest="data_file",
610 help="Data file",
611 metavar="DATA",
612 required=True)
613
614 parser.add_argument("-t", "--template-file",
615 dest="template_file",
616 help="Template file",
617 metavar="TEMPLATE",
618 required=True)
619
620 parser.add_argument("-s", "--suites-dir",
621 dest="suites_dir",
622 help="Suites dir",
623 metavar="SUITES",
624 required=True)
625
626 parser.add_argument("--help-file",
627 dest="help_file",
628 help="Help file",
629 metavar="HELPER",
630 required=True)
631
632 parser.add_argument("-p", "--platform-file",
633 dest="platform_file",
634 help="Platform code file",
635 metavar="PLATFORM_FILE",
636 required=True)
637
638 parser.add_argument("-o", "--out-dir",
639 dest="out_dir",
640 help="Dir where generated code and scripts are copied",
641 metavar="OUT_DIR",
642 required=True)
643
644 args = parser.parse_args()
645
646 data_file_name = os.path.basename(args.data_file)
647 data_name = os.path.splitext(data_file_name)[0]
648
649 out_c_file = os.path.join(args.out_dir, data_name + '.c')
650 out_data_file = os.path.join(args.out_dir, data_file_name)
651
652 out_c_file_dir = os.path.dirname(out_c_file)
653 out_data_file_dir = os.path.dirname(out_data_file)
654 for d in [out_c_file_dir, out_data_file_dir]:
655 if not os.path.exists(d):
656 os.makedirs(d)
657
Azim Khan1de892b2017-06-09 15:02:36 +0100658 generate_code(args.funcs_file, args.data_file, args.template_file, args.platform_file,
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100659 args.help_file, args.suites_dir, out_c_file, out_data_file)
660
661
662if __name__ == "__main__":
663 check_cmd()