#! /usr/bin/env python # # Copyright 2018 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # # # Python version the rtems-test-check script. # from __future__ import print_function import os import os.path import re import sre_constants import sys def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) # # Search the include paths for a file. # def find_testdata(paths, name): for p in paths: fn = os.path.join(p, name) if os.path.exists(fn): return fn return None # # Arguments. Keep it simple. # sys_args = sys.argv[1:] if len(sys_args) < 4: eprint('error: invalid command line') print('INVALID-TEST-DATA') sys.exit(2) verbose = False args = 0 if sys_args[1] == '-v': verbose = True args = 1 mode = sys_args[args + 1] bsp = sys_args[args + 2] includepaths = sys_args[args + 4].split(os.pathsep) testconfig = [find_testdata(includepaths, sys_args[args + 3])] tests = sys_args[args + 5:] if verbose: eprint('cmd: %s' % (' '.join(sys_args))) # # Handle the modes. # if mode == 'exclude': pass elif mode == 'cflags': if len(tests) != 1: eprint('error: test count not 1 for mode: %s' % (mode)) print('INVALID-TEST-DATA') sys.exit(1) else: eprint('error: invalid mode: %s' % (mode)) print('INVALID-TEST-DATA') sys.exit(1) # # Common RTEMS testsuite configuration. Load first. # rtems_testdata = find_testdata(includepaths, os.path.join('testdata', 'rtems.tcfg')) if rtems_testdata is not None: testconfig.insert(0, rtems_testdata) states = ['exclude', 'expected-fail', 'user-input', 'indeterminate', 'benchmark', 'rexclude', 'rinclude'] flags = ['cflags'] defines = { 'expected-fail' : '-DTEST_STATE_EXPECTED_FAIL=1', 'user-input' : '-DTEST_STATE_USER_INPUT=1', 'indeterminate' : '-DTEST_STATE_INDETERMINATE=1', 'benchmark' : '-DTEST_STATE_BENCHMARK=1' } output = [] testdata = { 'flags': {} } for f in flags: testdata['flags'][f] = {} if verbose: eprint('mode: %s' % (mode)) eprint('testconfig: %r' % (testconfig)) eprint('testconfig: %s' % (', '.join([x for x in testconfig if x is not None]))) eprint('includepaths: %s' % (includepaths)) eprint('bsp: %s' % (bsp)) eprint('tests: %s' % (', '.join(tests))) def clean(line): line = line[0:-1] b = line.find('#') if b >= 0: line = line[1:b] return line.strip() # # Load the test data. # while len(testconfig): tc = testconfig[0] testconfig.remove(tc) if tc is None: continue if verbose: eprint('reading: %s' % (tc)) if not os.path.exists(tc): if verbose: eprint('%s: not found' % (tc)) continue with open(tc) as f: tdata = [clean(l) for l in f.readlines()] lc = 0 for line in tdata: lc += 1 if len(line) == 0: continue ls = [s.strip() for s in line.split(':', 1)] if verbose: eprint('%4d: %s' % (lc, line)) if len(ls) != 2: eprint('error: syntax error: %s:%d' % (tc, lc)) print('INVALID-TEST-DATA') sys.exit(1) state = ls[0] test = ls[1] if state == 'include': td = find_testdata(includepaths, test) if td is None: eprint('error: include not found: %s:%d' % (tc, lc)) print('INVALID-TEST-DATA') sys.exit(1) testconfig.insert(0, td) if verbose: eprint('include: %s' % (', '.join(testconfig))) elif state in flags: fs = test.split(':', 1) if len(fs) != 2: eprint('error: syntax error: %s:%d' % (tc, lc)) print('INVALID-TEST-DATA') sys.exit(1) ftests = [t.strip() for t in fs[0].split(',')] if verbose: eprint('%4d: %r : %s' % (lc, ftests, fs[1])) for test in ftests: if test not in testdata['flags'][state]: testdata['flags'][state][test] = [fs[1]] else: testdata['flags'][state][test] += [fs[1]] elif state in states: stests = [t.strip() for t in test.split(',')] if state not in testdata: testdata[state] = stests else: testdata[state] += stests else: eprint('error: invalid test state: %s in %s:%d' % (state, tc, lc)) print('INVALID-TEST-DATA') sys.exit(1) if mode in flags: for state in ['exclude', 'rexclude', 'rinclude']: states.remove(state) for test in tests: if mode == 'exclude': # # Exclude is the highest priority, do this first # if 'exclude' in testdata and test in testdata['exclude']: exclude = True else: # # Regx exclude then regx include so you can filter a whole # group and add back some. # exclude = False if 'rexclude' in testdata: for e in testdata['rexclude']: try: m = re.compile(e).match(test) except sre_constants.error as ree: eprint('error: invalid rexclude regx: %s: %s' % (e, ree)) print('INVALID-TEST-DATA') sys.exit(1) if m: exclude = True if 'rinclude' in testdata: for i in testdata['rinclude']: try: m = re.compile(i).match(test) except sre_constants.error as ree: eprint('error: invalid rinclude regx: %s: %s' % (i, ree)) print('INVALID-TEST-DATA') sys.exit(1) if m: exclude = False # # If not excluded add the test to the output # if not exclude: output += [test] elif mode in flags: if mode == 'cflags': for state in states: if state in testdata and test in testdata[state]: output += [defines[state]] for ftest in testdata['flags'][mode]: try: m = re.compile(ftest).match(test) except sre_constants.error as ref: eprint('error: invalid flags test regx: %s: %s' % (ftest, ref)) print('INVALID-TEST-DATA') sys.exit(1) if m: output += testdata['flags'][mode][ftest] print(' '.join(sorted(set(output)))) sys.exit(0)