replace list_parser with a simpler api
parent
704f9217f7
commit
9d0494a9da
|
@ -75,6 +75,7 @@ struct OSTD_EXPORT cs_strref {
|
|||
|
||||
cs_strref() = delete;
|
||||
cs_strref(cs_shared_state &cs, ostd::string_range str);
|
||||
cs_strref(cs_state &cs, ostd::string_range str);
|
||||
|
||||
cs_strref(cs_strref const &ref);
|
||||
|
||||
|
@ -379,6 +380,7 @@ static inline void *cs_default_alloc(void *, void *p, size_t, size_t ns) {
|
|||
struct OSTD_EXPORT cs_state {
|
||||
friend struct cs_error;
|
||||
friend struct cs_strman;
|
||||
friend struct cs_strref;
|
||||
friend struct cs_value;
|
||||
friend struct cs_gen_state;
|
||||
|
||||
|
@ -649,6 +651,19 @@ private:
|
|||
bool p_pushed;
|
||||
};
|
||||
|
||||
struct cs_list_parse_state {
|
||||
cs_list_parse_state(ostd::string_range s = ostd::string_range{}): input{s} {}
|
||||
|
||||
ostd::string_range input{};
|
||||
ostd::string_range item{};
|
||||
ostd::string_range quoted_item{};
|
||||
};
|
||||
|
||||
OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs);
|
||||
OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs);
|
||||
OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs);
|
||||
OSTD_EXPORT void list_find_item(cs_list_parse_state &ps);
|
||||
|
||||
namespace util {
|
||||
template<typename R>
|
||||
inline R &&escape_string(R &&writer, ostd::string_range str) {
|
||||
|
@ -743,90 +758,6 @@ namespace util {
|
|||
cs_state &cs, ostd::string_range str
|
||||
);
|
||||
|
||||
struct list_range;
|
||||
|
||||
struct OSTD_EXPORT list_parser {
|
||||
list_parser() = delete;
|
||||
list_parser(cs_state &cs, ostd::string_range src):
|
||||
p_state(cs), p_input(src)
|
||||
{}
|
||||
|
||||
void skip();
|
||||
bool parse();
|
||||
size_t count();
|
||||
|
||||
template<typename R>
|
||||
R &&get_item(R &&writer) const {
|
||||
if (!p_quote.empty() && (*p_quote == '"')) {
|
||||
return unescape_string(std::forward<R>(writer), p_item);
|
||||
} else {
|
||||
ostd::range_put_all(writer, p_item);
|
||||
return std::forward<R>(writer);
|
||||
}
|
||||
}
|
||||
|
||||
cs_string get_item() const {
|
||||
return std::move(get_item(ostd::appender<cs_string>()).get());
|
||||
}
|
||||
|
||||
ostd::string_range &get_raw_item(bool quoted = false) {
|
||||
return quoted ? p_quote : p_item;
|
||||
}
|
||||
|
||||
ostd::string_range const &get_raw_item(bool quoted = false) const {
|
||||
return quoted ? p_quote : p_item;
|
||||
}
|
||||
|
||||
ostd::string_range &get_input() {
|
||||
return p_input;
|
||||
}
|
||||
|
||||
list_range iter() noexcept;
|
||||
|
||||
private:
|
||||
ostd::string_range p_quote = ostd::string_range();
|
||||
ostd::string_range p_item = ostd::string_range();
|
||||
cs_state &p_state;
|
||||
ostd::string_range p_input;
|
||||
};
|
||||
|
||||
struct list_range: ostd::input_range<list_range> {
|
||||
using range_category = ostd::forward_range_tag;
|
||||
using value_type = ostd::string_range;
|
||||
using reference = ostd::string_range;
|
||||
using size_type = std::size_t;
|
||||
|
||||
list_range() = delete;
|
||||
|
||||
list_range(list_parser &p) noexcept: p_parser(&p) {
|
||||
pop_front();
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return !bool(p_item);
|
||||
}
|
||||
|
||||
void pop_front() noexcept {
|
||||
if (p_parser->parse()) {
|
||||
p_item = p_parser->get_item();
|
||||
} else {
|
||||
p_item.reset();
|
||||
}
|
||||
}
|
||||
|
||||
ostd::string_range front() const noexcept {
|
||||
return *p_item;
|
||||
}
|
||||
|
||||
private:
|
||||
list_parser *p_parser;
|
||||
std::optional<cs_string> p_item{};
|
||||
};
|
||||
|
||||
inline list_range list_parser::iter() noexcept {
|
||||
return list_range{*this};
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
inline void format_int(R &&writer, cs_int val) {
|
||||
try {
|
||||
|
|
|
@ -17,14 +17,10 @@ ostd::string_range cs_gen_state::get_str() {
|
|||
return ret.slice(1, ret.size() - 1);
|
||||
}
|
||||
|
||||
cs_string cs_gen_state::get_str_dup(bool unescape) {
|
||||
cs_string cs_gen_state::get_str_dup() {
|
||||
auto str = get_str();
|
||||
auto app = ostd::appender<cs_string>();
|
||||
if (unescape) {
|
||||
util::unescape_string(app, str);
|
||||
} else {
|
||||
app.get() = str;
|
||||
}
|
||||
util::unescape_string(app, str);
|
||||
return std::move(app.get());
|
||||
}
|
||||
|
||||
|
|
215
src/cs_util.cc
215
src/cs_util.cc
|
@ -357,107 +357,120 @@ end:
|
|||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void list_parser::skip() {
|
||||
for (;;) {
|
||||
while (!p_input.empty()) {
|
||||
char c = *p_input;
|
||||
if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) {
|
||||
++p_input;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((p_input.size() < 2) || (p_input[0] != '/') || (p_input[1] != '/')) {
|
||||
break;
|
||||
}
|
||||
p_input = ostd::find(p_input, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
bool list_parser::parse() {
|
||||
skip();
|
||||
if (p_input.empty()) {
|
||||
return false;
|
||||
}
|
||||
switch (*p_input) {
|
||||
case '"':
|
||||
p_quote = p_input;
|
||||
p_input = parse_string(p_state, p_input);
|
||||
p_quote = p_quote.slice(0, &p_input[0] - &p_quote[0]);
|
||||
p_item = p_quote.slice(1, p_quote.size() - 1);
|
||||
break;
|
||||
case '(':
|
||||
case '[': {
|
||||
p_quote = p_input;
|
||||
++p_input;
|
||||
p_item = p_input;
|
||||
char btype = *p_quote;
|
||||
int brak = 1;
|
||||
for (;;) {
|
||||
p_input = ostd::find_one_of(
|
||||
p_input, ostd::string_range("\"/;()[]")
|
||||
);
|
||||
if (p_input.empty()) {
|
||||
return true;
|
||||
}
|
||||
char c = *p_input;
|
||||
++p_input;
|
||||
switch (c) {
|
||||
case '"':
|
||||
p_input = parse_string(p_state, p_input);
|
||||
break;
|
||||
case '/':
|
||||
if (!p_input.empty() && (*p_input == '/')) {
|
||||
p_input = ostd::find(p_input, '\n');
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
case '[':
|
||||
brak += (c == btype);
|
||||
break;
|
||||
case ')':
|
||||
if ((btype == '(') && (--brak <= 0)) {
|
||||
goto endblock;
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if ((btype == '[') && (--brak <= 0)) {
|
||||
goto endblock;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
endblock:
|
||||
p_item = p_item.slice(0, &p_input[0] - &p_item[0]);
|
||||
p_item.pop_back();
|
||||
p_quote = p_quote.slice(0, &p_input[0] - &p_quote[0]);
|
||||
break;
|
||||
}
|
||||
case ')':
|
||||
case ']':
|
||||
return false;
|
||||
default: {
|
||||
ostd::string_range e = parse_word(p_state, p_input);
|
||||
p_quote = p_item = p_input.slice(0, &e[0] - &p_input[0]);
|
||||
p_input = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
skip();
|
||||
if (!p_input.empty() && (*p_input == ';')) {
|
||||
++p_input;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t list_parser::count() {
|
||||
size_t ret = 0;
|
||||
while (parse()) {
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} /* namespace util */
|
||||
|
||||
OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) {
|
||||
list_find_item(ps);
|
||||
if (ps.input.empty()) {
|
||||
return false;
|
||||
}
|
||||
switch (*ps.input) {
|
||||
case '"':
|
||||
ps.quoted_item = ps.input;
|
||||
ps.input = util::parse_string(cs, ps.input);
|
||||
ps.quoted_item = ps.quoted_item.slice(
|
||||
0, &ps.input[0] - &ps.quoted_item[0]
|
||||
);
|
||||
ps.item = ps.quoted_item.slice(1, ps.quoted_item.size() - 1);
|
||||
break;
|
||||
case '(':
|
||||
case '[': {
|
||||
ps.quoted_item = ps.input;
|
||||
++ps.input;
|
||||
ps.item = ps.input;
|
||||
char btype = *ps.quoted_item;
|
||||
int brak = 1;
|
||||
for (;;) {
|
||||
ps.input = ostd::find_one_of(
|
||||
ps.input, ostd::string_range("\"/;()[]")
|
||||
);
|
||||
if (ps.input.empty()) {
|
||||
return true;
|
||||
}
|
||||
char c = *ps.input;
|
||||
++ps.input;
|
||||
switch (c) {
|
||||
case '"':
|
||||
ps.input = util::parse_string(cs, ps.input);
|
||||
break;
|
||||
case '/':
|
||||
if (!ps.input.empty() && (*ps.input == '/')) {
|
||||
ps.input = ostd::find(ps.input, '\n');
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
case '[':
|
||||
brak += (c == btype);
|
||||
break;
|
||||
case ')':
|
||||
if ((btype == '(') && (--brak <= 0)) {
|
||||
goto endblock;
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if ((btype == '[') && (--brak <= 0)) {
|
||||
goto endblock;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
endblock:
|
||||
ps.item = ps.item.slice(0, &ps.input[0] - &ps.item[0]);
|
||||
ps.item.pop_back();
|
||||
ps.quoted_item = ps.quoted_item.slice(
|
||||
0, &ps.input[0] - &ps.quoted_item[0]
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ')':
|
||||
case ']':
|
||||
return false;
|
||||
default: {
|
||||
ostd::string_range e = util::parse_word(cs, ps.input);
|
||||
ps.quoted_item = ps.item = ps.input.slice(0, &e[0] - &ps.input[0]);
|
||||
ps.input = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_find_item(ps);
|
||||
if (!ps.input.empty() && (*ps.input == ';')) {
|
||||
++ps.input;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) {
|
||||
size_t ret = 0;
|
||||
while (list_parse(ps, cs)) {
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) {
|
||||
if (!ps.quoted_item.empty() && (*ps.quoted_item == '"')) {
|
||||
auto app = ostd::appender<cs_string>();
|
||||
util::unescape_string(app, ps.item);
|
||||
return cs_strref{cs, app.get()};
|
||||
}
|
||||
return cs_strref{cs, ps.item};
|
||||
}
|
||||
|
||||
OSTD_EXPORT void list_find_item(cs_list_parse_state &ps) {
|
||||
for (;;) {
|
||||
while (!ps.input.empty()) {
|
||||
char c = *ps.input;
|
||||
if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) {
|
||||
++ps.input;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((ps.input.size() < 2) || (ps.input[0] != '/') || (ps.input[1] != '/')) {
|
||||
break;
|
||||
}
|
||||
ps.input = ostd::find(ps.input, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace cscript */
|
||||
|
|
|
@ -13,6 +13,12 @@ cs_strref::cs_strref(cs_shared_state &cs, ostd::string_range str):
|
|||
p_str = cs.strman->add(str);
|
||||
}
|
||||
|
||||
cs_strref::cs_strref(cs_state &cs, ostd::string_range str):
|
||||
p_state{cs.p_state}
|
||||
{
|
||||
p_str = p_state->strman->add(str);
|
||||
}
|
||||
|
||||
cs_strref::cs_strref(cs_strref const &ref): p_state{ref.p_state}, p_str{ref.p_str}
|
||||
{
|
||||
p_state->strman->ref(p_str);
|
||||
|
|
|
@ -195,7 +195,7 @@ struct cs_gen_state {
|
|||
}
|
||||
|
||||
ostd::string_range get_str();
|
||||
cs_string get_str_dup(bool unescape = true);
|
||||
cs_string get_str_dup();
|
||||
|
||||
ostd::string_range get_word();
|
||||
|
||||
|
|
171
src/lib_list.cc
171
src/lib_list.cc
|
@ -35,13 +35,13 @@ static inline void cs_list_find(
|
|||
) {
|
||||
cs_int n = 0, skip = args[2].get_int();
|
||||
T val = cs_arg_val<T>::get(args[1]);
|
||||
for (util::list_parser p(cs, args[0].get_str()); p.parse(); ++n) {
|
||||
for (cs_list_parse_state p{args[0].get_str()}; list_parse(p, cs); ++n) {
|
||||
if (cmp(p, val)) {
|
||||
res.set_int(n);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < skip; ++i) {
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
goto notfound;
|
||||
}
|
||||
++n;
|
||||
|
@ -56,14 +56,14 @@ static inline void cs_list_assoc(
|
|||
cs_state &cs, cs_value_r args, cs_value &res, F cmp
|
||||
) {
|
||||
T val = cs_arg_val<T>::get(args[1]);
|
||||
for (util::list_parser p(cs, args[0].get_str()); p.parse();) {
|
||||
for (cs_list_parse_state p{args[0].get_str()}; list_parse(p, cs);) {
|
||||
if (cmp(p, val)) {
|
||||
if (p.parse()) {
|
||||
res.set_str(p.get_item());
|
||||
if (list_parse(p, cs)) {
|
||||
res.set_str(list_get_item(p, cs));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +79,8 @@ static void cs_loop_list_conc(
|
|||
}
|
||||
cs_string r;
|
||||
int n = 0;
|
||||
for (util::list_parser p(cs, list); p.parse(); ++n) {
|
||||
idv.set_str(p.get_item());
|
||||
for (cs_list_parse_state p{list}; list_parse(p, cs); ++n) {
|
||||
idv.set_str(list_get_item(p, cs));
|
||||
idv.push();
|
||||
if (n && space) {
|
||||
r += ' ';
|
||||
|
@ -104,8 +104,8 @@ int cs_list_includes(
|
|||
cs_state &cs, ostd::string_range list, ostd::string_range needle
|
||||
) {
|
||||
int offset = 0;
|
||||
for (util::list_parser p(cs, list); p.parse();) {
|
||||
if (p.get_raw_item() == needle) {
|
||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
||||
if (p.item == needle) {
|
||||
return offset;
|
||||
}
|
||||
++offset;
|
||||
|
@ -126,12 +126,12 @@ static inline void cs_list_merge(
|
|||
if (Swap) {
|
||||
std::swap(list, elems);
|
||||
}
|
||||
for (util::list_parser p(cs, list); p.parse();) {
|
||||
if (cmp(cs_list_includes(cs, elems, p.get_raw_item()), 0)) {
|
||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
||||
if (cmp(cs_list_includes(cs, elems, p.item), 0)) {
|
||||
if (!buf.empty()) {
|
||||
buf += ' ';
|
||||
}
|
||||
buf += p.get_raw_item(true);
|
||||
buf += p.quoted_item;
|
||||
}
|
||||
}
|
||||
res.set_str(buf);
|
||||
|
@ -141,7 +141,8 @@ static void cs_init_lib_list_sort(cs_state &cs);
|
|||
|
||||
void cs_init_lib_list(cs_state &gcs) {
|
||||
gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) {
|
||||
res.set_int(cs_int(util::list_parser(cs, args[0].get_str()).count()));
|
||||
cs_list_parse_state p{args[0].get_str()};
|
||||
res.set_int(cs_int(list_count(p, cs)));
|
||||
});
|
||||
|
||||
gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) {
|
||||
|
@ -149,51 +150,51 @@ void cs_init_lib_list(cs_state &gcs) {
|
|||
return;
|
||||
}
|
||||
cs_strref str = args[0].get_str();
|
||||
util::list_parser p(cs, str);
|
||||
p.get_raw_item() = str;
|
||||
cs_list_parse_state p{str};
|
||||
p.item = str;
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
p.get_input() = str;
|
||||
p.input = str;
|
||||
cs_int pos = args[i].get_int();
|
||||
for (; pos > 0; --pos) {
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos > 0 || !p.parse()) {
|
||||
p.get_raw_item() = p.get_raw_item(true) = ostd::string_range();
|
||||
if (pos > 0 || !list_parse(p, cs)) {
|
||||
p.item = p.quoted_item = ostd::string_range();
|
||||
}
|
||||
}
|
||||
res.set_str(p.get_item());
|
||||
res.set_str(list_get_item(p, cs));
|
||||
});
|
||||
|
||||
gcs.new_command("sublist", "siiN", [](auto &cs, auto args, auto &res) {
|
||||
cs_int skip = args[1].get_int(),
|
||||
cs_int skip = args[1].get_int(),
|
||||
count = args[2].get_int(),
|
||||
numargs = args[3].get_int();
|
||||
|
||||
cs_int offset = std::max(skip, cs_int(0)),
|
||||
len = (numargs >= 3) ? std::max(count, cs_int(0)) : -1;
|
||||
|
||||
util::list_parser p(cs, args[0].get_str());
|
||||
cs_list_parse_state p{args[0].get_str()};
|
||||
for (cs_int i = 0; i < offset; ++i) {
|
||||
if (!p.parse()) break;
|
||||
if (!list_parse(p, cs)) break;
|
||||
}
|
||||
if (len < 0) {
|
||||
if (offset > 0) {
|
||||
p.skip();
|
||||
list_find_item(p);
|
||||
}
|
||||
res.set_str(cs_string{p.get_input()});
|
||||
res.set_str(cs_string{p.input});
|
||||
return;
|
||||
}
|
||||
|
||||
char const *list = p.get_input().data();
|
||||
p.get_raw_item(true) = ostd::string_range();
|
||||
if (len > 0 && p.parse()) {
|
||||
while (--len > 0 && p.parse());
|
||||
char const *list = p.input.data();
|
||||
p.quoted_item = ostd::string_range();
|
||||
if (len > 0 && list_parse(p, cs)) {
|
||||
while (--len > 0 && list_parse(p, cs));
|
||||
}
|
||||
ostd::string_range quote = p.get_raw_item(true);
|
||||
ostd::string_range quote = p.quoted_item;
|
||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
||||
res.set_str(cs_string{list, size_t(qend - list)});
|
||||
res.set_str(ostd::string_range{list, qend});
|
||||
});
|
||||
|
||||
gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) {
|
||||
|
@ -204,9 +205,9 @@ void cs_init_lib_list(cs_state &gcs) {
|
|||
}
|
||||
auto body = args[2].get_code();
|
||||
int n = -1;
|
||||
for (util::list_parser p(cs, args[1].get_str()); p.parse();) {
|
||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs);) {
|
||||
++n;
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.item});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
res.set_int(cs_int(n));
|
||||
|
@ -223,17 +224,17 @@ void cs_init_lib_list(cs_state &gcs) {
|
|||
}
|
||||
auto body = args[2].get_code();
|
||||
int n = -1;
|
||||
for (util::list_parser p(cs, args[1].get_str()); p.parse();) {
|
||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs);) {
|
||||
++n;
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.item});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
if (p.parse()) {
|
||||
res.set_str(p.get_item());
|
||||
if (list_parse(p, cs)) {
|
||||
res.set_str(list_get_item(p, cs));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -241,44 +242,44 @@ void cs_init_lib_list(cs_state &gcs) {
|
|||
|
||||
gcs.new_command("listfind=", "i", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_find<cs_int>(
|
||||
cs, args, res, [](const util::list_parser &p, cs_int val) {
|
||||
return cs_parse_int(p.get_raw_item()) == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, cs_int val) {
|
||||
return cs_parse_int(p.item) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listfind=f", "f", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_find<cs_float>(
|
||||
cs, args, res, [](const util::list_parser &p, cs_float val) {
|
||||
return cs_parse_float(p.get_raw_item()) == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, cs_float val) {
|
||||
return cs_parse_float(p.item) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listfind=s", "s", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_find<ostd::string_range>(
|
||||
cs, args, res, [](const util::list_parser &p, ostd::string_range val) {
|
||||
return p.get_raw_item() == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, ostd::string_range val) {
|
||||
return p.item == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
gcs.new_command("listassoc=", "i", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_assoc<cs_int>(
|
||||
cs, args, res, [](const util::list_parser &p, cs_int val) {
|
||||
return cs_parse_int(p.get_raw_item()) == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, cs_int val) {
|
||||
return cs_parse_int(p.item) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listassoc=f", "f", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_assoc<cs_float>(
|
||||
cs, args, res, [](const util::list_parser &p, cs_float val) {
|
||||
return cs_parse_float(p.get_raw_item()) == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, cs_float val) {
|
||||
return cs_parse_float(p.item) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listassoc=s", "s", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_assoc<ostd::string_range>(
|
||||
cs, args, res, [](const util::list_parser &p, ostd::string_range val) {
|
||||
return p.get_raw_item() == val;
|
||||
cs, args, res, [](cs_list_parse_state const &p, ostd::string_range val) {
|
||||
return p.item == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -290,8 +291,8 @@ void cs_init_lib_list(cs_state &gcs) {
|
|||
}
|
||||
auto body = args[2].get_code();
|
||||
int n = 0;
|
||||
for (util::list_parser p(cs, args[1].get_str()); p.parse(); ++n) {
|
||||
idv.set_str(p.get_item());
|
||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
||||
idv.set_str(list_get_item(p, cs));
|
||||
idv.push();
|
||||
switch (cs.run_loop(body)) {
|
||||
case cs_loop_state::BREAK:
|
||||
|
@ -312,10 +313,10 @@ end:
|
|||
}
|
||||
auto body = args[3].get_code();
|
||||
int n = 0;
|
||||
for (util::list_parser p(cs, args[2].get_str()); p.parse(); n += 2) {
|
||||
idv1.set_str(p.get_item());
|
||||
if (p.parse()) {
|
||||
idv2.set_str(p.get_item());
|
||||
for (cs_list_parse_state p{args[2].get_str()}; list_parse(p, cs); n += 2) {
|
||||
idv1.set_str(list_get_item(p, cs));
|
||||
if (list_parse(p, cs)) {
|
||||
idv2.set_str(list_get_item(p, cs));
|
||||
} else {
|
||||
idv2.set_str("");
|
||||
}
|
||||
|
@ -341,15 +342,15 @@ end:
|
|||
}
|
||||
auto body = args[4].get_code();
|
||||
int n = 0;
|
||||
for (util::list_parser p(cs, args[3].get_str()); p.parse(); n += 3) {
|
||||
idv1.set_str(p.get_item());
|
||||
if (p.parse()) {
|
||||
idv2.set_str(p.get_item());
|
||||
for (cs_list_parse_state p{args[3].get_str()}; list_parse(p, cs); n += 3) {
|
||||
idv1.set_str(list_get_item(p, cs));
|
||||
if (list_parse(p, cs)) {
|
||||
idv2.set_str(list_get_item(p, cs));
|
||||
} else {
|
||||
idv2.set_str("");
|
||||
}
|
||||
if (p.parse()) {
|
||||
idv3.set_str(p.get_item());
|
||||
if (list_parse(p, cs)) {
|
||||
idv3.set_str(list_get_item(p, cs));
|
||||
} else {
|
||||
idv3.set_str("");
|
||||
}
|
||||
|
@ -391,14 +392,14 @@ end:
|
|||
auto body = args[2].get_code();
|
||||
cs_string r;
|
||||
int n = 0;
|
||||
for (util::list_parser p(cs, args[1].get_str()); p.parse(); ++n) {
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
||||
idv.set_str(p.item);
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
if (r.size()) {
|
||||
r += ' ';
|
||||
}
|
||||
r += p.get_raw_item(true);
|
||||
r += p.quoted_item;
|
||||
}
|
||||
}
|
||||
res.set_str(r);
|
||||
|
@ -411,8 +412,8 @@ end:
|
|||
}
|
||||
auto body = args[2].get_code();
|
||||
int n = 0, r = 0;
|
||||
for (util::list_parser p(cs, args[1].get_str()); p.parse(); ++n) {
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
||||
idv.set_str(p.item);
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
r++;
|
||||
|
@ -425,14 +426,14 @@ end:
|
|||
auto buf = ostd::appender<cs_string>();
|
||||
ostd::string_range s = args[0].get_str();
|
||||
ostd::string_range conj = args[1].get_str();
|
||||
size_t len = util::list_parser(cs, s).count();
|
||||
cs_list_parse_state p{s};
|
||||
size_t len = list_count(p, cs);
|
||||
size_t n = 0;
|
||||
for (util::list_parser p(cs, s); p.parse(); ++n) {
|
||||
if (!p.get_raw_item(true).empty() &&
|
||||
(p.get_raw_item(true).front() == '"')) {
|
||||
util::unescape_string(buf, p.get_raw_item());
|
||||
for (p.input = s; list_parse(p, cs); ++n) {
|
||||
if (!p.quoted_item.empty() && (p.quoted_item.front() == '"')) {
|
||||
util::unescape_string(buf, p.item);
|
||||
} else {
|
||||
ostd::range_put_all(buf, p.get_raw_item());
|
||||
ostd::range_put_all(buf, p.item);
|
||||
}
|
||||
if ((n + 1) < len) {
|
||||
if ((len > 2) || conj.empty()) {
|
||||
|
@ -470,13 +471,13 @@ end:
|
|||
ostd::string_range s = args[0].get_str();
|
||||
ostd::string_range vals = args[1].get_str();
|
||||
char const *list = s.data();
|
||||
util::list_parser p(cs, s);
|
||||
cs_list_parse_state p{s};
|
||||
for (cs_int i = 0; i < offset; ++i) {
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ostd::string_range quote = p.get_raw_item(true);
|
||||
ostd::string_range quote = p.quoted_item;
|
||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
||||
cs_string buf;
|
||||
if (qend > list) {
|
||||
|
@ -489,13 +490,13 @@ end:
|
|||
buf += vals;
|
||||
}
|
||||
for (cs_int i = 0; i < len; ++i) {
|
||||
if (!p.parse()) {
|
||||
if (!list_parse(p, cs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.skip();
|
||||
if (!p.get_input().empty()) {
|
||||
switch (p.get_input().front()) {
|
||||
list_find_item(p);
|
||||
if (!p.input.empty()) {
|
||||
switch (p.input.front()) {
|
||||
case ')':
|
||||
case ']':
|
||||
break;
|
||||
|
@ -503,7 +504,7 @@ end:
|
|||
if (!buf.empty()) {
|
||||
buf += ' ';
|
||||
}
|
||||
buf += p.get_input();
|
||||
buf += p.input;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -545,14 +546,14 @@ static void cs_list_sort(
|
|||
cs_vector<ListSortItem> items;
|
||||
size_t total = 0;
|
||||
|
||||
for (util::list_parser p(cs, list); p.parse();) {
|
||||
ListSortItem item = { p.get_raw_item(), p.get_raw_item(true) };
|
||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
||||
ListSortItem item = { p.item, p.quoted_item };
|
||||
items.push_back(item);
|
||||
total += item.quote.size();
|
||||
}
|
||||
|
||||
if (items.empty()) {
|
||||
res.set_str(cs_string{list});
|
||||
res.set_str(list);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue