Mesa (master): clover: Pass unquoted compiler arguments to Clang

Francisco Jerez currojerez at kemper.freedesktop.org
Sun Oct 30 19:19:19 UTC 2016


Module: Mesa
Branch: master
Commit: e3272865c216933168e6c08766d266a33d0e1497
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e3272865c216933168e6c08766d266a33d0e1497

Author: Vedran Miletić <vedran at miletic.net>
Date:   Wed Sep 28 17:11:43 2016 +0200

clover: Pass unquoted compiler arguments to Clang

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

v3: simplify parsing logic, use more C++11

v4: restore error throwing, clarify a comment

Signed-off-by: Vedran Miletić <vedran at miletic.net>
Reviewed-by: Francisco Jerez <currojerez at riseup.net>

---

 src/gallium/state_trackers/clover/llvm/util.hpp | 40 ++++++++++++++++++++++---
 1 file changed, 36 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..222becd 100644
--- a/src/gallium/state_trackers/clover/llvm/util.hpp
+++ b/src/gallium/state_trackers/clover/llvm/util.hpp
@@ -24,6 +24,7 @@
 #ifndef CLOVER_LLVM_UTIL_HPP
 #define CLOVER_LLVM_UTIL_HPP
 
+#include "core/error.hpp"
 #include "util/u_debug.h"
 
 #include <vector>
@@ -42,11 +43,42 @@ 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 quoted argument, most frequently the
+         // include path. This is useful so that path containing spaces is
+         // treated as a single argument instead of being split by the spaces.
+         // Additionally, the argument should also be unquoted before being
+         // passed to the compiler. We avoid using std::string::replace here to
+         // remove quotes, as the single and double quote characters can be a
+         // part of the file name.
+         bool escape_next = false;
+         bool in_quote_double = false;
+         bool in_quote_single = false;
+
+         for (auto c : s) {
+            if (escape_next) {
+               oss.put(c);
+               escape_next = false;
+            } else if (c == '\\') {
+               escape_next = true;
+            } else if (c == '"' && !in_quote_single) {
+               in_quote_double = !in_quote_double;
+            } else if (c == '\'' && !in_quote_double) {
+               in_quote_single = !in_quote_single;
+            } else if (c != ' ' || in_quote_single || in_quote_double) {
+               oss.put(c);
+            } else if (oss.tellp() > 0) {
+               ss.emplace_back(oss.str());
+               oss.str("");
+            }
+         }
+
+         if (oss.tellp() > 0)
+            ss.emplace_back(oss.str());
+
+         if (in_quote_double || in_quote_single)
+            throw invalid_build_options_error();
 
          return ss;
       }




More information about the mesa-commit mailing list