diff options
Diffstat (limited to 'src/strings.cc')
| -rw-r--r-- | src/strings.cc | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/strings.cc b/src/strings.cc new file mode 100644 index 0000000..1d74dee --- /dev/null +++ b/src/strings.cc @@ -0,0 +1,94 @@ +// -*- mode: c++; c-basic-offset: 2; -*- + +#include "common.hh" + +#include "character.hh" +#include "strings.hh" + +// static +void Strings::trim(std::string const& str, size_t* start, size_t* end) { + assert(start && end); + assert(*start <= *end); + assert(*end <= str.size()); + while (*start < *end && Character::isspace(str, *start)) ++(*start); + while (*end > *start && Character::isspace(str, *end - 1)) --(*end); +} + +// static +std::string Strings::trim(std::string const& str) { + return trim(str, 0, str.size()); +} + +// static +std::string Strings::trim(std::string const& str, size_t start, size_t end) { + auto s = start, e = end; + trim(str, &s, &e); + return str.substr(s, e - s); +} + +// static +std::string Strings::quote(std::string const& str) { + return quote(str, 0, str.size()); +} + +// static +std::string Strings::quote(std::string const& str, size_t start, size_t end) { + assert(start <= end); + assert(end <= str.size()); + auto i = start; + while (i < end) { + auto c = str[i]; + if (c == '"' || c == '\\') break; + ++i; + } + std::string ret("\""); + if (i == end) { + ret.append(str.substr(start, end - start)); + } else { + ret.append(str.substr(start, i - start)); + while (true) { + ret.push_back('\\'); + auto j = i++; + while (i < end) { + auto c = str[i]; + if (c == '"' || c == '\\') break; + ++i; + } + ret.append(str.substr(j, i - j)); + if (i == end) break; + } + } + ret.push_back('"'); + return ret; +} + +// static +std::string Strings::unquote(std::string const& str) { + return unquote(str, 0, str.size()); +} + +// static +std::string Strings::unquote(std::string const& str, size_t start, size_t end) { + assert(start < end - 1); + assert(end <= str.size()); + assert(str[start] == '"' && str[end - 1] == '"'); + ++start; + --end; + auto i = start; + while (i < end && str[i] != '\\') ++i; + if (i == end) return str.substr(start, end - start); + std::string ret(str.substr(start, i - start)); + while (true) { + ++i; // skip backslash + if (i == end) { + assert(false); + ret.push_back('\\'); + break; + } + auto j = i++; + while (i < end && str[i] != '\\') ++i; + ret.append(str.substr(j, i - j)); + if (i == end) break; + } + return ret; +} |
