Skip to content

Commit 3225c31

Browse files
Add 3c-regtest.py and migrate one example test to use it.
Fixes: - Comment about #_MARKER_# - abspath
1 parent 9a8a7b2 commit 3225c31

File tree

2 files changed

+113
-6
lines changed

2 files changed

+113
-6
lines changed

clang/test/3C/3c-regtest.py

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env python
2+
#
3+
# Usage: 3c-regtest -t TMPNAME [options...] SRC_FILE
4+
#
5+
# TMPNAME corresponds to %t and SRC_FILE corresponds to %s. Both are required.
6+
#
7+
# --subst can be used for things such as %clang, for example (assuming single
8+
# --quotes are removed by the shell):
9+
#
10+
# --subst %clang 'clang -some-flag'
11+
#
12+
# (Note: A literal % has to be represented as %% in a RUN line. If we instead
13+
# established the convention of automatically prepending the % here, then the
14+
# RUN line would trip the "Do not use 'clang' in tests, use '%clang'." error.)
15+
#
16+
# Example RUN line:
17+
#
18+
# // RUN: %S/3c-regtest.py -t %t --subst %%clang '%clang' %s
19+
#
20+
# Soon, we'll add options for different kinds of 3C regression tests.
21+
22+
# TODO: Add Windows compatibility code once we have an easy way to test on Windows.
23+
24+
import sys
25+
import os
26+
import platform
27+
import argparse
28+
29+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) +
30+
'/../../../llvm/utils/lit')
31+
import lit.TestRunner
32+
33+
print "NOTICE: cwd is %s" % os.getcwd()
34+
35+
def die(msg):
36+
sys.stderr.write('Error: %s\n' % msg)
37+
sys.exit(1)
38+
39+
parser = argparse.ArgumentParser(description='Run a 3C regression test.')
40+
# TODO: Add help
41+
parser.add_argument('test_file')
42+
parser.add_argument('-t', required=True)
43+
parser.add_argument('--subst', action='append', nargs=2, default=[])
44+
args = parser.parse_args()
45+
46+
test_dir = os.path.dirname(args.test_file)
47+
if test_dir == '':
48+
test_dir = '.'
49+
50+
tmpName = args.t
51+
tmpNameSuffix = '.tmp'
52+
if tmpName.endswith(tmpNameSuffix):
53+
tmpBase = tmpName[:-len(tmpNameSuffix)]
54+
else:
55+
die('-t argument %s does not end with %s' % (tmpName, tmpNameSuffix))
56+
57+
substitutions = [
58+
# #_MARKER_# is a hack copied from getDefaultSubstitutions in
59+
# llvm/utils/lit/lit/TestRunner.py. To explain it a bit more fully:
60+
# applySubstitutions processes each before/after pair in turn and replaces
61+
# all occurrences. So if we simply put ('%%', '%') as either the first or
62+
# last pair, there is a risk of a % being interpreted as part of a %s, etc.
63+
# Instead, we temporarily replace %% with a string that doesn't contain %
64+
# and that we assume doesn't occur elsewhere in the commands. The "proper"
65+
# way to implement this kind of substitution processing is to make one pass
66+
# over the input from left to right, replacing codes as they are found, but
67+
# apparently that wasn't worth the extra code in `lit`.
68+
('%%', '#_MARKER_#'),
69+
('%s', args.test_file),
70+
('%S', test_dir),
71+
('%t', tmpName),
72+
]
73+
substitutions.extend(args.subst)
74+
substitutions.append(('#_MARKER_#', '%'))
75+
76+
# Starting with processor.py because it's always the same.
77+
commands = [
78+
# FIXME: 'foo.c' + 'hecked.c' is a terrible hack; find the right way to do this.
79+
'3c -alltypes -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK" %s',
80+
'3c -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK" %s',
81+
'3c -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -',
82+
'3c -output-postfix=checked -alltypes %s',
83+
'3c -alltypes %shecked.c -- | count 0',
84+
'rm %shecked.c',
85+
]
86+
commands = lit.TestRunner.applySubstitutions(commands, substitutions)
87+
88+
class FakeTestConfig:
89+
def __init__(self):
90+
self.pipefail = True # Is this always OK?
91+
self.environment = dict(os.environ)
92+
93+
class FakeTest:
94+
def __init__(self):
95+
self.config = FakeTestConfig()
96+
97+
class FakeLitConfig:
98+
def __init__(self):
99+
self.isWindows = platform.system() == 'windows'
100+
# Let the calling `lit` handle any timeout.
101+
self.maxIndividualTestTime = 0
102+
103+
res = lit.TestRunner.executeScriptInternal(
104+
FakeTest(), FakeLitConfig(), tmpBase, commands, os.getcwd())
105+
if isinstance(res, lit.Test.Result):
106+
die('Error: executeScriptInternal returned unexpected Result(%s, %r)' %
107+
(res.code.name, res.output))
108+
109+
out, err, exitCode, timeoutInfo = res
110+
sys.stdout.write(out)
111+
sys.stderr.write(err)
112+
sys.exit(exitCode)

clang/test/3C/b9_allsafestructp.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
// RUN: 3c -alltypes -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK" %s
2-
// RUN: 3c -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK" %s
3-
// RUN: 3c -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -
4-
// RUN: 3c -output-postfix=checked -alltypes %s
5-
// RUN: 3c -alltypes %S/b9_allsafestructp.checked.c -- | count 0
6-
// RUN: rm %S/b9_allsafestructp.checked.c
1+
// RUN: %S/3c-regtest.py -t %t --subst %%clang '%clang' %s
72
#include <stddef.h>
83
#include <stddef.h>
94
extern _Itype_for_any(T) void *calloc(size_t nmemb, size_t size) : itype(_Array_ptr<T>) byte_count(nmemb * size);

0 commit comments

Comments
 (0)