Skip to content

Commit 169948f

Browse files
authored
Merge pull request swiftlang#34176 from drodriguez/windows-percent-r-is-bad
[windows] Avoid %r for quoting module-cache-path in Windows.
2 parents 4419f87 + 8470a66 commit 169948f

File tree

2 files changed

+84
-46
lines changed

2 files changed

+84
-46
lines changed

test/Driver/working-directory.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
// -output-file-map itself
6161
// RUN: echo "{\"main.swift\": {\"object\": \"main-modified.o\"}}" > %t/ofmo2.json
6262
// RUN: touch %t/main.swift
63-
// RUN: cd %S && %swiftc_driver -driver-print-jobs -working-directory %/t -c main.swift -output-file-map ofmo2.json | %FileCheck %s -check-prefix=OUTPUT_FILE_MAP_2
63+
// RUN: cd %S && %swiftc_driver -driver-print-jobs -working-directory %/t -c main.swift -output-file-map ofmo2.json | %FileCheck %s -check-prefix=OUTPUT_FILE_MAP_2 --enable-yaml-compatibility
6464
// -output-file-map= is an alias for -output-file-map
65-
// RUN: cd %S && %swiftc_driver -driver-print-jobs -working-directory %/t -c main.swift -output-file-map=ofmo2.json | %FileCheck %s -check-prefix=OUTPUT_FILE_MAP_2
65+
// RUN: cd %S && %swiftc_driver -driver-print-jobs -working-directory %/t -c main.swift -output-file-map=ofmo2.json | %FileCheck %s -check-prefix=OUTPUT_FILE_MAP_2 --enable-yaml-compatibility
6666
// OUTPUT_FILE_MAP_2: BUILD_DIR{{.*}}main-modified.o
6767

6868
// RUN: %empty-directory(%t/sub)

test/lit.cfg

+82-44
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,27 @@ def get_lldb_python_interpreter(lldb_build_root):
110110
return None
111111
return python_path
112112

113+
if not platform.system() == 'Windows':
114+
# Python 3.3 has shlex.quote, while previous Python have pipes.quote
115+
if sys.version_info[0:2] >= (3, 2):
116+
shell_quote = shlex.quote
117+
else:
118+
shell_quote = pipes.quote
119+
else:
120+
# In Windows neither pipe.quote nor shlex.quote works.
121+
def shell_quote(s):
122+
# Quote the argument if it is empty, or contains a quote or a space.
123+
if len(s) == 0 or re.search(r'["\s]', s):
124+
s = '"' + s.replace('"', r'\"') + '"'
125+
return s
126+
127+
def escape_for_substitute_captures(s):
128+
# SubstituteCaptures strings are used as replacement patterns for regular
129+
# expressions. In them escapes like \1, \2 are used as references, but that
130+
# means that simple \ will try to be interpreted, so we need to escape them
131+
# with \\.
132+
return s.replace("\\", "\\\\")
133+
113134
###
114135

115136
# Check that the object root is known.
@@ -380,7 +401,7 @@ config.sil_test_options = os.environ.get('SIL_TEST_OPTIONS', '')
380401

381402
config.clang_module_cache_path = make_path(config.swift_test_results_dir, "clang-module-cache")
382403
shutil.rmtree(config.clang_module_cache_path, ignore_errors=True)
383-
mcp_opt = "-module-cache-path %r" % config.clang_module_cache_path
404+
mcp_opt = "-module-cache-path %s" % shell_quote(config.clang_module_cache_path)
384405
clang_mcp_opt = "-fmodules-cache-path=%r" % config.clang_module_cache_path
385406
lit_config.note("Using Clang module cache: " + config.clang_module_cache_path)
386407
lit_config.note("Using test results dir: " + config.swift_test_results_dir)
@@ -396,7 +417,7 @@ config.substitutions.append( ('%llvm_obj_root', config.llvm_obj_root) )
396417
config.substitutions.append( ('%llvm_src_root', config.llvm_src_root) )
397418
config.substitutions.append( ('%swift_obj_root', config.swift_obj_root) )
398419
config.substitutions.append( ('%swift_src_root', config.swift_src_root) )
399-
config.substitutions.append( ('%{python}', pipes.quote(sys.executable)) )
420+
config.substitutions.append( ('%{python}', shell_quote(sys.executable)) )
400421
config.substitutions.append( ('%{python.unquoted}', sys.executable) )
401422
config.substitutions.append( ('%mcp_opt', mcp_opt) )
402423
config.substitutions.append( ('%swift_driver_plain', "%r" % config.swift) )
@@ -1096,7 +1117,8 @@ elif run_os in ['windows-msvc']:
10961117
subst_target_swift_frontend_mock_sdk_after = ''
10971118

