summaryrefslogtreecommitdiff
path: root/src/jsutil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsutil.cc')
-rw-r--r--src/jsutil.cc72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/jsutil.cc b/src/jsutil.cc
new file mode 100644
index 0000000..ca74b48
--- /dev/null
+++ b/src/jsutil.cc
@@ -0,0 +1,72 @@
+#include "common.hh"
+
+#include "jsutil.hh"
+
+namespace js {
+
+namespace {
+
+constexpr const char kSingleQuoteChars[] = "'\0\\\n\r\v\t\b\f";
+constexpr const char kDoubleQuoteChars[] = "\"\0\\\n\r\v\t\b\f";
+
+} // namespace
+
+std::string quote(std::string_view in, QuoteChar quote_char) {
+ std::string ret;
+ quote(in, ret, quote_char);
+ return ret;
+}
+
+void quote(std::string_view in, std::string& out, QuoteChar quote_char) {
+ out.reserve(out.size() + 2 + in.size());
+ std::string_view chars;
+ switch (quote_char) {
+ case QuoteChar::SINGLE:
+ chars = std::string_view(kSingleQuoteChars, sizeof(kSingleQuoteChars) - 1);
+ break;
+ case QuoteChar::DOUBLE:
+ chars = std::string_view(kDoubleQuoteChars, sizeof(kDoubleQuoteChars) - 1);
+ break;
+ }
+ out.push_back(chars.front());
+ size_t last = 0;
+ while (true) {
+ auto next = in.find_first_of(chars, last);
+ if (next == std::string::npos) {
+ out.append(in, last);
+ break;
+ }
+ out.append(in, last, next - last);
+ out.push_back('\\');
+ switch (in[next]) {
+ case '\0':
+ out.push_back('0');
+ break;
+ case '\n':
+ out.push_back('n');
+ break;
+ case '\r':
+ out.push_back('r');
+ break;
+ case '\v':
+ out.push_back('v');
+ break;
+ case '\t':
+ out.push_back('t');
+ break;
+ case '\b':
+ out.push_back('b');
+ break;
+ case '\f':
+ out.push_back('f');
+ break;
+ default:
+ out.push_back(in[next]);
+ break;
+ }
+ last = next + 1;
+ }
+ out.push_back(chars.front());
+}
+
+} // namespace js