diff options
Diffstat (limited to 'src/jsutil.cc')
| -rw-r--r-- | src/jsutil.cc | 72 |
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 |
