remove parselist
parent
a3c3b65251
commit
2260c1ec0a
151
cubescript.cc
151
cubescript.cc
|
@ -3801,93 +3801,6 @@ void cs_init_lib_base_loops(CsState &cs) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *liststart = nullptr, *listend = nullptr, *listquotestart = nullptr, *listquoteend = nullptr;
|
|
||||||
|
|
||||||
static inline void skiplist(const char *&p) {
|
|
||||||
for (;;) {
|
|
||||||
p += strspn(p, " \t\r\n");
|
|
||||||
if (p[0] != '/' || p[1] != '/') break;
|
|
||||||
p += strcspn(p, "\n\0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool parselist(const char *&s, const char *&start = liststart, const char *&end = listend, const char *"estart = listquotestart, const char *"eend = listquoteend) {
|
|
||||||
skiplist(s);
|
|
||||||
switch (*s) {
|
|
||||||
case '"':
|
|
||||||
quotestart = s++;
|
|
||||||
start = s;
|
|
||||||
s = parsestring(s);
|
|
||||||
end = s;
|
|
||||||
if (*s == '"') s++;
|
|
||||||
quoteend = s;
|
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
case '[':
|
|
||||||
quotestart = s;
|
|
||||||
start = s + 1;
|
|
||||||
for (int braktype = *s++, brak = 1;;) {
|
|
||||||
s += strcspn(s, "\"/;()[]\0");
|
|
||||||
int c = *s++;
|
|
||||||
switch (c) {
|
|
||||||
case '\0':
|
|
||||||
s--;
|
|
||||||
quoteend = end = s;
|
|
||||||
return true;
|
|
||||||
case '"':
|
|
||||||
s = parsestring(s);
|
|
||||||
if (*s == '"') s++;
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
if (*s == '/') s += strcspn(s, "\n\0");
|
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
case '[':
|
|
||||||
if (c == braktype) brak++;
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
if (braktype == '(' && --brak <= 0) goto endblock;
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
if (braktype == '[' && --brak <= 0) goto endblock;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endblock:
|
|
||||||
end = s - 1;
|
|
||||||
quoteend = s;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
case ')':
|
|
||||||
case ']':
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
quotestart = start = s;
|
|
||||||
s = parseword(s);
|
|
||||||
quoteend = end = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
skiplist(s);
|
|
||||||
if (*s == ';') s++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ostd::String listelem(const char *start, const char *end, const char *quotestart) {
|
|
||||||
ostd::Size len = end - start;
|
|
||||||
ostd::String s;
|
|
||||||
s.reserve(len);
|
|
||||||
if (*quotestart == '"') {
|
|
||||||
auto writer = s.iter_cap();
|
|
||||||
util::unescape_string(writer, ostd::ConstCharRange(start, end));
|
|
||||||
writer.put('\0');
|
|
||||||
} else {
|
|
||||||
memcpy(s.data(), start, len);
|
|
||||||
s[len] = '\0';
|
|
||||||
}
|
|
||||||
s.advance(len);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ListParser {
|
struct ListParser {
|
||||||
ostd::ConstCharRange input;
|
ostd::ConstCharRange input;
|
||||||
ostd::ConstCharRange quote = ostd::ConstCharRange();
|
ostd::ConstCharRange quote = ostd::ConstCharRange();
|
||||||
|
@ -4093,35 +4006,38 @@ void init_lib_list(CsState &cs) {
|
||||||
if (!numargs)
|
if (!numargs)
|
||||||
return;
|
return;
|
||||||
ostd::ConstCharRange str = args[0].get_str();
|
ostd::ConstCharRange str = args[0].get_str();
|
||||||
const char *start = str.data(),
|
ListParser p(str);
|
||||||
*end = &str[str.size()],
|
p.item = str;
|
||||||
*qstart = "";
|
|
||||||
for (int i = 1; i < numargs; ++i) {
|
for (int i = 1; i < numargs; ++i) {
|
||||||
const char *list = start;
|
p.input = str;
|
||||||
int pos = args[i].get_int();
|
int pos = args[i].get_int();
|
||||||
for (; pos > 0; --pos)
|
for (; pos > 0; --pos)
|
||||||
if (!parselist(list)) break;
|
if (!p.parse()) break;
|
||||||
if (pos > 0 || !parselist(list, start, end, qstart))
|
if (pos > 0 || !p.parse())
|
||||||
start = end = qstart = "";
|
p.item = p.quote = ostd::ConstCharRange();
|
||||||
}
|
}
|
||||||
cs.result->set_str(listelem(start, end, qstart).disown());
|
cs.result->set_str(p.element().disown());
|
||||||
});
|
});
|
||||||
|
|
||||||
cs.add_command("sublist", "siiN", [](CsState &cs, const char *s,
|
cs.add_command("sublist", "siiN", [](CsState &cs, const char *s,
|
||||||
int *skip, int *count, int *numargs) {
|
int *skip, int *count, int *numargs) {
|
||||||
int offset = ostd::max(*skip, 0),
|
int offset = ostd::max(*skip, 0),
|
||||||
len = (*numargs >= 3) ? ostd::max(*count, 0) : -1;
|
len = (*numargs >= 3) ? ostd::max(*count, 0) : -1;
|
||||||
|
ListParser p(s);
|
||||||
for (int i = 0; i < offset; ++i)
|
for (int i = 0; i < offset; ++i)
|
||||||
if (!parselist(s)) break;
|
if (!p.parse()) break;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
skiplist(s);
|
p.skip();
|
||||||
cs.result->set_str(cs_dup_ostr(s));
|
cs.result->set_str(cs_dup_ostr(p.input));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const char *list = s, *start, *end, *qstart, *qend = s;
|
|
||||||
if (len > 0 && parselist(s, start, end, list, qend))
|
const char *list = p.input.data();
|
||||||
while (--len > 0 && parselist(s, start, end, qstart, qend));
|
p.quote = ostd::ConstCharRange();
|
||||||
|
if (len > 0 && p.parse())
|
||||||
|
while (--len > 0 && p.parse());
|
||||||
|
const char *qend = !p.quote.empty() ? &p.quote[p.quote.size()] : list;
|
||||||
cs.result->set_str(cs_dup_ostr(ostd::ConstCharRange(list, qend - list)));
|
cs.result->set_str(cs_dup_ostr(ostd::ConstCharRange(list, qend - list)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4390,35 +4306,36 @@ found:
|
||||||
int *count) {
|
int *count) {
|
||||||
int offset = ostd::max(*skip, 0);
|
int offset = ostd::max(*skip, 0);
|
||||||
int len = ostd::max(*count, 0);
|
int len = ostd::max(*count, 0);
|
||||||
const char *list = s, *start, *end, *qstart, *qend = s;
|
const char *list = s;
|
||||||
|
ListParser p(s);
|
||||||
for (int i = 0; i < offset; ++i)
|
for (int i = 0; i < offset; ++i)
|
||||||
if (!parselist(s, start, end, qstart, qend))
|
if (!p.parse())
|
||||||
break;
|
break;
|
||||||
ostd::Vector<char> p;
|
const char *qend = !p.quote.empty() ? &p.quote[p.quote.size()] : list;
|
||||||
|
ostd::Vector<char> buf;
|
||||||
if (qend > list)
|
if (qend > list)
|
||||||
p.push_n(list, qend - list);
|
buf.push_n(list, qend - list);
|
||||||
if (*vals) {
|
if (*vals) {
|
||||||
if (!p.empty())
|
if (!buf.empty())
|
||||||
p.push(' ');
|
buf.push(' ');
|
||||||
p.push_n(vals, strlen(vals));
|
buf.push_n(vals, strlen(vals));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
if (!parselist(s))
|
if (!p.parse())
|
||||||
break;
|
break;
|
||||||
skiplist(s);
|
p.skip();
|
||||||
switch (*s) {
|
if (!p.input.empty()) switch (p.input.front()) {
|
||||||
case '\0':
|
|
||||||
case ')':
|
case ')':
|
||||||
case ']':
|
case ']':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!p.empty())
|
if (!buf.empty())
|
||||||
p.push(' ');
|
buf.push(' ');
|
||||||
p.push_n(s, strlen(s));
|
buf.push_n(p.input.data(), p.input.size());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p.push('\0');
|
buf.push('\0');
|
||||||
cs.result->set_str(p.disown());
|
cs.result->set_str(buf.disown());
|
||||||
});
|
});
|
||||||
|
|
||||||
cs_init_lib_list_sort(cs);
|
cs_init_lib_list_sort(cs);
|
||||||
|
|
Loading…
Reference in New Issue