add cs_charbuf (mutable buffer controlled by our allocator)

also use it in a few places
master
Daniel Kolesa 2021-03-19 02:44:29 +01:00
parent 5a4cccf194
commit 5ee7e27839
3 changed files with 48 additions and 8 deletions

View File

@ -519,9 +519,9 @@ 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) {
if (!ps.quoted_item.empty() && (*ps.quoted_item == '"')) {
auto app = ostd::appender<cs_string>();
auto app = ostd::appender<cs_charbuf>(cs);
util::unescape_string(app, ps.item);
return cs_strref{cs, app.get()};
return cs_strref{cs, app.get().str()};
}
return cs_strref{cs, ps.item};
}

View File

@ -82,6 +82,21 @@ struct cs_shared_state {
v->~T();
alloc(v, len * sizeof(T), 0);
}
template<typename T>
struct allocator {
using value_type = T;
T *allocate(std::size_t n) {
return static_cast<T *>(state->alloc(nullptr, 0, n * sizeof(T)));
}
void deallocate(T *p, std::size_t n) {
state->alloc(p, n, 0);
}
cs_shared_state *state;
};
};
inline cs_shared_state *cs_get_sstate(cs_state &cs) {
@ -164,6 +179,31 @@ struct cs_strman {
std::unordered_map<ostd::string_range, cs_strref_state *> counts{};
};
struct cs_charbuf {
cs_charbuf(cs_shared_state &cs):
buf{cs_shared_state::allocator<char>{&cs}}
{}
cs_charbuf(cs_state &cs):
buf{cs_shared_state::allocator<char>{cs_get_sstate(cs)}}
{}
using size_type = std::size_t;
using value_type = char;
using reference = char &;
using const_reference = char const &;
void reserve(std::size_t s) { buf.reserve(s); }
void push_back(char c) { buf.push_back(c); }
ostd::string_range str() {
return ostd::string_range{buf.data(), buf.data() + buf.size()};
}
std::vector<char, cs_shared_state::allocator<char>> buf;
};
} /* namespace cscript */
#endif /* LIBCUBESCRIPT_CS_UTIL_HH */

View File

@ -82,16 +82,16 @@ void cs_init_lib_string(cs_state &cs) {
res.set_str(sr);
});
cs.new_command("escape", "s", [](auto &, auto args, auto &res) {
auto s = ostd::appender<cs_string>();
cs.new_command("escape", "s", [](auto &ccs, auto args, auto &res) {
auto s = ostd::appender<cs_charbuf>(ccs);
util::escape_string(s, args[0].get_str());
res.set_str(s.get());
res.set_str(s.get().str());
});
cs.new_command("unescape", "s", [](auto &, auto args, auto &res) {
auto s = ostd::appender<cs_string>();
cs.new_command("unescape", "s", [](auto &ccs, auto args, auto &res) {
auto s = ostd::appender<cs_charbuf>(ccs);
util::unescape_string(s, args[0].get_str());
res.set_str(s.get());
res.set_str(s.get().str());
});
cs.new_command("concat", "V", [](auto &ccs, auto args, auto &res) {