From b0e481a653b01e4329bccb1d101d56e3e878e960 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 3 Jun 2016 16:43:46 +0300 Subject: Port to MinGW --- build2/name.cxx | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 8 deletions(-) (limited to 'build2/name.cxx') diff --git a/build2/name.cxx b/build2/name.cxx index f3e4c0f..de1ee51 100644 --- a/build2/name.cxx +++ b/build2/name.cxx @@ -4,15 +4,69 @@ #include // Note: not +#include // strchr() + +#include + #include namespace build2 { ostream& - operator<< (ostream& os, const name& n) + to_stream (ostream& os, const name& n, bool quote, char pair) { + auto write_string = [quote, pair, &os](const string& v) + { + char sc[] = { + '{', '}', '[', ']', '$', '(', ')', // Token endings. + ' ', '\t', '\n', '#', // Spaces. + '\\', '"', // Escaping and quoting. + '%', // Project name separator. + pair, // Pair separator, if any. + '\0'}; + + if (quote && v.find ('\'') != string::npos) + { + // Quote the string with the double quotes rather than with the single + // one. Escape some of the special characters. + // + os << '"'; + + for (auto c: v) + { + if (strchr ("\\$(\"", c) != nullptr) // Special inside double quotes. + os << '\\'; + + os << c; + } + + os << '"'; + } + else if (quote && v.find_first_of (sc) != string::npos) + os << "'" << v << "'"; + else + os << v; + }; + + auto write_dir = [quote, &os, &write_string](const dir_path& d) + { + if (quote) + { + std::ostringstream s; + stream_verb (s, stream_verb (os)); + s << d; + + write_string (s.str ()); + } + else + os << d; + }; + if (n.proj != nullptr) - os << *n.proj << '%'; + { + write_string (*n.proj); + os << '%'; + } // If the value is empty, then we want to print the directory // inside {}, e.g., dir{bar/}, not bar/dir{}. We also want to @@ -23,15 +77,18 @@ namespace build2 bool t (!n.type.empty () || (!d && !v)); if (v) - os << n.dir; + write_dir (n.dir); if (t) - os << n.type << '{'; + { + write_string (n.type); + os << '{'; + } if (v) - os << n.value; + write_string (n.value); else - os << n.dir; + write_dir (n.dir); if (t) os << '}'; @@ -40,13 +97,13 @@ namespace build2 } ostream& - operator<< (ostream& os, const names_view& ns) + to_stream (ostream& os, const names_view& ns, bool quote, char pair) { for (auto i (ns.begin ()), e (ns.end ()); i != e; ) { const name& n (*i); ++i; - os << n; + to_stream (os, n, quote, pair); if (n.pair) os << n.pair; -- cgit v1.1