Properly escape define values with spaces
Previously they were not handled properly, leading to indexing
errors.
PiperOrigin-RevId: 251724057
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index c27b703..d99ebf5 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -1041,8 +1041,8 @@
}
// Adds XCBuildConfigurations to the given indexer PBXTarget.
- // Note that preprocessorDefines is expected to be a pre-quoted set of defines (e.g., if "key" has
- // spaces it would be the string: key="value with spaces").
+ // Note that preprocessorDefines may or may not contain values with spaces. If it does contain
+ // spaces, the key will be escaped (e.g. -Dfoo bar becomes -D"foo bar").
private func addConfigsForIndexingTarget(_ target: PBXTarget, data: IndexerData) {
var buildSettings = options.buildSettingsForTarget(target.name)
@@ -1053,8 +1053,17 @@
}
var allOtherCFlags = data.otherCFlags.filter { !$0.hasPrefix("-W") }
+ // Escape the spaces in the defines by transforming -Dfoo bar into -D"foo bar".
if !data.preprocessorDefines.isEmpty {
- allOtherCFlags.append(contentsOf: data.preprocessorDefines.sorted().map({"-D\($0)"}))
+ allOtherCFlags.append(contentsOf: data.preprocessorDefines.sorted().map { define in
+ // Need to quote all defines with spaces that are not yet quoted.
+ if define.rangeOfCharacter(from: .whitespaces) != nil &&
+ !((define.hasPrefix("\"") && define.hasSuffix("\"")) ||
+ (define.hasPrefix("'") && define.hasSuffix("'"))) {
+ return "-D\"\(define)\""
+ }
+ return "-D\(define)"
+ })
}
if !allOtherCFlags.isEmpty {
diff --git a/src/TulsiGeneratorIntegrationTests/AspectTests.swift b/src/TulsiGeneratorIntegrationTests/AspectTests.swift
index 735dfc3..abd6842 100644
--- a/src/TulsiGeneratorIntegrationTests/AspectTests.swift
+++ b/src/TulsiGeneratorIntegrationTests/AspectTests.swift
@@ -278,9 +278,9 @@
.hasAttribute(.copts, value: ["-DSubLibraryWithDifferentDefines_LocalDefine",
"-DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1",
"-DSubLibraryWithDifferentDefines_STRING_DEFINE=Test",
- "-DSubLibraryWithDifferentDefines_STRING_WITH_SPACES='String with spaces'",
- "-D'SubLibraryWithDifferentDefines Define with spaces'",
- "-D'SubLibraryWithDifferentDefines Define with spaces and value'=1"] as NSArray)
+ "-DSubLibraryWithDifferentDefines_STRING_WITH_SPACES=String with spaces",
+ "-D'SubLibraryWithDifferentDefines_SINGLEQUOTED=Single quoted with spaces'",
+ "-D\"SubLibraryWithDifferentDefines_PREQUOTED=Prequoted with spaces\""] as NSArray)
.hasObjcDefines(["SubLibraryWithDifferentDefines=1"])
.hasIncludes(["tulsi_test/SubLibraryWithDifferentDefines/includes",
"tulsi-includes/x/x/tulsi_test/SubLibraryWithDifferentDefines/includes"])
diff --git a/src/TulsiGeneratorIntegrationTests/Resources/ComplexSingle.BUILD b/src/TulsiGeneratorIntegrationTests/Resources/ComplexSingle.BUILD
index addad25..45fbfce 100644
--- a/src/TulsiGeneratorIntegrationTests/Resources/ComplexSingle.BUILD
+++ b/src/TulsiGeneratorIntegrationTests/Resources/ComplexSingle.BUILD
@@ -198,9 +198,9 @@
"-DSubLibraryWithDifferentDefines_LocalDefine",
"-DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1",
"-DSubLibraryWithDifferentDefines_STRING_DEFINE=Test",
- "-DSubLibraryWithDifferentDefines_STRING_WITH_SPACES='String with spaces'",
- "-D'SubLibraryWithDifferentDefines Define with spaces'",
- "-D'SubLibraryWithDifferentDefines Define with spaces and value'=1",
+ "-DSubLibraryWithDifferentDefines_STRING_WITH_SPACES=String with spaces",
+ "-D'SubLibraryWithDifferentDefines_SINGLEQUOTED=Single quoted with spaces'",
+ "-D\"SubLibraryWithDifferentDefines_PREQUOTED=Prequoted with spaces\"",
],
defines = [
"SubLibraryWithDifferentDefines=1",
diff --git a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/ComplexSingleProject.xcodeproj/project.pbxproj b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/ComplexSingleProject.xcodeproj/project.pbxproj
index 48f0ea7..aa434ec 100644
--- a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/ComplexSingleProject.xcodeproj/project.pbxproj
+++ b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/ComplexSingleProject.xcodeproj/project.pbxproj
@@ -1125,7 +1125,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/Application/includes/first/include $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/first/include $(TULSI_WR)/tulsi_e2e_complex/Application/includes/second/include $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/second/include $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/Application/includes/first/include $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/first/include $(TULSI_BWRS)/tulsi_e2e_complex/Application/includes/second/include $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/second/include $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-DA=BINARY_DEFINE -DLIBRARY SECOND DEFINE=2 -DLIBRARY_DEFINES_DEFINE=1 -DLIBRARY_VALUE_WITH_SPACES=Value with spaces -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
+ OTHER_CFLAGS = "-DA=BINARY_DEFINE -D\"LIBRARY SECOND DEFINE=2\" -DLIBRARY_DEFINES_DEFINE=1 -D\"LIBRARY_VALUE_WITH_SPACES=Value with spaces\" -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
PRODUCT_NAME = _idx_ApplicationLibrary_3EA018EE_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
@@ -1150,7 +1150,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-DLIBRARY SECOND DEFINE=2 -DLIBRARY_COPT_DEFINE -DLIBRARY_DEFINES_DEFINE=1 -DLIBRARY_VALUE_WITH_SPACES=Value with spaces -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
+ OTHER_CFLAGS = "-D\"LIBRARY SECOND DEFINE=2\" -DLIBRARY_COPT_DEFINE -DLIBRARY_DEFINES_DEFINE=1 -D\"LIBRARY_VALUE_WITH_SPACES=Value with spaces\" -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
PRODUCT_NAME = _idx_Library_FAFE9183_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
@@ -1190,7 +1190,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-D'SubLibraryWithDifferentDefines Define with spaces and value'=1 -D'SubLibraryWithDifferentDefines Define with spaces' -DSubLibraryWithDifferentDefines=1 -DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1 -DSubLibraryWithDifferentDefines_LocalDefine -DSubLibraryWithDifferentDefines_STRING_DEFINE=Test -DSubLibraryWithDifferentDefines_STRING_WITH_SPACES='String with spaces'";
+ OTHER_CFLAGS = "-D\"SubLibraryWithDifferentDefines_PREQUOTED=Prequoted with spaces\" -D'SubLibraryWithDifferentDefines_SINGLEQUOTED=Single quoted with spaces' -DSubLibraryWithDifferentDefines=1 -DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1 -DSubLibraryWithDifferentDefines_LocalDefine -DSubLibraryWithDifferentDefines_STRING_DEFINE=Test -D\"SubLibraryWithDifferentDefines_STRING_WITH_SPACES=String with spaces\"";
PRODUCT_NAME = _idx_SubLibraryWithDifferentDefines_B982A5CC_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
@@ -1307,7 +1307,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/Application/includes/first/include $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/first/include $(TULSI_WR)/tulsi_e2e_complex/Application/includes/second/include $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/second/include $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/Application/includes/first/include $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/first/include $(TULSI_BWRS)/tulsi_e2e_complex/Application/includes/second/include $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/Application/includes/second/include $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-DA=BINARY_DEFINE -DLIBRARY SECOND DEFINE=2 -DLIBRARY_DEFINES_DEFINE=1 -DLIBRARY_VALUE_WITH_SPACES=Value with spaces -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
+ OTHER_CFLAGS = "-DA=BINARY_DEFINE -D\"LIBRARY SECOND DEFINE=2\" -DLIBRARY_DEFINES_DEFINE=1 -D\"LIBRARY_VALUE_WITH_SPACES=Value with spaces\" -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
PRODUCT_NAME = _idx_ApplicationLibrary_3EA018EE_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
@@ -1332,7 +1332,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-DLIBRARY SECOND DEFINE=2 -DLIBRARY_COPT_DEFINE -DLIBRARY_DEFINES_DEFINE=1 -DLIBRARY_VALUE_WITH_SPACES=Value with spaces -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
+ OTHER_CFLAGS = "-D\"LIBRARY SECOND DEFINE=2\" -DLIBRARY_COPT_DEFINE -DLIBRARY_DEFINES_DEFINE=1 -D\"LIBRARY_VALUE_WITH_SPACES=Value with spaces\" -DSubLibraryWithDefines=1 -DSubLibraryWithDefines_DEFINE=SubLibraryWithDefines -DSubLibraryWithDifferentDefines=1";
PRODUCT_NAME = _idx_Library_FAFE9183_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
@@ -1372,7 +1372,7 @@
GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_WR)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_WR)/_tulsi-includes/x/x/ $(TULSI_BWRS)/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_complex/SubLibraryWithDifferentDefines/includes $(TULSI_BWRS)/_tulsi-includes/x/x/ ";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
- OTHER_CFLAGS = "-D'SubLibraryWithDifferentDefines Define with spaces and value'=1 -D'SubLibraryWithDifferentDefines Define with spaces' -DSubLibraryWithDifferentDefines=1 -DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1 -DSubLibraryWithDifferentDefines_LocalDefine -DSubLibraryWithDifferentDefines_STRING_DEFINE=Test -DSubLibraryWithDifferentDefines_STRING_WITH_SPACES='String with spaces'";
+ OTHER_CFLAGS = "-D\"SubLibraryWithDifferentDefines_PREQUOTED=Prequoted with spaces\" -D'SubLibraryWithDifferentDefines_SINGLEQUOTED=Single quoted with spaces' -DSubLibraryWithDifferentDefines=1 -DSubLibraryWithDifferentDefines_INTEGER_DEFINE=1 -DSubLibraryWithDifferentDefines_LocalDefine -DSubLibraryWithDifferentDefines_STRING_DEFINE=Test -D\"SubLibraryWithDifferentDefines_STRING_WITH_SPACES=String with spaces\"";
PRODUCT_NAME = _idx_SubLibraryWithDifferentDefines_B982A5CC_ios_min10.0;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "$(TULSI_WR)";
diff --git a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
index 7ffaf03..0a7ab5b 100644
--- a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
+++ b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
@@ -2618,6 +2618,40 @@
inTargets: targets)
}
+ func testIndexerCFlagsDefinesEscaping() {
+ let package = "test/package"
+
+ let objcTargetName = "ObjcTarget"
+ let objcTargetBuildLabel = BuildLabel("\(package):\(objcTargetName)")
+ let objcTargetDefines = [
+ "A=value with space",
+ "'B=preescaped value'",
+ "\"C=preescaped value\"",
+ "D=nospaces"
+ ] as AnyObject
+
+ let objcLibraryRule = makeTestRuleEntry(objcTargetBuildLabel,
+ type: "objc_library",
+ attributes: ["compiler_defines": objcTargetDefines],
+ sourceFiles: sourceFileNames)
+
+ var processedEntries = [RuleEntry: (NSOrderedSet)]()
+ let indexerTargetName = String(format: "_idx_\(objcTargetName)_%08X_ios_min9.0", objcTargetBuildLabel.hashValue)
+ targetGenerator.registerRuleEntryForIndexer(objcLibraryRule,
+ ruleEntryMap: RuleEntryMap(),
+ pathFilters: pathFilters,
+ processedEntries: &processedEntries)
+ targetGenerator.generateIndexerTargets()
+
+ let targets = project.targetByName
+ XCTAssertEqual(targets.count, 1)
+ validateIndexerTarget(indexerTargetName,
+ sourceFileNames: sourceFileNames,
+ otherCFlags: "-D\"C=preescaped value\" -D'B=preescaped value' -D\"A=value with space\" -DD=nospaces",
+ isSwift: false,
+ inTargets: targets)
+ }
+
// MARK: - Helper methods
private func debugBuildSettingsFromSettings(_ settings: [String: String]) -> [String: String] {