-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Expand file tree
/
Copy pathPathSanitizingFileCheck
More file actions
executable file
·131 lines (114 loc) · 4.8 KB
/
PathSanitizingFileCheck
File metadata and controls
executable file
·131 lines (114 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
# utils/PathSanitizingFileCheck -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
import argparse
import io
import os
import platform
import re
import subprocess
import sys
# LLVM Lit performs realpath with the config path, so all paths are relative
# to the real path. Paths that come from CMake (like cmake_binary_dir and
# swift_src_root), might not do real path. Use realpath to normalize. Because
# this normalizes Windows paths to use backslashes, we have to replace them
# back to forward slashes.
def normalize_if_path(s):
# Check dirname for cases like a file named `%t.out.txt`
# There won't be a `%t` path, but we still want to match this path substring.
if not os.path.exists(s) and not os.path.exists(os.path.dirname(s)):
return s
if platform.system() == "Windows":
return os.path.abspath(s).replace('\\', '/')
else:
return os.path.realpath(s)
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""
PathSanitizingFileCheck is a wrapper around LLVM's FileCheck. In addition
to all FileCheck features, PathSanitizingFileCheck can replace given
strings in the input with other strings. This feature is used to replace
paths to the source and build directories with path-independent
constants.""")
parser.add_argument(
"--sanitize",
help="replace the given string with another string",
metavar="REPLACEMENT=SOURCE",
action="append",
dest="sanitize_strings",
default=[])
parser.add_argument(
"--use-filecheck",
help="path to LLVM FileCheck executable",
metavar="PATH",
action="store",
dest="file_check_path",
default="FileCheck")
parser.add_argument(
"--enable-windows-compatibility",
help="Enable Windows path compatibility, which checks against both "
"forward slashes and backward slashes.",
action="store_true")
parser.add_argument(
"--enable-yaml-compatibility",
help="Enable YAML path compatibility. Since YAML double escapes "
"backward slashes, we need to check for them escaped. Only "
"available if Windows compatibility is enabled.",
action="store_true")
parser.add_argument(
"--dry-run",
help="Apply the replacements to the input and print the result "
"to standard output",
action="store_true")
parser.add_argument(
"--ignore-runtime-warnings",
help="Ignore warnings from the Swift runtime",
action="store_true")
args, unknown_args = parser.parse_known_args()
if args.enable_windows_compatibility:
if args.enable_yaml_compatibility:
slashes_re = r'(/|\\\\|\\\\\\\\)'
else:
slashes_re = r'(/|\\\\)'
else:
slashes_re = r'/'
stdin = io.open(sys.stdin.fileno(), 'r', encoding='utf-8', errors='ignore').read()
for s in sorted(args.sanitize_strings, key=len, reverse=True):
replacement, pattern = s.split('=', 1)
# Since we want to use pattern as a regex in some platforms, we need
# to escape it first, and then replace the escaped slash
# literal (r'\\/') for our platform-dependent slash regex.
stdin = re.sub(re.sub(r'\\/' if sys.version_info[0] < 3 else r'/',
slashes_re, re.escape(normalize_if_path(pattern))),
replacement, stdin)
# Because we force the backtracer on in the tests, we can get runtime
# warnings about privileged programs. Suppress those, and also the
# warning it might emit if backtracing isn't supported on the test platform.
# Additionally, suppress warnings about unknown backtracer options, since
# we might want to add new ones to the lit tests and we should ignore
# messages from the system copy of the runtime in that case.
if args.ignore_runtime_warnings:
stdin = re.sub(r'^swift runtime: (backtrace-on-crash is not '
r'supported|unknown) .*\n', "", stdin, flags=re.M)
if args.dry_run:
print(stdin)
return 0
else:
p = subprocess.Popen(
[args.file_check_path] + unknown_args, stdin=subprocess.PIPE)
stdout, stderr = p.communicate(stdin.encode('utf-8'))
if stdout is not None:
print(stdout)
if stderr is not None:
print(stderr, file=sys.stderr)
return p.wait()
if __name__ == '__main__':
exit(main())