use a stolen buffer for strupper/lower

master
Daniel Kolesa 2021-03-19 01:31:34 +01:00
parent b42da1e56f
commit 126d6ab2b6
3 changed files with 31 additions and 9 deletions

View File

@ -70,6 +70,8 @@ OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code);
struct OSTD_EXPORT cs_strref {
friend struct cs_value;
/* FIXME: eliminate this */
friend inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs);
cs_strref() = delete;
cs_strref(cs_shared_state &cs, ostd::string_range str);
@ -381,6 +383,7 @@ struct OSTD_EXPORT cs_state {
friend struct cs_strref;
friend struct cs_value;
friend struct cs_gen_state;
friend inline cs_shared_state *cs_get_sstate(cs_state &);
cs_shared_state *p_state;
cs_ident_link *p_callstack = nullptr;

View File

@ -155,6 +155,14 @@ struct cs_shared_state {
}
};
inline cs_shared_state *cs_get_sstate(cs_state &cs) {
return cs.p_state;
}
inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs) {
return cs_strref{p, cs};
}
struct CsBreakException {
};

View File

@ -3,6 +3,7 @@
#include <cubescript/cubescript.hh>
#include "cs_util.hh"
#include "cs_vm.hh"
namespace cscript {
@ -56,20 +57,30 @@ void cs_init_lib_string(cs_state &cs) {
res.set_str(ostd::string_range{static_cast<char const *>(p)});
});
cs.new_command("strlower", "s", [](auto &, auto args, auto &res) {
cs_string s{ostd::string_range{args[0].get_str()}};
for (auto i: ostd::range(s.size())) {
s[i] = tolower(s[i]);
cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) {
auto inps = ostd::string_range{args[0].get_str()};
auto *ics = cs_get_sstate(ccs);
auto *buf = ics->strman->alloc_buf(inps.size());
for (auto i: ostd::range(inps.size())) {
buf[i] = tolower(inps[i]);
}
res.set_str(s);
auto const *cbuf = ics->strman->steal(buf);
auto sr = cs_make_strref(cbuf, *ics);
sman->unref(cbuf);
res.set_str(sr);
});
cs.new_command("strupper", "s", [](auto &, auto args, auto &res) {
cs_string s{ostd::string_range{args[0].get_str()}};
for (auto i: ostd::range(s.size())) {
s[i] = toupper(s[i]);
auto inps = ostd::string_range{args[0].get_str()};
auto *ics = cs_get_sstate(ccs);
auto *buf = ics->strman->alloc_buf(inps.size());
for (auto i: ostd::range(inps.size())) {
buf[i] = toupper(inps[i]);
}
res.set_str(s);
auto const *cbuf = ics->strman->steal(buf);
auto sr = cs_make_strref(cbuf, *ics);
sman->unref(cbuf);
res.set_str(sr);
});
cs.new_command("escape", "s", [](auto &, auto args, auto &res) {