use list parser more

master
Daniel Kolesa 2015-08-13 00:42:59 +01:00
parent 97b070b972
commit 146b9851fd
1 changed files with 43 additions and 58 deletions

View File

@ -3990,7 +3990,7 @@ endblock:
ostd::String element() { ostd::String element() {
ostd::String s; ostd::String s;
s.reserve(item.size()); s.reserve(item.size());
if (quote.front() == '"') { if (!quote.empty() && (quote.front() == '"')) {
auto writer = s.iter_cap(); auto writer = s.iter_cap();
util::unescape_string(writer, item); util::unescape_string(writer, item);
writer.put('\0'); writer.put('\0');
@ -4054,9 +4054,8 @@ static void cs_loop_list_conc(CsState &cs, Ident *id, const char *list,
IdentStack stack; IdentStack stack;
ostd::Vector<char> r; ostd::Vector<char> r;
int n = 0; int n = 0;
const char *s = list, *start, *end, *qstart; for (ListParser p(list); p.parse(); ++n) {
for (; parselist(s, start, end, qstart); ++n) { char *val = p.element().disown();
char *val = listelem(start, end, qstart).disown();
cs_set_iter(*id, val, stack); cs_set_iter(*id, val, stack);
if (n && space) if (n && space)
r.push(' '); r.push(' ');
@ -4074,9 +4073,8 @@ static void cs_loop_list_conc(CsState &cs, Ident *id, const char *list,
int cs_list_includes(const char *list, ostd::ConstCharRange needle) { int cs_list_includes(const char *list, ostd::ConstCharRange needle) {
int offset = 0; int offset = 0;
const char *s = list, *start, *end; for (ListParser p(list); p.parse();) {
while (parselist(s, start, end)) { if (p.item == needle)
if (ostd::ConstCharRange(start, end) == needle)
return offset; return offset;
++offset; ++offset;
} }
@ -4136,10 +4134,9 @@ void init_lib_list(CsState &cs) {
} }
IdentStack stack; IdentStack stack;
int n = -1; int n = -1;
for (const char *s = list, *start, *end; parselist(s, start, end);) { for (ListParser p(list); p.parse();) {
++n; ++n;
cs_set_iter(*id, cs_dup_ostr(ostd::ConstCharRange(start, cs_set_iter(*id, cs_dup_ostr(p.item), stack);
end - start)), stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
cs.result->set_int(n); cs.result->set_int(n);
goto found; goto found;
@ -4158,17 +4155,15 @@ found:
return; return;
IdentStack stack; IdentStack stack;
int n = -1; int n = -1;
const char *s = list, *start, *end, *qstart; for (ListParser p(list); p.parse();) {
while (parselist(s, start, end)) {
++n; ++n;
cs_set_iter(*id, cs_dup_ostr(ostd::ConstCharRange(start, cs_set_iter(*id, cs_dup_ostr(p.item), stack);
end - start)), stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (parselist(s, start, end, qstart)) if (p.parse())
cs.result->set_str(listelem(start, end, qstart).disown()); cs.result->set_str(p.element().disown());
break; break;
} }
if (!parselist(s)) if (!p.parse())
break; break;
} }
if (n >= 0) if (n >= 0)
@ -4180,14 +4175,13 @@ found:
type *val, int *skip) { \ type *val, int *skip) { \
int n = 0; \ int n = 0; \
init; \ init; \
const char *s = list, *start, *end, *qstart; \ for (ListParser p(list); p.parse(); ++n) { \
for (; parselist(s, start, end, qstart); ++n) { \
if (cmp) { \ if (cmp) { \
cs.result->set_int(n); \ cs.result->set_int(n); \
return; \ return; \
} \ } \
for (int i = 0; i < *skip; ++i) { \ for (int i = 0; i < *skip; ++i) { \
if (!parselist(s)) \ if (!p.parse()) \
goto notfound; \ goto notfound; \
++n; \ ++n; \
} \ } \
@ -4196,32 +4190,31 @@ found:
cs.result->set_int(-1); \ cs.result->set_int(-1); \
}); });
CS_CMD_LIST_FIND("listfind=", "i", int, {}, parseint(start) == *val); CS_CMD_LIST_FIND("listfind=", "i", int, {}, cs_parse_int(p.item) == *val);
CS_CMD_LIST_FIND("listfind=f", "f", float, {}, parsefloat(start) == *val); CS_CMD_LIST_FIND("listfind=f", "f", float, {}, cs_parse_float(p.item) == *val);
CS_CMD_LIST_FIND("listfind=s", "s", char, int len = (int)strlen(val), CS_CMD_LIST_FIND("listfind=s", "s", char, ostd::Size len = strlen(val),
int(end - start) == len && !memcmp(start, val, len)); p.item == ostd::ConstCharRange(val, len));
#undef CS_CMD_LIST_FIND #undef CS_CMD_LIST_FIND
#define CS_CMD_LIST_ASSOC(name, fmt, type, init, cmp) \ #define CS_CMD_LIST_ASSOC(name, fmt, type, init, cmp) \
cs.add_command(name, "s" fmt, [](CsState &cs, char *list, type *val) { \ cs.add_command(name, "s" fmt, [](CsState &cs, char *list, type *val) { \
init; \ init; \
const char *s = list, *start, *end, *qstart; \ for (ListParser p(list); p.parse();) { \
while (parselist(s, start, end)) { \
if (cmp) { \ if (cmp) { \
if (parselist(s, start, end, qstart)) \ if (p.parse()) \
cs.result->set_str(listelem(start, end, qstart).disown()); \ cs.result->set_str(p.element().disown()); \
return; \ return; \
} \ } \
if (!parselist(s)) \ if (!p.parse()) \
break; \ break; \
} \ } \
}); });
CS_CMD_LIST_ASSOC("listassoc=", "i", int, {}, parseint(start) == *val); CS_CMD_LIST_ASSOC("listassoc=", "i", int, {}, cs_parse_int(p.item) == *val);
CS_CMD_LIST_ASSOC("listassoc=f", "f", float, {}, parsefloat(start) == *val); CS_CMD_LIST_ASSOC("listassoc=f", "f", float, {}, cs_parse_float(p.item) == *val);
CS_CMD_LIST_ASSOC("listassoc=s", "s", char, int len = (int)strlen(val), CS_CMD_LIST_ASSOC("listassoc=s", "s", char, ostd::Size len = strlen(val),
int(end - start) == len && !memcmp(start, val, len)); p.item == ostd::ConstCharRange(val, len));
#undef CS_CMD_LIST_ASSOC #undef CS_CMD_LIST_ASSOC
@ -4232,9 +4225,8 @@ found:
return; return;
IdentStack stack; IdentStack stack;
int n = 0; int n = 0;
const char *s = list, *start, *end, *qstart; for (ListParser p(list); p.parse(); ++n) {
for (; parselist(s, start, end, qstart); ++n) { cs_set_iter(*id, p.element().disown(), stack);
cs_set_iter(*id, listelem(start, end, qstart).disown(), stack);
cs.run_int(body); cs.run_int(body);
} }
if (n >= 0) if (n >= 0)
@ -4248,12 +4240,10 @@ found:
return; return;
IdentStack stack, stack2; IdentStack stack, stack2;
int n = 0; int n = 0;
const char *s = list, *start, *end, *qstart; for (ListParser p(list); p.parse(); n += 2) {
for (; parselist(s, start, end, qstart); n += 2) { cs_set_iter(*id, p.element().disown(), stack);
cs_set_iter(*id, listelem(start, end, qstart).disown(), stack); cs_set_iter(*id2, p.parse() ? p.element().disown()
cs_set_iter(*id2, parselist(s, start, end, qstart) : cs_dup_ostr(""), stack2);
? listelem(start, end, qstart).disown()
: cs_dup_ostr(""), stack2);
cs.run_int(body); cs.run_int(body);
} }
if (n >= 0) { if (n >= 0) {
@ -4272,15 +4262,12 @@ found:
return; return;
IdentStack stack, stack2, stack3; IdentStack stack, stack2, stack3;
int n = 0; int n = 0;
const char *s = list, *start, *end, *qstart; for (ListParser p(list); p.parse(); n += 3) {
for (; parselist(s, start, end, qstart); n += 3) { cs_set_iter(*id, p.element().disown(), stack);
cs_set_iter(*id, listelem(start, end, qstart).disown(), stack); cs_set_iter(*id2, p.parse() ? p.element().disown()
cs_set_iter(*id2, parselist(s, start, end, qstart) : cs_dup_ostr(""), stack2);
? listelem(start, end, qstart).disown() cs_set_iter(*id3, p.parse() ? p.element().disown()
: cs_dup_ostr(""), stack2); : cs_dup_ostr(""), stack3);
cs_set_iter(*id3, parselist(s, start, end, qstart)
? listelem(start, end, qstart).disown()
: cs_dup_ostr(""), stack3);
cs.run_int(body); cs.run_int(body);
} }
if (n >= 0) { if (n >= 0) {
@ -4310,13 +4297,12 @@ found:
IdentStack stack; IdentStack stack;
ostd::Vector<char> r; ostd::Vector<char> r;
int n = 0; int n = 0;
const char *s = list, *start, *end, *qstart, *qend; for (ListParser p(list); p.parse(); ++n) {
for (; parselist(s, start, end, qstart, qend); ++n) { char *val = cs_dup_ostr(p.item);
char *val = cs_dup_ostr(ostd::ConstCharRange(start, end - start));
cs_set_iter(*id, val, stack); cs_set_iter(*id, val, stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (r.size()) r.push(' '); if (r.size()) r.push(' ');
r.push_n(qstart, qend - qstart); r.push_n(p.quote.data(), p.quote.size());
} }
} }
if (n >= 0) if (n >= 0)
@ -4332,9 +4318,8 @@ found:
return; return;
IdentStack stack; IdentStack stack;
int n = 0, r = 0; int n = 0, r = 0;
const char *s = list, *start, *end; for (ListParser p(list); p.parse(); ++n) {
for (; parselist(s, start, end); ++n) { char *val = cs_dup_ostr(p.item);
char *val = cs_dup_ostr(ostd::ConstCharRange(start, end - start));
cs_set_iter(*id, val, stack); cs_set_iter(*id, val, stack);
if (cs.run_bool(body)) if (cs.run_bool(body))
r++; r++;