diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt index 132832d332c..3cd3ca0f976 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt @@ -114,9 +114,8 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper } } -private fun Properties.getSpaceSeparated(name: String): List { - return this.getProperty(name)?.split(' ')?.filter { it.isNotEmpty() } ?: emptyList() -} +private fun Properties.getSpaceSeparated(name: String): List = + this.getProperty(name)?.let { parseSpaceSeparatedArgs(it) } ?: emptyList() private fun parseDefFile(file: File?, substitutions: Map): Triple> { val properties = Properties() @@ -141,11 +140,21 @@ private fun parseDefFile(file: File?, substitutions: Map): Tripl headerLines = emptyList() } - val propertiesReader = StringReader(propertyLines.joinToString(System.lineSeparator())) + // \ isn't escaping character in quotes, so replace them with \\. + val joinedLines = propertyLines.joinToString(System.lineSeparator()) + val escapedTokens = joinedLines.split('"') + val postprocessProperties = escapedTokens.mapIndexed { index, token -> + if (index % 2 != 0) { + token.replace("""\\(?=.)""".toRegex(), Regex.escapeReplacement("""\\""")) + } else { + token + } + }.joinToString("\"") + val propertiesReader = StringReader(postprocessProperties) properties.load(propertiesReader) // Pass unsubstituted copy of properties we have obtained from `.def` - // to compiler `-maniest`. + // to compiler `-manifest`. val manifestAddendProperties = properties.duplicate() substitute(properties, substitutions) diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/Util.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/Util.kt index d3f8d6bab50..c3d3a7950d2 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/Util.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/Util.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.konan.util import kotlin.system.measureTimeMillis import org.jetbrains.kotlin.konan.file.* +import java.lang.StringBuilder // FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this function: fun printMillisec(message: String, body: () -> T): T { @@ -59,3 +60,34 @@ fun String.removeSuffixIfPresent(suffix: String) = if (this.endsWith(suffix)) this.dropLast(suffix.length) else this fun Lazy.getValueOrNull(): T? = if (isInitialized()) value else null + +fun parseSpaceSeparatedArgs(argsString: String): List { + val parsedArgs = mutableListOf() + var inQuotes = false + var currentCharSequence = StringBuilder() + fun saveArg() { + if (!currentCharSequence.isEmpty()) { + parsedArgs.add(currentCharSequence.toString()) + currentCharSequence = StringBuilder() + } + } + argsString.forEach { char -> + if (char == '"') { + inQuotes = !inQuotes + // Save value which was in quotes. + if (!inQuotes) { + saveArg() + } + } else if (char == ' ' && !inQuotes) { + // Space is separator. + saveArg() + } else { + currentCharSequence.append(char) + } + } + if (inQuotes) { + error("No close-quote was found in $currentCharSequence.") + } + saveArg() + return parsedArgs +} \ No newline at end of file