From 37b79aea968a97997178849d5cf874916b27ad2d Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Tue, 3 Aug 2021 08:49:56 -0500 Subject: [PATCH] [Target] Switched from escaped spaces to quoted spaces. Instead of -attr=value\ with\ spaces, will instead be written as -attr='value with spaces'. --- src/target/target.cc | 45 +++++++++++++++------ tests/python/unittest/test_target_target.py | 2 +- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/target/target.cc b/src/target/target.cc index 68a6534e88c0..ea897adb77b8 100644 --- a/src/target/target.cc +++ b/src/target/target.cc @@ -146,8 +146,10 @@ static int FindFirstSubstr(const std::string& str, const std::string& substr) { return pos == std::string::npos ? -1 : pos; } -static Optional JoinString(const std::vector& array, char separator, - char escape = '\\') { +static Optional JoinString(const std::vector& array, char separator) { + char escape = '\\'; + char quote = '\''; + if (array.empty()) { return NullOpt; } @@ -160,18 +162,27 @@ static Optional JoinString(const std::vector& array, char separa } std::string str = array[i]; - for (char c : str) { - if (c == separator) { - os << escape; + + if ((str.find(separator) == std::string::npos) && (str.find(quote) == std::string::npos)) { + os << str; + } else { + os << quote; + for (char c : str) { + if (c == separator || c == quote) { + os << escape; + } + os << c; } - os << c; + os << quote; } } return String(os.str()); } -static std::vector SplitString(const std::string& str, char separator, - char escape = '\\') { +static std::vector SplitString(const std::string& str, char separator) { + char escape = '\\'; + char quote = '\''; + std::vector output; const char* start = str.data(); @@ -188,18 +199,26 @@ static std::vector SplitString(const std::string& str, char separat } }; + bool pos_quoted = false; + while (pos < end) { - if ((*pos == escape) && (pos + 1 < end) && (pos[1] == separator)) { - current_word << separator; - pos += 2; - } else if (*pos == separator) { + if ((*pos == separator) && !pos_quoted) { finish_word(); pos++; + } else if ((*pos == escape) && (pos + 1 < end) && (pos[1] == quote)) { + current_word << quote; + pos += 2; + } else if (*pos == quote) { + pos_quoted = !pos_quoted; + pos++; } else { current_word << *pos; pos++; } } + + ICHECK(!pos_quoted) << "Mismatched quotes '' in string"; + finish_word(); return output; @@ -276,7 +295,7 @@ ObjectRef TargetInternal::ParseType(const std::string& str, // Parsing string, strip leading/trailing spaces auto start = str.find_first_not_of(' '); auto end = str.find_last_not_of(' '); - return String(str.substr(start, (end - start - 1))); + return String(str.substr(start, (end - start + 1))); } else if (info.type_index == Target::ContainerType::_GetOrAllocRuntimeTypeIndex()) { // Parsing target diff --git a/tests/python/unittest/test_target_target.py b/tests/python/unittest/test_target_target.py index 7190bb0dd3ed..5007ef13e4d8 100644 --- a/tests/python/unittest/test_target_target.py +++ b/tests/python/unittest/test_target_target.py @@ -78,7 +78,7 @@ def test_target_string_parse(): def test_target_string_with_spaces(): target = tvm.target.Target( - "vulkan -device_name=Name\ of\ GPU\ with\ spaces -device_type=discrete" + "vulkan -device_name='Name of GPU with spaces' -device_type=discrete" ) assert target.attrs["device_name"] == "Name of GPU with spaces" assert target.attrs["device_type"] == "discrete"