aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-07-28 16:23:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-07-28 16:23:13 +0200
commitab4c1b8a8b67fd9ffc89c804efa260584530897d (patch)
tree050bd00ec20c7668ac249cab4a9b777bc577f8d5
parentff07b9a24212fd8cb92504f51b650afd52d7d408 (diff)
Factor out and generalize/extend to_stream_quoted(string)
-rw-r--r--libbuild2/script/script.cxx45
-rw-r--r--libbuild2/utility.cxx46
-rw-r--r--libbuild2/utility.hxx33
3 files changed, 80 insertions, 44 deletions
diff --git a/libbuild2/script/script.cxx b/libbuild2/script/script.cxx
index b53fc23..ee2c9aa 100644
--- a/libbuild2/script/script.cxx
+++ b/libbuild2/script/script.cxx
@@ -237,56 +237,15 @@ namespace build2
}
}
- // Quote a string unconditionally, assuming it contains some special
- // characters.
- //
- // If the quote character is present in the string then it is double
- // quoted rather than single quoted. In this case the following characters
- // are escaped:
- //
- // \"
- //
- static void
- to_stream_quoted (ostream& o, const char* s)
- {
- if (strchr (s, '\'') != nullptr)
- {
- o << '"';
-
- for (; *s != '\0'; ++s)
- {
- // Escape characters special inside double quotes.
- //
- if (strchr ("\\\"", *s) != nullptr)
- o << '\\';
-
- o << *s;
- }
-
- o << '"';
- }
- else
- o << '\'' << s << '\'';
- }
-
- static inline void
- to_stream_quoted (ostream& o, const string& s)
- {
- to_stream_quoted (o, s.c_str ());
- }
-
// Quote if empty or contains spaces or any of the command line special
// characters.
//
- static void
+ static inline void
to_stream_q (ostream& o, const string& s)
{
// NOTE: update dump(line) if adding any new special character.
//
- if (s.empty () || s.find_first_of (" |&<>=\\\"'") != string::npos)
- to_stream_quoted (o, s);
- else
- o << s;
+ to_stream_quoted (o, s, " |&<>=\\\"'");
}
void
diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx
index 1135851..ae7c9b0 100644
--- a/libbuild2/utility.cxx
+++ b/libbuild2/utility.cxx
@@ -16,7 +16,7 @@
#endif
#include <cerrno> // ENOENT
-#include <cstring> // strlen(), str[n]cmp()
+#include <cstring> // strlen(), str[n]cmp(), strchr()
#include <iostream> // cerr
#include <libbuild2/target.hxx>
@@ -1011,4 +1011,48 @@ namespace build2
return r;
}
+
+ void
+ to_stream_quoted (ostream& o, const char* s)
+ {
+ if (strchr (s, '\'') != nullptr)
+ {
+ o << '"';
+
+ for (; *s != '\0'; ++s)
+ {
+ // Escape characters special inside double quotes.
+ //
+ if (strchr ("\\\"", *s) != nullptr)
+ o << '\\';
+
+ o << *s;
+ }
+
+ o << '"';
+ }
+ else
+ o << '\'' << s << '\'';
+ }
+
+ void
+ to_stream_quoted (ostream& o, const string& s, const char* special, bool e)
+ {
+ if ((e && s.empty ()) || s.find_first_of (special) != string::npos)
+ to_stream_quoted (o, s);
+ else
+ o << s;
+ }
+
+ void
+ to_stream_quoted (ostream& o, const strings& ss, const char* special)
+ {
+ for (auto b (ss.begin ()), i (b), e (ss.end ()); i != e; ++i)
+ {
+ if (i != b)
+ o << ' ';
+
+ to_stream_quoted (o, *i, special);
+ }
+ }
}
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index 151b409..f4fd7bc 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -1114,6 +1114,39 @@ namespace build2
//
optional<uint64_t>
parse_number (const string&, uint64_t max = UINT64_MAX);
+
+
+ // Write a string to a stream, single or double-quoting it unconditionally.
+ //
+ // If no quote characters are present in the string, then it is single-
+ // quoted. Otherwise, it is double quoted and the `\"` characters (backslach
+ // and double quote) inside the string are escaped.
+ //
+ LIBBUILD2_SYMEXPORT void
+ to_stream_quoted (ostream&, const char*);
+
+ inline void
+ to_stream_quoted (ostream& o, const string& s)
+ {
+ to_stream_quoted (o, s.c_str ());
+ }
+
+ // As above but only quote the string if it contains any of the specified
+ // special characters (which should include backslash as well as single and
+ // double quotes) or is empty (unless empty is false).
+ //
+ LIBBUILD2_SYMEXPORT void
+ to_stream_quoted (ostream&, const string&,
+ const char* special, bool empty = true);
+
+ // Write a vector of strings to a stream separating elements with a space
+ // and quoting each element if it is empty or contains any of the specified
+ // special characters (which should include space and backslash as well as
+ // single and double quotes; this is also the default which is suitable for
+ // displaying command line options, etc).
+ //
+ LIBBUILD2_SYMEXPORT void
+ to_stream_quoted (ostream&, const strings&, const char* special = " \\\"'");
}
#include <libbuild2/utility.ixx>