10981119
config.target_build_swift_dylib = \
1099-
SubstituteCaptures("%s -parse-as-library -emit-library -o \\1" % (config.target_build_swift))
1120+
SubstituteCaptures(r"%s -parse-as-library -emit-library -o \1" % (
1121+
escape_for_substitute_captures(config.target_build_swift)))
11001122
config.target_add_rpath = r''
11011123

11021124
config.target_clang = \
@@ -1280,7 +1302,7 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android':
12801302
toolchain_directory = make_path(
12811303
config.android_ndk_path, "toolchains", toolchain_directory_name,
12821304
"prebuilt", prebuilt_directory)
1283-
tools_directory = pipes.quote(make_path(
1305+
tools_directory = shell_quote(make_path(
12841306
toolchain_directory, ndk_platform_triple, "bin"))
12851307
lit_config.note("Testing Android " + config.variant_triple)
12861308
config.target_object_format = "elf"
@@ -1290,20 +1312,20 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android':
12901312
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
12911313
config.target_sdk_name = "android"
12921314
android_link_paths_opt = "-L {} -L {} -L {}".format(
1293-
pipes.quote(make_path(
1315+
shell_quote(make_path(
12941316
config.android_ndk_path, "sources", "cxx-stl", "llvm-libc++",
12951317
"libs", ndk_platform_tuple)),
1296-
pipes.quote(make_path(
1318+
shell_quote(make_path(
12971319
toolchain_directory, "lib", "gcc", ndk_platform_triple,
12981320
"{}.x".format(config.android_ndk_gcc_version))),
1299-
pipes.quote(make_path(
1321+
shell_quote(make_path(
13001322
toolchain_directory, ndk_platform_triple, "lib")))
13011323
# Since NDK r14 the headers are unified under $NDK_PATH/sysroot, so the -sdk
13021324
# switch is not enough. Additionally we have to include both the unified
13031325
# sysroot, and the architecture sysroot.
1304-
unified_android_include_path = pipes.quote(make_path(
1326+
unified_android_include_path = shell_quote(make_path(
13051327
config.android_ndk_path, "sysroot", "usr", "include"))
1306-
architecture_android_include_path = pipes.quote(make_path(
1328+
architecture_android_include_path = shell_quote(make_path(
13071329
config.android_ndk_path, "sysroot", "usr", "include",
13081330
ndk_platform_triple))
13091331
android_include_paths_opt = "-I {} -I {}".format(
@@ -1749,21 +1771,27 @@ if not kIsWindows:
17491771

17501772
if not getattr(config, 'target_run_simple_swift', None):
17511773
config.target_run_simple_swift_parameterized = SubstituteCaptures(
1752-
"%%empty-directory(%%t) && "
1753-
"%s %s %%s \\1 -o %%t/a.out -module-name main && "
1754-
"%s %%t/a.out && "
1755-
"%s %%t/a.out"
1756-
% (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run)
1774+
r"%%empty-directory(%%t) && "
1775+
r"%s %s %%s \1 -o %%t/a.out -module-name main && "
1776+
r"%s %%t/a.out && "
1777+
r"%s %%t/a.out"
1778+
% (escape_for_substitute_captures(config.target_build_swift),
1779+
escape_for_substitute_captures(mcp_opt),
1780+
escape_for_substitute_captures(config.target_codesign),
1781+
escape_for_substitute_captures(config.target_run))
17571782
)
17581783
config.target_run_simple_swiftgyb_parameterized = SubstituteCaptures(
1759-
"%%empty-directory(%%t) && "
1760-
"%%gyb %%s -o %%t/main.swift && "
1761-
"%%line-directive %%t/main.swift -- "
1762-
"%s %s %%t/main.swift \\1 -o %%t/a.out -module-name main && "
1763-
"%s %%t/a.out && "
1764-
"%%line-directive %%t/main.swift -- "
1765-
"%s %%t/a.out"
1766-
% (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run)
1784+
r"%%empty-directory(%%t) && "
1785+
r"%%gyb %%s -o %%t/main.swift && "
1786+
r"%%line-directive %%t/main.swift -- "
1787+
r"%s %s %%t/main.swift \1 -o %%t/a.out -module-name main && "
1788+
r"%s %%t/a.out && "
1789+
r"%%line-directive %%t/main.swift -- "
1790+
r"%s %%t/a.out"
1791+
% (escape_for_substitute_captures(config.target_build_swift),
1792+
escape_for_substitute_captures(mcp_opt),
1793+
escape_for_substitute_captures(config.target_codesign),
1794+
escape_for_substitute_captures(config.target_run))
17671795
)
17681796

17691797
config.target_run_simple_swift = (
@@ -1804,7 +1832,7 @@ config.target_resilience_test = (
18041832
'%s %s --target-build-swift "%s" --target-run "%s" --t %%t --S %%S '
18051833
'--s %%s --lib-prefix "%s" --lib-suffix "%s" --target-codesign "%s" '
18061834
'--additional-compile-flags "%s" --triple "%s"'
1807-
% (pipes.quote(sys.executable), config.rth, config.target_build_swift,
1835+
% (shell_quote(sys.executable), config.rth, config.target_build_swift,
18081836
config.target_run, config.target_shared_library_prefix,
18091837
config.target_shared_library_suffix, config.target_codesign,
18101838
rth_flags, config.variant_triple))
@@ -1833,8 +1861,9 @@ config.substitutions.append(('%target-swift-emit-ir\(mock-sdk:([^)]+)\)',
18331861
SubstituteCaptures(r'%target-swift-frontend(mock-sdk:\1) -emit-ir -verify-syntax-tree')))
18341862
config.substitutions.append(('%target-swift-emit-ir', '%target-swift-frontend -emit-ir -verify-syntax-tree'))
18351863
config.substitutions.append(('%target-swift-frontend\(mock-sdk:([^)]+)\)',
1836-
SubstituteCaptures(r'%s \1 %s' % (subst_target_swift_frontend_mock_sdk,
1837-
subst_target_swift_frontend_mock_sdk_after))))
1864+
SubstituteCaptures(r'%s \1 %s' % (
1865+
escape_for_substitute_captures(subst_target_swift_frontend_mock_sdk),
1866+
escape_for_substitute_captures(subst_target_swift_frontend_mock_sdk_after)))))
18381867
config.substitutions.append(('%target-swift-frontend', config.target_swift_frontend))
18391868

18401869

@@ -1872,22 +1901,23 @@ else:
18721901
SubstituteCaptures(r'ln \1 \2 || cp \1 \2')))
18731902

18741903
config.substitutions.append(('%utils', config.swift_utils))
1875-
config.substitutions.append(('%line-directive', '%s %s' % (pipes.quote(sys.executable), config.line_directive)))
1876-
config.substitutions.append(('%gyb', '%s %s' % (pipes.quote(sys.executable), config.gyb)))
1904+
config.substitutions.append(('%line-directive', '%s %s' % (shell_quote(sys.executable), config.line_directive)))
1905+
config.substitutions.append(('%gyb', '%s %s' % (shell_quote(sys.executable), config.gyb)))
18771906
config.substitutions.append(('%round-trip-syntax-test',
1878-
'%s %s' % (pipes.quote(sys.executable),
1907+
'%s %s' % (shell_quote(sys.executable),
18791908
config.round_trip_syntax_test)))
1880-
config.substitutions.append(('%rth', '%s %s' % (pipes.quote(sys.executable), config.rth)))
1909+
config.substitutions.append(('%rth', '%s %s' % (shell_quote(sys.executable), config.rth)))
18811910
config.substitutions.append(('%scale-test',
18821911
'{} {} --swiftc-binary={} --tmpdir=%t'.format(
1883-
pipes.quote(sys.executable), config.scale_test,
1912+
shell_quote(sys.executable), config.scale_test,
18841913
config.swiftc)))
18851914
config.substitutions.append(('%empty-directory\(([^)]+)\)',
18861915
SubstituteCaptures(r'rm -rf "\1" && mkdir -p "\1"')))
18871916

18881917
config.substitutions.append(('%target-sil-opt\(mock-sdk:([^)]+)\)',
1889-
SubstituteCaptures(r'%s \1 %s' % (subst_target_sil_opt_mock_sdk,
1890-
subst_target_sil_opt_mock_sdk_after))))
1918+
SubstituteCaptures(r'%s \1 %s' % (
1919+
escape_for_substitute_captures(subst_target_sil_opt_mock_sdk),
1920+
escape_for_substitute_captures(subst_target_sil_opt_mock_sdk_after)))))
18911921
# NOTE: This needs to be appended after the mock-sdk expansion to ensure that we
18921922
# first expand the mock-sdk when lit is processing.
18931923
config.substitutions.append(('%target-sil-opt', config.target_sil_opt))
@@ -1897,9 +1927,10 @@ config.substitutions.append(('%target-sil-llvm-gen', config.target_sil_llvm_gen)
18971927
config.substitutions.append(('%target-sil-nm', config.target_sil_nm))
18981928

18991929
config.substitutions.append(('%target-swift-ide-test\(mock-sdk:([^)]+)\)',
1900-
SubstituteCaptures(r'%s \1 %s -swift-version %s' % (subst_target_swift_ide_test_mock_sdk,
1901-
subst_target_swift_ide_test_mock_sdk_after,
1902-
swift_version))))
1930+
SubstituteCaptures(r'%s \1 %s -swift-version %s' % (
1931+
escape_for_substitute_captures(subst_target_swift_ide_test_mock_sdk),
1932+
escape_for_substitute_captures(subst_target_swift_ide_test_mock_sdk_after),
1933+
escape_for_substitute_captures(swift_version)))))
19031934
config.substitutions.append(('%target-swift-ide-test', "%s -swift-version %s" % (config.target_swift_ide_test, swift_version)))
19041935

19051936
config.substitutions.append(('%target-swift-symbolgraph-extract', config.target_swift_symbolgraph_extract))
@@ -1944,8 +1975,9 @@ config.substitutions.append(('%target-object-format', config.target_object_forma
19441975
config.substitutions.append(('%{target-shared-library-prefix}', config.target_shared_library_prefix))
19451976
config.substitutions.append(('%{target-shared-library-suffix}', config.target_shared_library_suffix))
19461977
config.substitutions.insert(0, ('%target-library-name\(([^)]+)\)',
1947-
SubstituteCaptures(r'%s\1%s' % (config.target_shared_library_prefix,
1948-
config.target_shared_library_suffix))))
1978+
SubstituteCaptures(r'%s\1%s' % (
1979+
escape_for_substitute_captures(config.target_shared_library_prefix),
1980+
escape_for_substitute_captures(config.target_shared_library_suffix)))))
19491981
config.substitutions.append(('%target-rpath\(([^)]+)\)',
19501982
SubstituteCaptures(config.target_add_rpath)))
19511983

@@ -1958,14 +1990,20 @@ if hasattr(config, 'otool_classic'):
19581990
config.substitutions.append(('%otool-classic', config.otool_classic))
19591991

19601992
config.substitutions.append(('%FileCheck',
1961-
'%s %r --sanitize BUILD_DIR=%r --sanitize SOURCE_DIR=%r --use-filecheck %r %s' % (
1962-
pipes.quote(sys.executable),
1963-
config.PathSanitizingFileCheck,
1964-
swift_obj_root,
1965-
config.swift_src_root,
1966-
config.filecheck,
1993+
'%s %s --sanitize BUILD_DIR=%s --sanitize SOURCE_DIR=%s --use-filecheck %s %s' % (
1994+
shell_quote(sys.executable),
1995+
shell_quote(config.PathSanitizingFileCheck),
1996+
# LLVM Lit performs realpath with the config path, so all paths are relative
1997+
# to the real path. swift_obj_root and swift_src_root come from CMake, which
1998+
# might not do real path. Because we have to match what Lit uses against what
1999+
# we provide we use realpath here. Because PathSanitizingFileCheck only
2000+
# understands sanitize patterns with forward slashes, and realpath normalizes
2001+
# the slashes, we have to replace them back to forward slashes.
2002+
shell_quote(os.path.realpath(swift_obj_root).replace("\\", "/")),
2003+
shell_quote(os.path.realpath(config.swift_src_root).replace("\\", "/")),
2004+
shell_quote(config.filecheck),
19672005
'--enable-windows-compatibility' if kIsWindows else '')))
1968-
config.substitutions.append(('%raw-FileCheck', pipes.quote(config.filecheck)))
2006+
config.substitutions.append(('%raw-FileCheck', shell_quote(config.filecheck)))
19692007
config.substitutions.append(('%import-libdispatch', getattr(config, 'import_libdispatch', '')))
19702008

19712009
if config.lldb_build_root != "":

0 commit comments

Comments
 (0)