On 07/13/2016 02:18 PM, Vedran Miletić wrote:
OpenCL apps can quote arguments they pass to the OpenCL compiler, most commonly include paths containing spaces. If the Clang OpenCL compiler was called via a shell, the shell would split the arguments with respect to to quotes and then remove quotes before passing the arguments to the compiler. Since we call Clang as a library, we have to split the argument with respect to quotes and then remove quotes before passing the arguments. v2: move to tokenize(), remove throwing of CL_INVALID_COMPILER_OPTIONS --- src/gallium/state_trackers/clover/llvm/util.hpp | 37 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/gallium/state_trackers/clover/llvm/util.hpp b/src/gallium/state_trackers/clover/llvm/util.hpp index 8db6f20..c149542 100644 --- a/src/gallium/state_trackers/clover/llvm/util.hpp +++ b/src/gallium/state_trackers/clover/llvm/util.hpp @@ -42,11 +42,40 @@ namespace clover { inline std::vector<std::string> tokenize(const std::string &s) { std::vector<std::string> ss; - std::istringstream iss(s); - std::string t; + std::ostringstream oss; - while (getline(iss, t, ' ')) - ss.push_back(t); + // OpenCL programs can pass a single or double quoted argument, most + // frequently include path. This is useful so that the path containing + // spaces is treated as a single argument, but we should anyhow unquote + // quoted arguments before passing them to the compiler. + // We do not want to avoid using std::string::replace here, as include + // path can contain quotes in file names. + bool escape_next = false; + bool skip_space = false; + bool in_quote_double = false; + bool in_quote_single = false; + for (auto pos = std::begin(s); pos != std::end(s); ++pos) { + if (escape_next) { + oss.put(*pos); + escape_next = false; + } else if (*pos == '\\') { + escape_next = true; + } else if (*pos == '"' && !in_quote_single) { + in_quote_double = !in_quote_double; + skip_space = !skip_space; + } else if (*pos == '\'' && !in_quote_double) { + in_quote_single = !in_quote_single; + skip_space = !skip_space; + } else if (*pos == ' ' && !skip_space && oss.tellp() > 0) { + ss.emplace_back(oss.str()); + oss.str(""); + } else if (*pos != ' ' || skip_space) { + oss.put(*pos); + } + } + if (oss.tellp() > 0) { + ss.emplace_back(oss.str()); + } return ss; }
Apologies, wrongly sent e-mail. Vedran -- Vedran Miletić vedran.miletic.net _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel