Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:54

0001 #! /usr/bin/env python3
0002 #
0003 # Copyright 2018 Chris Johns (chrisj@rtems.org)
0004 # All rights reserved.
0005 #
0006 # This file is part of the RTEMS Tools package in 'rtems-tools'.
0007 #
0008 # Redistribution and use in source and binary forms, with or without
0009 # modification, are permitted provided that the following conditions are met:
0010 #
0011 # 1. Redistributions of source code must retain the above copyright notice,
0012 # this list of conditions and the following disclaimer.
0013 #
0014 # 2. Redistributions in binary form must reproduce the above copyright notice,
0015 # this list of conditions and the following disclaimer in the documentation
0016 # and/or other materials provided with the distribution.
0017 #
0018 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
0022 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028 # POSSIBILITY OF SUCH DAMAGE.
0029 #
0030 #
0031 
0032 #
0033 # Python version the rtems-test-check script.
0034 #
0035 
0036 import os
0037 import os.path
0038 import re
0039 import sys
0040 
0041 def eprint(*args, **kwargs):
0042     print(*args, file=sys.stderr, **kwargs)
0043 
0044 #
0045 # Search the include paths for a file.
0046 #
0047 def find_testdata(paths, name):
0048     for p in paths:
0049         fn = os.path.join(p, name)
0050         if os.path.exists(fn):
0051             return fn
0052     return None
0053 
0054 #
0055 # Arguments. Keep it simple.
0056 #
0057 sys_args = sys.argv[1:]
0058 if len(sys_args) < 4:
0059     eprint('error: invalid command line')
0060     print('INVALID-TEST-DATA')
0061     sys.exit(2)
0062 
0063 verbose = False
0064 args = 0
0065 
0066 if sys_args[1] == '-v':
0067     verbose = True
0068     args = 1
0069 
0070 mode = sys_args[args + 1]
0071 bsp = sys_args[args + 2]
0072 includepaths = sys_args[args + 4].split(os.pathsep)
0073 testconfig = [find_testdata(includepaths, sys_args[args + 3])]
0074 tests = sys_args[args + 5:]
0075 
0076 if verbose:
0077     eprint('cmd: %s' % (' '.join(sys_args)))
0078 
0079 #
0080 # Handle the modes.
0081 #
0082 if mode == 'exclude':
0083     pass
0084 elif mode == 'cflags':
0085     if len(tests) != 1:
0086         eprint('error: test count not 1 for mode: %s' % (mode))
0087         print('INVALID-TEST-DATA')
0088         sys.exit(1)
0089 else:
0090     eprint('error: invalid mode: %s' % (mode))
0091     print('INVALID-TEST-DATA')
0092     sys.exit(1)
0093 
0094 #
0095 # Common RTEMS testsuite configuration. Load first.
0096 #
0097 rtems_testdata = find_testdata(includepaths, os.path.join('testdata', 'rtems.tcfg'))
0098 if rtems_testdata is not None:
0099     testconfig.insert(0, rtems_testdata)
0100 
0101 states = ['exclude',
0102           'expected-fail',
0103           'user-input',
0104           'indeterminate',
0105           'benchmark',
0106           'rexclude',
0107           'rinclude']
0108 flags = ['cflags']
0109 defines = { 'expected-fail' : '-DTEST_STATE_EXPECTED_FAIL=1',
0110             'user-input'    : '-DTEST_STATE_USER_INPUT=1',
0111             'indeterminate' : '-DTEST_STATE_INDETERMINATE=1',
0112             'benchmark'     : '-DTEST_STATE_BENCHMARK=1' }
0113 output = []
0114 testdata = { 'flags': {} }
0115 
0116 for f in flags:
0117     testdata['flags'][f] = {}
0118 
0119 if verbose:
0120     eprint('mode: %s' % (mode))
0121     eprint('testconfig: %r' % (testconfig))
0122     eprint('testconfig: %s' % (', '.join([x for x in testconfig if x is not None])))
0123     eprint('includepaths: %s' % (includepaths))
0124     eprint('bsp: %s' % (bsp))
0125     eprint('tests: %s' % (', '.join(tests)))
0126 
0127 def clean(line):
0128     line = line[0:-1]
0129     b = line.find('#')
0130     if b >= 0:
0131         line = line[1:b]
0132     return line.strip()
0133 
0134 #
0135 # Load the test data.
0136 #
0137 while len(testconfig):
0138     tc = testconfig[0]
0139     testconfig.remove(tc)
0140     if tc is None:
0141         continue
0142     if verbose:
0143         eprint('reading: %s' % (tc))
0144     if not os.path.exists(tc):
0145         if verbose:
0146             eprint('%s: not found' % (tc))
0147         continue
0148     with open(tc) as f:
0149         tdata = [clean(l) for l in f.readlines()]
0150     lc = 0
0151     for line in tdata:
0152         lc += 1
0153         if len(line) == 0:
0154             continue
0155         ls = [s.strip() for s in line.split(':', 1)]
0156         if verbose:
0157             eprint('%4d: %s' % (lc, line))
0158         if len(ls) != 2:
0159             eprint('error: syntax error: %s:%d' % (tc, lc))
0160             print('INVALID-TEST-DATA')
0161             sys.exit(1)
0162         state = ls[0]
0163         test = ls[1]
0164         if state == 'include':
0165             td = find_testdata(includepaths, test)
0166             if td is None:
0167                 eprint('error: include not found: %s:%d' % (tc, lc))
0168                 print('INVALID-TEST-DATA')
0169                 sys.exit(1)
0170             testconfig.insert(0, td)
0171             if verbose:
0172                 eprint('include: %s' % (', '.join(testconfig)))
0173         elif state in flags:
0174             fs = test.split(':', 1)
0175             if len(fs) != 2:
0176                 eprint('error: syntax error: %s:%d' % (tc, lc))
0177                 print('INVALID-TEST-DATA')
0178                 sys.exit(1)
0179             ftests = [t.strip() for t in fs[0].split(',')]
0180             if verbose:
0181                 eprint('%4d: %r : %s' % (lc, ftests, fs[1]))
0182             for test in ftests:
0183                 if test not in testdata['flags'][state]:
0184                     testdata['flags'][state][test] = [fs[1]]
0185                 else:
0186                     testdata['flags'][state][test] += [fs[1]]
0187         elif state in states:
0188             stests = [t.strip() for t in test.split(',')]
0189             if state not in testdata:
0190                 testdata[state] = stests
0191             else:
0192                 testdata[state] += stests
0193         else:
0194             eprint('error: invalid test state: %s in %s:%d' % (state, tc, lc))
0195             print('INVALID-TEST-DATA')
0196             sys.exit(1)
0197 
0198 if mode in flags:
0199     for state in ['exclude', 'rexclude', 'rinclude']:
0200         states.remove(state)
0201 
0202 for test in tests:
0203     if mode == 'exclude':
0204         #
0205         # Exclude is the highest priority, do this first
0206         #
0207         if 'exclude' in testdata and test in testdata['exclude']:
0208             exclude = True
0209         else:
0210             #
0211             # Regx exclude then regx include so you can filter a whole
0212             # group and add back some.
0213             #
0214             exclude = False
0215             if 'rexclude' in testdata:
0216                 for e in testdata['rexclude']:
0217                     try:
0218                         m = re.compile(e).match(test)
0219                     except re.error as ree:
0220                         eprint('error: invalid rexclude regx: %s: %s' % (e, ree))
0221                         print('INVALID-TEST-DATA')
0222                         sys.exit(1)
0223                     if m:
0224                         exclude = True
0225                         if 'rinclude' in testdata:
0226                             for i in testdata['rinclude']:
0227                                 try:
0228                                     m = re.compile(i).match(test)
0229                                 except re.error as ree:
0230                                     eprint('error: invalid rinclude regx: %s: %s' % (i, ree))
0231                                     print('INVALID-TEST-DATA')
0232                                     sys.exit(1)
0233                                 if m:
0234                                     exclude = False
0235         #
0236         # If not excluded add the test to the output
0237         #
0238         if not exclude:
0239             output += [test]
0240     elif mode in flags:
0241         if mode == 'cflags':
0242             for state in states:
0243                 if state in testdata and test in testdata[state]:
0244                     output += [defines[state]]
0245         for ftest in testdata['flags'][mode]:
0246             try:
0247                 m = re.compile(ftest).match(test)
0248             except re.error as ref:
0249                 eprint('error: invalid flags test regx: %s: %s' % (ftest, ref))
0250                 print('INVALID-TEST-DATA')
0251                 sys.exit(1)
0252             if m:
0253                 output += testdata['flags'][mode][ftest]
0254 
0255 print(' '.join(sorted(set(output))))
0256 
0257 sys.exit(0)