add range-based str parse

master
Daniel Kolesa 2015-08-12 02:11:22 +01:00
parent aaf4d1581d
commit d81b166544
1 changed files with 24 additions and 6 deletions

View File

@ -1016,6 +1016,21 @@ const char *parsestring(const char *p) {
return p; return p;
} }
ostd::ConstCharRange cs_parse_str(ostd::ConstCharRange str) {
for (; !str.empty(); str.pop_front())
switch (str.front()) {
case '\r':
case '\n':
case '\"':
return str;
case '^':
str.pop_front();
if (!str.empty()) break;
return str;
}
return str;
}
static char *conc(ostd::Vector<char> &buf, TaggedValue *v, int n, bool space, const char *prefix = nullptr, int prefixlen = 0) { static char *conc(ostd::Vector<char> &buf, TaggedValue *v, int n, bool space, const char *prefix = nullptr, int prefixlen = 0) {
if (prefix) { if (prefix) {
buf.push_n(prefix, prefixlen); buf.push_n(prefix, prefixlen);
@ -1665,12 +1680,15 @@ static bool compileblockstr(GenState &gs, ostd::ConstCharRange str, bool macro)
str.pop_front(); str.pop_front();
break; break;
case '\"': { case '\"': {
const char *start = str.data(); ostd::ConstCharRange start = str;
const char *end = parsestring(start + 1); start.pop_front();
if (*end == '\"') end++; ostd::ConstCharRange end = cs_parse_str(start);
memcpy(&buf[len], start, end - start); if (!end.empty() && (end.front() == '\"'))
len += end - start; end.pop_front();
str.pop_front_n(end - start); ostd::Size slen = str.distance_front(end);
memcpy(&buf[len], str.data(), slen);
len += slen;
str = end;
break; break;
} }
case '/': case '/':