get rid of ostd requirements inside library entirely

master
Daniel Kolesa 2021-03-20 07:24:25 +01:00
parent 68669413cc
commit cb926a5750
5 changed files with 185 additions and 132 deletions

View File

@ -1,9 +1,7 @@
#ifndef LIBCUBESCRIPT_CUBESCRIPT_HH #ifndef LIBCUBESCRIPT_CUBESCRIPT_HH
#define LIBCUBESCRIPT_CUBESCRIPT_HH #define LIBCUBESCRIPT_CUBESCRIPT_HH
#include <stdio.h> #include <cstring>
#include <stdlib.h>
#include <vector> #include <vector>
#include <optional> #include <optional>
#include <functional> #include <functional>
@ -13,10 +11,26 @@
#include "cubescript_conf.hh" #include "cubescript_conf.hh"
#include <ostd/platform.hh> #if defined(__CYGWIN__) || (defined(_WIN32) && !defined(_XBOX_VER))
#include <ostd/string.hh> # ifdef LIBCUBESCRIPT_DLL
#include <ostd/range.hh> # ifdef LIBCUBESCRIPT_BUILD
#include <ostd/format.hh> # define LIBCUBESCRIPT_EXPORT __declspec(dllexport)
# else
# define LIBCUBESCRIPT_EXPORT __declspec(dllimport)
# endif
# else
# define LIBCUBESCRIPT_EXPORT
# endif
# define LIBCUBESCRIPT_LOCAL
#else
# if defined(__GNUC__) && (__GNUC__ >= 4)
# define LIBCUBESCRIPT_EXPORT __attribute__((visibility("default")))
# define LIBCUBESCRIPT_LOCAL __attribute__((visibility("hidden")))
# else
# define LIBCUBESCRIPT_EXPORT
# define LIBCUBESCRIPT_LOCAL
# endif
#endif
namespace cscript { namespace cscript {
@ -43,7 +57,7 @@ struct cs_value;
struct cs_state; struct cs_state;
struct cs_shared_state; struct cs_shared_state;
struct OSTD_EXPORT cs_bcode_ref { struct LIBCUBESCRIPT_EXPORT cs_bcode_ref {
cs_bcode_ref(): cs_bcode_ref():
p_code(nullptr) p_code(nullptr)
{} {}
@ -67,9 +81,9 @@ private:
cs_bcode *p_code; cs_bcode *p_code;
}; };
OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code); LIBCUBESCRIPT_EXPORT bool cs_code_is_empty(cs_bcode *code);
struct OSTD_EXPORT cs_strref { struct LIBCUBESCRIPT_EXPORT cs_strref {
friend struct cs_value; friend struct cs_value;
/* FIXME: eliminate this */ /* FIXME: eliminate this */
friend inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs); friend inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs);
@ -111,7 +125,7 @@ enum class cs_value_type {
NONE = 0, INT, FLOAT, STRING, CODE, IDENT NONE = 0, INT, FLOAT, STRING, CODE, IDENT
}; };
struct OSTD_EXPORT cs_value { struct LIBCUBESCRIPT_EXPORT cs_value {
cs_value() = delete; cs_value() = delete;
~cs_value(); ~cs_value();
@ -191,7 +205,7 @@ struct cs_svar;
struct cs_alias; struct cs_alias;
struct cs_command; struct cs_command;
struct OSTD_EXPORT cs_ident { struct LIBCUBESCRIPT_EXPORT cs_ident {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
@ -253,7 +267,7 @@ private:
int p_index = -1; int p_index = -1;
}; };
struct OSTD_EXPORT cs_var: cs_ident { struct LIBCUBESCRIPT_EXPORT cs_var: cs_ident {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
@ -270,7 +284,7 @@ private:
} }
}; };
struct OSTD_EXPORT cs_ivar: cs_var { struct LIBCUBESCRIPT_EXPORT cs_ivar: cs_var {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
@ -288,7 +302,7 @@ private:
cs_int p_storage, p_minval, p_maxval, p_overrideval; cs_int p_storage, p_minval, p_maxval, p_overrideval;
}; };
struct OSTD_EXPORT cs_fvar: cs_var { struct LIBCUBESCRIPT_EXPORT cs_fvar: cs_var {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
@ -307,7 +321,7 @@ private:
cs_float p_storage, p_minval, p_maxval, p_overrideval; cs_float p_storage, p_minval, p_maxval, p_overrideval;
}; };
struct OSTD_EXPORT cs_svar: cs_var { struct LIBCUBESCRIPT_EXPORT cs_svar: cs_var {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
@ -320,7 +334,7 @@ private:
cs_strref p_storage, p_overrideval; cs_strref p_storage, p_overrideval;
}; };
struct OSTD_EXPORT cs_alias: cs_ident { struct LIBCUBESCRIPT_EXPORT cs_alias: cs_ident {
friend struct cs_state; friend struct cs_state;
friend struct cs_shared_state; friend struct cs_shared_state;
friend struct cs_alias_internal; friend struct cs_alias_internal;
@ -380,7 +394,7 @@ static inline void *cs_default_alloc(void *, void *p, size_t, size_t ns) {
return new unsigned char[ns]; return new unsigned char[ns];
} }
struct OSTD_EXPORT cs_state { struct LIBCUBESCRIPT_EXPORT cs_state {
friend struct cs_error; friend struct cs_error;
friend struct cs_strman; friend struct cs_strman;
friend struct cs_strref; friend struct cs_strref;
@ -515,11 +529,11 @@ struct OSTD_EXPORT cs_state {
void print_var(cs_var const &v) const; void print_var(cs_var const &v) const;
private: private:
OSTD_LOCAL cs_state(cs_shared_state *s); LIBCUBESCRIPT_LOCAL cs_state(cs_shared_state *s);
cs_ident *add_ident(cs_ident *id); cs_ident *add_ident(cs_ident *id);
OSTD_LOCAL void *alloc(void *ptr, size_t olds, size_t news); LIBCUBESCRIPT_LOCAL void *alloc(void *ptr, size_t olds, size_t news);
cs_gen_state *p_pstate = nullptr; cs_gen_state *p_pstate = nullptr;
int p_inloop = 0; int p_inloop = 0;
@ -587,16 +601,20 @@ struct cs_error {
cs_error(cs_state &cs, std::string_view msg, A &&...args): cs_error(cs_state &cs, std::string_view msg, A &&...args):
p_errmsg(), p_stack(cs) p_errmsg(), p_stack(cs)
{ {
try { char fbuf[512];
char fbuf[512]; int written = std::snprintf(
auto ret = ostd::format( fbuf, sizeof(fbuf), "%.*s", int(msg.size()), msg.data()
ostd::counting_sink(ostd::char_range(fbuf, fbuf + sizeof(fbuf))), );
msg, std::forward<A>(args)... if (written >= int(sizeof(fbuf))) {
).get_written(); written = std::strlen(fbuf);
p_errmsg = save_msg(cs, ostd::char_range(fbuf, fbuf + ret)); } else if (written <= 0) {
} catch (...) { std::strncpy(fbuf, "format error", sizeof(fbuf));
p_errmsg = save_msg(cs, msg); written = std::strlen(fbuf);
} }
p_errmsg = save_msg(cs, std::string_view{
static_cast<char const *>(fbuf),
std::size_t(written)
});
p_stack = save_stack(cs); p_stack = save_stack(cs);
} }
@ -608,7 +626,7 @@ private:
cs_stack_state p_stack; cs_stack_state p_stack;
}; };
struct OSTD_EXPORT cs_stacked_value: cs_value { struct LIBCUBESCRIPT_EXPORT cs_stacked_value: cs_value {
cs_stacked_value(cs_state &cs, cs_ident *id = nullptr); cs_stacked_value(cs_state &cs, cs_ident *id = nullptr);
~cs_stacked_value(); ~cs_stacked_value();
@ -634,7 +652,7 @@ private:
bool p_pushed; bool p_pushed;
}; };
struct OSTD_EXPORT cs_list_parse_state { struct LIBCUBESCRIPT_EXPORT cs_list_parse_state {
cs_list_parse_state(std::string_view s = std::string_view{}): cs_list_parse_state(std::string_view s = std::string_view{}):
input_beg{s.data()}, input_end{s.data() + s.size()} input_beg{s.data()}, input_end{s.data() + s.size()}
{} {}
@ -653,12 +671,12 @@ struct OSTD_EXPORT cs_list_parse_state {
std::string_view quoted_item{}; std::string_view quoted_item{};
}; };
OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs); LIBCUBESCRIPT_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); LIBCUBESCRIPT_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); LIBCUBESCRIPT_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); LIBCUBESCRIPT_EXPORT void list_find_item(cs_list_parse_state &ps);
OSTD_EXPORT cs_strref value_list_concat( LIBCUBESCRIPT_EXPORT cs_strref value_list_concat(
cs_state &cs, std::span<cs_value> vals, cs_state &cs, std::span<cs_value> vals,
std::string_view sep = std::string_view{} std::string_view sep = std::string_view{}
); );
@ -666,7 +684,6 @@ OSTD_EXPORT cs_strref value_list_concat(
namespace util { namespace util {
template<typename R> template<typename R>
inline R escape_string(R writer, std::string_view str) { inline R escape_string(R writer, std::string_view str) {
using namespace ostd::string_literals;
*writer++ = '"'; *writer++ = '"';
for (auto c: str) { for (auto c: str) {
switch (c) { switch (c) {
@ -720,7 +737,7 @@ namespace util {
return writer; return writer;
} }
OSTD_EXPORT char const *parse_string( LIBCUBESCRIPT_EXPORT char const *parse_string(
cs_state &cs, std::string_view str, size_t &nlines cs_state &cs, std::string_view str, size_t &nlines
); );
@ -731,27 +748,31 @@ namespace util {
return parse_string(cs, str, nlines); return parse_string(cs, str, nlines);
} }
OSTD_EXPORT char const *parse_word(cs_state &cs, std::string_view str); LIBCUBESCRIPT_EXPORT char const *parse_word(cs_state &cs, std::string_view str);
template<typename R> template<typename R>
inline void print_stack(R &&writer, cs_stack_state const &st) { inline R print_stack(R writer, cs_stack_state const &st) {
char buf[32] = {0};
auto nd = st.get(); auto nd = st.get();
while (nd) { while (nd) {
try { auto name = nd->id->get_name();
ostd::format( *writer++ = ' ';
std::forward<R>(writer), *writer++ = ' ';
((nd->index == 1) && st.gap()) if ((nd->index == 1) && st.gap()) {
? " ..%d) %s" : " %d) %s", *writer++ = '.';
nd->index, nd->id->get_name() *writer++ = '.';
);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
} }
snprintf(buf, sizeof(buf), "%d", nd->index);
char const *p = buf;
std::copy(p, p + strlen(p), writer);
*writer++ = ')';
std::copy(name.begin(), name.end(), writer);
nd = nd->next; nd = nd->next;
if (nd) { if (nd) {
writer.put('\n'); *writer++ = '\n';
} }
} }
return writer;
} }
} /* namespace util */ } /* namespace util */

View File

@ -330,7 +330,7 @@ bool cs_strref::operator==(cs_strref const &s) const {
} }
namespace util { namespace util {
OSTD_EXPORT char const *parse_string( LIBCUBESCRIPT_EXPORT char const *parse_string(
cs_state &cs, std::string_view str, size_t &nlines cs_state &cs, std::string_view str, size_t &nlines
) { ) {
size_t nl = 0; size_t nl = 0;
@ -383,7 +383,7 @@ end:
return ++beg; return ++beg;
} }
OSTD_EXPORT char const *parse_word(cs_state &cs, std::string_view str) { LIBCUBESCRIPT_EXPORT char const *parse_word(cs_state &cs, std::string_view str) {
char const *it = str.begin(); char const *it = str.begin();
char const *end = str.end(); char const *end = str.end();
for (; it != end; ++it) { for (; it != end; ++it) {
@ -432,7 +432,7 @@ end:
} }
} /* namespace util */ } /* namespace util */
OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) { LIBCUBESCRIPT_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) {
list_find_item(ps); list_find_item(ps);
if (ps.input_beg == ps.input_end) { if (ps.input_beg == ps.input_end) {
return false; return false;
@ -521,7 +521,7 @@ endblock:
return true; return true;
} }
OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) { LIBCUBESCRIPT_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) {
size_t ret = 0; size_t ret = 0;
while (list_parse(ps, cs)) { while (list_parse(ps, cs)) {
++ret; ++ret;
@ -529,7 +529,7 @@ OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) {
return ret; return ret;
} }
OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) { LIBCUBESCRIPT_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) {
if (!ps.quoted_item.empty() && (ps.quoted_item.front() == '"')) { if (!ps.quoted_item.empty() && (ps.quoted_item.front() == '"')) {
cs_charbuf buf{cs}; cs_charbuf buf{cs};
util::unescape_string(std::back_inserter(buf), ps.item); util::unescape_string(std::back_inserter(buf), ps.item);
@ -538,7 +538,7 @@ OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) {
return cs_strref{cs, ps.item}; return cs_strref{cs, ps.item};
} }
OSTD_EXPORT void list_find_item(cs_list_parse_state &ps) { LIBCUBESCRIPT_EXPORT void list_find_item(cs_list_parse_state &ps) {
for (;;) { for (;;) {
while (ps.input_beg != ps.input_end) { while (ps.input_beg != ps.input_end) {
char c = *ps.input_beg; char c = *ps.input_beg;
@ -558,7 +558,7 @@ OSTD_EXPORT void list_find_item(cs_list_parse_state &ps) {
} }
} }
OSTD_EXPORT cs_strref value_list_concat( LIBCUBESCRIPT_EXPORT cs_strref value_list_concat(
cs_state &cs, std::span<cs_value> vals, std::string_view sep cs_state &cs, std::span<cs_value> vals, std::string_view sep
) { ) {
cs_charbuf buf{cs}; cs_charbuf buf{cs};

View File

@ -2,28 +2,54 @@
#include "cs_vm.hh" #include "cs_vm.hh"
#include "cs_util.hh" #include "cs_util.hh"
#include <cmath>
namespace cscript { namespace cscript {
static cs_charbuf intstr(cs_int v, cs_shared_state &cs) { static std::string_view intstr(cs_int v, cs_charbuf &buf) {
auto app = ostd::appender<cs_charbuf>(cs); buf.reserve(32);
try { int n = snprintf(buf.data(), 32, CS_INT_FORMAT, v);
ostd::format(app, CS_INT_FORMAT, v); if (n > 32) {
} catch (ostd::format_error const &e) { buf.reserve(n + 1);
throw cs_internal_error{e.what()}; int nn = snprintf(buf.data(), n + 1, CS_INT_FORMAT, v);
if ((nn > n) || (nn <= 0)) {
n = -1;
} else {
n = nn;
}
} }
return std::move(app.get()); if (n <= 0) {
throw cs_internal_error{"format error"};
}
return std::string_view{buf.data(), std::size_t(n)};
} }
static cs_charbuf floatstr(cs_float v, cs_shared_state &cs) { static std::string_view floatstr(cs_float v, cs_charbuf &buf) {
auto app = ostd::appender<cs_charbuf>(cs); buf.reserve(32);
try { int n;
ostd::format( if (v == std::floor(v)) {
app, (v == floor(v)) ? CS_ROUND_FLOAT_FORMAT : CS_FLOAT_FORMAT, v n = snprintf(buf.data(), 32, CS_ROUND_FLOAT_FORMAT, v);
); } else {
} catch (ostd::format_error const &e) { n = snprintf(buf.data(), 32, CS_FLOAT_FORMAT, v);
throw cs_internal_error{e.what()};
} }
return std::move(app.get()); if (n > 32) {
buf.reserve(n + 1);
int nn;
if (v == std::floor(v)) {
nn = snprintf(buf.data(), n + 1, CS_ROUND_FLOAT_FORMAT, v);
} else {
nn = snprintf(buf.data(), n + 1, CS_FLOAT_FORMAT, v);
}
if ((nn > n) || (nn <= 0)) {
n = -1;
} else {
n = nn;
}
}
if (n <= 0) {
throw cs_internal_error{"format error"};
}
return std::string_view{buf.data(), std::size_t(n)};
} }
template<typename T> template<typename T>
@ -201,19 +227,21 @@ cs_int cs_value::force_int() {
std::string_view cs_value::force_str() { std::string_view cs_value::force_str() {
cs_charbuf rs{*state()}; cs_charbuf rs{*state()};
std::string_view str;
switch (get_type()) { switch (get_type()) {
case cs_value_type::FLOAT: case cs_value_type::FLOAT:
rs = std::move(floatstr(csv_get<cs_float>(p_stor), *state())); str = floatstr(csv_get<cs_float>(p_stor), rs);
break; break;
case cs_value_type::INT: case cs_value_type::INT:
rs = std::move(intstr(csv_get<cs_int>(p_stor), *state())); str = intstr(csv_get<cs_int>(p_stor), rs);
break; break;
case cs_value_type::STRING: case cs_value_type::STRING:
return *reinterpret_cast<cs_strref const *>(&p_stor); return *reinterpret_cast<cs_strref const *>(&p_stor);
default: default:
str = rs.str();
break; break;
} }
set_str(rs.str()); set_str(str);
return std::string_view(*reinterpret_cast<cs_strref const *>(&p_stor)); return std::string_view(*reinterpret_cast<cs_strref const *>(&p_stor));
} }
@ -267,14 +295,14 @@ cs_strref cs_value::get_str() const {
switch (get_type()) { switch (get_type()) {
case cs_value_type::STRING: case cs_value_type::STRING:
return *reinterpret_cast<cs_strref const *>(&p_stor); return *reinterpret_cast<cs_strref const *>(&p_stor);
case cs_value_type::INT: case cs_value_type::INT: {
return cs_strref{ cs_charbuf rs{*state()};
*state(), intstr(csv_get<cs_int>(p_stor), *state()).str() return cs_strref{*state(), intstr(csv_get<cs_int>(p_stor), rs)};
}; }
case cs_value_type::FLOAT: case cs_value_type::FLOAT: {
return cs_strref{ cs_charbuf rs{*state()};
*state(), floatstr(csv_get<cs_float>(p_stor), *state()).str() return cs_strref{*state(), floatstr(csv_get<cs_float>(p_stor), rs)};
}; }
default: default:
break; break;
} }
@ -298,7 +326,7 @@ void cs_value::get_val(cs_value &r) const {
} }
} }
OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code) { LIBCUBESCRIPT_EXPORT bool cs_code_is_empty(cs_bcode *code) {
if (!code) { if (!code) {
return true; return true;
} }

View File

@ -1,6 +1,8 @@
#include <cubescript/cubescript.hh> #include <cubescript/cubescript.hh>
#include "cs_vm.hh" #include "cs_vm.hh"
#include <iterator>
namespace cscript { namespace cscript {
bool cs_check_num(std::string_view s) { bool cs_check_num(std::string_view s) {
@ -359,11 +361,11 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
cs_init_lib_base(*this); cs_init_lib_base(*this);
} }
OSTD_EXPORT cs_state::~cs_state() { LIBCUBESCRIPT_EXPORT cs_state::~cs_state() {
destroy(); destroy();
} }
OSTD_EXPORT void cs_state::destroy() { LIBCUBESCRIPT_EXPORT void cs_state::destroy() {
if (!p_state || !p_owner) { if (!p_state || !p_owner) {
return; return;
} }
@ -384,31 +386,31 @@ cs_state::cs_state(cs_shared_state *s):
p_state(s), p_owner(false) p_state(s), p_owner(false)
{} {}
OSTD_EXPORT cs_state cs_state::new_thread() { LIBCUBESCRIPT_EXPORT cs_state cs_state::new_thread() {
return cs_state{p_state}; return cs_state{p_state};
} }
OSTD_EXPORT cs_hook_cb cs_state::set_call_hook(cs_hook_cb func) { LIBCUBESCRIPT_EXPORT cs_hook_cb cs_state::set_call_hook(cs_hook_cb func) {
auto hk = std::move(p_callhook); auto hk = std::move(p_callhook);
p_callhook = std::move(func); p_callhook = std::move(func);
return hk; return hk;
} }
OSTD_EXPORT cs_hook_cb const &cs_state::get_call_hook() const { LIBCUBESCRIPT_EXPORT cs_hook_cb const &cs_state::get_call_hook() const {
return p_callhook; return p_callhook;
} }
OSTD_EXPORT cs_hook_cb &cs_state::get_call_hook() { LIBCUBESCRIPT_EXPORT cs_hook_cb &cs_state::get_call_hook() {
return p_callhook; return p_callhook;
} }
OSTD_EXPORT cs_vprint_cb cs_state::set_var_printer(cs_vprint_cb func) { LIBCUBESCRIPT_EXPORT cs_vprint_cb cs_state::set_var_printer(cs_vprint_cb func) {
auto fn = std::move(p_state->varprintf); auto fn = std::move(p_state->varprintf);
p_state->varprintf = std::move(func); p_state->varprintf = std::move(func);
return fn; return fn;
} }
OSTD_EXPORT cs_vprint_cb const &cs_state::get_var_printer() const { LIBCUBESCRIPT_EXPORT cs_vprint_cb const &cs_state::get_var_printer() const {
return p_state->varprintf; return p_state->varprintf;
} }
@ -416,7 +418,7 @@ void *cs_state::alloc(void *ptr, size_t os, size_t ns) {
return p_state->alloc(ptr, os, ns); return p_state->alloc(ptr, os, ns);
} }
OSTD_EXPORT void cs_state::clear_override(cs_ident &id) { LIBCUBESCRIPT_EXPORT void cs_state::clear_override(cs_ident &id) {
if (!(id.get_flags() & CS_IDF_OVERRIDDEN)) { if (!(id.get_flags() & CS_IDF_OVERRIDDEN)) {
return; return;
} }
@ -451,13 +453,13 @@ OSTD_EXPORT void cs_state::clear_override(cs_ident &id) {
id.p_flags &= ~CS_IDF_OVERRIDDEN; id.p_flags &= ~CS_IDF_OVERRIDDEN;
} }
OSTD_EXPORT void cs_state::clear_overrides() { LIBCUBESCRIPT_EXPORT void cs_state::clear_overrides() {
for (auto &p: p_state->idents) { for (auto &p: p_state->idents) {
clear_override(*(p.second)); clear_override(*(p.second));
} }
} }
OSTD_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) { LIBCUBESCRIPT_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) {
if (!id) { if (!id) {
return nullptr; return nullptr;
} }
@ -467,7 +469,7 @@ OSTD_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) {
return p_state->identmap.back(); return p_state->identmap.back();
} }
OSTD_EXPORT cs_ident *cs_state::new_ident(std::string_view name, int flags) { LIBCUBESCRIPT_EXPORT cs_ident *cs_state::new_ident(std::string_view name, int flags) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id) { if (!id) {
if (cs_check_num(name)) { if (cs_check_num(name)) {
@ -482,7 +484,7 @@ OSTD_EXPORT cs_ident *cs_state::new_ident(std::string_view name, int flags) {
return id; return id;
} }
OSTD_EXPORT cs_ident *cs_state::force_ident(cs_value &v) { LIBCUBESCRIPT_EXPORT cs_ident *cs_state::force_ident(cs_value &v) {
switch (v.get_type()) { switch (v.get_type()) {
case cs_value_type::IDENT: case cs_value_type::IDENT:
return v.get_ident(); return v.get_ident();
@ -498,7 +500,7 @@ OSTD_EXPORT cs_ident *cs_state::force_ident(cs_value &v) {
return p_state->identmap[DummyIdx]; return p_state->identmap[DummyIdx];
} }
OSTD_EXPORT cs_ident *cs_state::get_ident(std::string_view name) { LIBCUBESCRIPT_EXPORT cs_ident *cs_state::get_ident(std::string_view name) {
auto id = p_state->idents.find(name); auto id = p_state->idents.find(name);
if (id != p_state->idents.end()) { if (id != p_state->idents.end()) {
return id->second; return id->second;
@ -506,7 +508,7 @@ OSTD_EXPORT cs_ident *cs_state::get_ident(std::string_view name) {
return nullptr; return nullptr;
} }
OSTD_EXPORT cs_alias *cs_state::get_alias(std::string_view name) { LIBCUBESCRIPT_EXPORT cs_alias *cs_state::get_alias(std::string_view name) {
auto id = get_ident(name); auto id = get_ident(name);
if (!id || !id->is_alias()) { if (!id || !id->is_alias()) {
return nullptr; return nullptr;
@ -514,23 +516,23 @@ OSTD_EXPORT cs_alias *cs_state::get_alias(std::string_view name) {
return static_cast<cs_alias *>(id); return static_cast<cs_alias *>(id);
} }
OSTD_EXPORT bool cs_state::have_ident(std::string_view name) { LIBCUBESCRIPT_EXPORT bool cs_state::have_ident(std::string_view name) {
return p_state->idents.find(name) != p_state->idents.end(); return p_state->idents.find(name) != p_state->idents.end();
} }
OSTD_EXPORT std::span<cs_ident *> cs_state::get_idents() { LIBCUBESCRIPT_EXPORT std::span<cs_ident *> cs_state::get_idents() {
return std::span<cs_ident *>{ return std::span<cs_ident *>{
p_state->identmap.data(), p_state->identmap.data(),
p_state->identmap.size() p_state->identmap.size()
}; };
} }
OSTD_EXPORT std::span<cs_ident const *> cs_state::get_idents() const { LIBCUBESCRIPT_EXPORT std::span<cs_ident const *> cs_state::get_idents() const {
auto ptr = const_cast<cs_ident const **>(p_state->identmap.data()); auto ptr = const_cast<cs_ident const **>(p_state->identmap.data());
return std::span<cs_ident const *>{ptr, p_state->identmap.size()}; return std::span<cs_ident const *>{ptr, p_state->identmap.size()};
} }
OSTD_EXPORT cs_ivar *cs_state::new_ivar( LIBCUBESCRIPT_EXPORT cs_ivar *cs_state::new_ivar(
std::string_view n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags std::string_view n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
) { ) {
return add_ident(p_state->create<cs_ivar>( return add_ident(p_state->create<cs_ivar>(
@ -538,7 +540,7 @@ OSTD_EXPORT cs_ivar *cs_state::new_ivar(
))->get_ivar(); ))->get_ivar();
} }
OSTD_EXPORT cs_fvar *cs_state::new_fvar( LIBCUBESCRIPT_EXPORT cs_fvar *cs_state::new_fvar(
std::string_view n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags std::string_view n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags
) { ) {
return add_ident(p_state->create<cs_fvar>( return add_ident(p_state->create<cs_fvar>(
@ -546,7 +548,7 @@ OSTD_EXPORT cs_fvar *cs_state::new_fvar(
))->get_fvar(); ))->get_fvar();
} }
OSTD_EXPORT cs_svar *cs_state::new_svar( LIBCUBESCRIPT_EXPORT cs_svar *cs_state::new_svar(
std::string_view n, std::string_view v, cs_var_cb f, int flags std::string_view n, std::string_view v, cs_var_cb f, int flags
) { ) {
return add_ident(p_state->create<cs_svar>( return add_ident(p_state->create<cs_svar>(
@ -555,7 +557,7 @@ OSTD_EXPORT cs_svar *cs_state::new_svar(
))->get_svar(); ))->get_svar();
} }
OSTD_EXPORT void cs_state::reset_var(std::string_view name) { LIBCUBESCRIPT_EXPORT void cs_state::reset_var(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id) { if (!id) {
throw cs_error(*this, "variable %s does not exist", name); throw cs_error(*this, "variable %s does not exist", name);
@ -566,14 +568,14 @@ OSTD_EXPORT void cs_state::reset_var(std::string_view name) {
clear_override(*id); clear_override(*id);
} }
OSTD_EXPORT void cs_state::touch_var(std::string_view name) { LIBCUBESCRIPT_EXPORT void cs_state::touch_var(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (id && id->is_var()) { if (id && id->is_var()) {
static_cast<cs_var *>(id)->changed(*this); static_cast<cs_var *>(id)->changed(*this);
} }
} }
OSTD_EXPORT void cs_state::set_alias(std::string_view name, cs_value v) { LIBCUBESCRIPT_EXPORT void cs_state::set_alias(std::string_view name, cs_value v) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
@ -610,7 +612,7 @@ OSTD_EXPORT void cs_state::set_alias(std::string_view name, cs_value v) {
} }
} }
OSTD_EXPORT void cs_state::print_var(cs_var const &v) const { LIBCUBESCRIPT_EXPORT void cs_state::print_var(cs_var const &v) const {
p_state->varprintf(*this, v); p_state->varprintf(*this, v);
} }
@ -669,7 +671,7 @@ static inline void cs_override_var(cs_state &cs, cs_var *v, int &vflags, SF sf)
} }
} }
OSTD_EXPORT void cs_state::set_var_int( LIBCUBESCRIPT_EXPORT void cs_state::set_var_int(
std::string_view name, cs_int v, bool dofunc, bool doclamp std::string_view name, cs_int v, bool dofunc, bool doclamp
) { ) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
@ -691,7 +693,7 @@ OSTD_EXPORT void cs_state::set_var_int(
} }
} }
OSTD_EXPORT void cs_state::set_var_float( LIBCUBESCRIPT_EXPORT void cs_state::set_var_float(
std::string_view name, cs_float v, bool dofunc, bool doclamp std::string_view name, cs_float v, bool dofunc, bool doclamp
) { ) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
@ -713,7 +715,7 @@ OSTD_EXPORT void cs_state::set_var_float(
} }
} }
OSTD_EXPORT void cs_state::set_var_str( LIBCUBESCRIPT_EXPORT void cs_state::set_var_str(
std::string_view name, std::string_view v, bool dofunc std::string_view name, std::string_view v, bool dofunc
) { ) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
@ -731,7 +733,7 @@ OSTD_EXPORT void cs_state::set_var_str(
} }
} }
OSTD_EXPORT std::optional<cs_int> LIBCUBESCRIPT_EXPORT std::optional<cs_int>
cs_state::get_var_int(std::string_view name) { cs_state::get_var_int(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_ivar()) { if (!id || id->is_ivar()) {
@ -740,7 +742,7 @@ cs_state::get_var_int(std::string_view name) {
return static_cast<cs_ivar *>(id)->get_value(); return static_cast<cs_ivar *>(id)->get_value();
} }
OSTD_EXPORT std::optional<cs_float> LIBCUBESCRIPT_EXPORT std::optional<cs_float>
cs_state::get_var_float(std::string_view name) { cs_state::get_var_float(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_fvar()) { if (!id || id->is_fvar()) {
@ -749,7 +751,7 @@ cs_state::get_var_float(std::string_view name) {
return static_cast<cs_fvar *>(id)->get_value(); return static_cast<cs_fvar *>(id)->get_value();
} }
OSTD_EXPORT std::optional<cs_strref> LIBCUBESCRIPT_EXPORT std::optional<cs_strref>
cs_state::get_var_str(std::string_view name) { cs_state::get_var_str(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_svar()) { if (!id || id->is_svar()) {
@ -758,7 +760,7 @@ cs_state::get_var_str(std::string_view name) {
return cs_strref{*p_state, static_cast<cs_svar *>(id)->get_value()}; return cs_strref{*p_state, static_cast<cs_svar *>(id)->get_value()};
} }
OSTD_EXPORT std::optional<cs_int> LIBCUBESCRIPT_EXPORT std::optional<cs_int>
cs_state::get_var_min_int(std::string_view name) { cs_state::get_var_min_int(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_ivar()) { if (!id || id->is_ivar()) {
@ -767,7 +769,7 @@ cs_state::get_var_min_int(std::string_view name) {
return static_cast<cs_ivar *>(id)->get_val_min(); return static_cast<cs_ivar *>(id)->get_val_min();
} }
OSTD_EXPORT std::optional<cs_int> LIBCUBESCRIPT_EXPORT std::optional<cs_int>
cs_state::get_var_max_int(std::string_view name) { cs_state::get_var_max_int(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_ivar()) { if (!id || id->is_ivar()) {
@ -776,7 +778,7 @@ cs_state::get_var_max_int(std::string_view name) {
return static_cast<cs_ivar *>(id)->get_val_max(); return static_cast<cs_ivar *>(id)->get_val_max();
} }
OSTD_EXPORT std::optional<cs_float> LIBCUBESCRIPT_EXPORT std::optional<cs_float>
cs_state::get_var_min_float(std::string_view name) { cs_state::get_var_min_float(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_fvar()) { if (!id || id->is_fvar()) {
@ -785,7 +787,7 @@ cs_state::get_var_min_float(std::string_view name) {
return static_cast<cs_fvar *>(id)->get_val_min(); return static_cast<cs_fvar *>(id)->get_val_min();
} }
OSTD_EXPORT std::optional<cs_float> LIBCUBESCRIPT_EXPORT std::optional<cs_float>
cs_state::get_var_max_float(std::string_view name) { cs_state::get_var_max_float(std::string_view name) {
cs_ident *id = get_ident(name); cs_ident *id = get_ident(name);
if (!id || id->is_fvar()) { if (!id || id->is_fvar()) {
@ -794,7 +796,7 @@ cs_state::get_var_max_float(std::string_view name) {
return static_cast<cs_fvar *>(id)->get_val_max(); return static_cast<cs_fvar *>(id)->get_val_max();
} }
OSTD_EXPORT std::optional<cs_strref> LIBCUBESCRIPT_EXPORT std::optional<cs_strref>
cs_state::get_alias_val(std::string_view name) { cs_state::get_alias_val(std::string_view name) {
cs_alias *a = get_alias(name); cs_alias *a = get_alias(name);
if (!a) { if (!a) {
@ -827,7 +829,7 @@ cs_int cs_clamp_var(cs_state &cs, cs_ivar *iv, cs_int v) {
); );
} }
OSTD_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) { LIBCUBESCRIPT_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
if (iv->get_flags() & CS_IDF_READONLY) { if (iv->get_flags() & CS_IDF_READONLY) {
throw cs_error( throw cs_error(
*this, "variable '%s' is read only", iv->get_name() *this, "variable '%s' is read only", iv->get_name()
@ -844,7 +846,7 @@ OSTD_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
iv->changed(*this); iv->changed(*this);
} }
OSTD_EXPORT void cs_state::set_var_int_checked( LIBCUBESCRIPT_EXPORT void cs_state::set_var_int_checked(
cs_ivar *iv, std::span<cs_value> args cs_ivar *iv, std::span<cs_value> args
) { ) {
cs_int v = args[0].force_int(); cs_int v = args[0].force_int();
@ -875,7 +877,7 @@ cs_float cs_clamp_fvar(cs_state &cs, cs_fvar *fv, cs_float v) {
return v; return v;
} }
OSTD_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) { LIBCUBESCRIPT_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) {
if (fv->get_flags() & CS_IDF_READONLY) { if (fv->get_flags() & CS_IDF_READONLY) {
throw cs_error( throw cs_error(
*this, "variable '%s' is read only", fv->get_name() *this, "variable '%s' is read only", fv->get_name()
@ -892,7 +894,7 @@ OSTD_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) {
fv->changed(*this); fv->changed(*this);
} }
OSTD_EXPORT void cs_state::set_var_str_checked( LIBCUBESCRIPT_EXPORT void cs_state::set_var_str_checked(
cs_svar *sv, std::string_view v cs_svar *sv, std::string_view v
) { ) {
if (sv->get_flags() & CS_IDF_READONLY) { if (sv->get_flags() & CS_IDF_READONLY) {
@ -908,7 +910,7 @@ OSTD_EXPORT void cs_state::set_var_str_checked(
sv->changed(*this); sv->changed(*this);
} }
OSTD_EXPORT cs_command *cs_state::new_command( LIBCUBESCRIPT_EXPORT cs_command *cs_state::new_command(
std::string_view name, std::string_view args, cs_command_cb func std::string_view name, std::string_view args, cs_command_cb func
) { ) {
int nargs = 0; int nargs = 0;
@ -1037,9 +1039,9 @@ void cs_init_lib_base(cs_state &gcs) {
} catch (cs_error const &e) { } catch (cs_error const &e) {
result.set_str(e.what()); result.set_str(e.what());
if (e.get_stack().get()) { if (e.get_stack().get()) {
auto app = ostd::appender<cs_charbuf>(cs); cs_charbuf buf{cs};
cscript::util::print_stack(app, e.get_stack()); util::print_stack(std::back_inserter(buf), e.get_stack());
tback.set_str(app.get().str()); tback.set_str(buf.str());
} }
rc = false; rc = false;
} }
@ -1302,7 +1304,7 @@ void cs_init_lib_math(cs_state &cs);
void cs_init_lib_string(cs_state &cs); void cs_init_lib_string(cs_state &cs);
void cs_init_lib_list(cs_state &cs); void cs_init_lib_list(cs_state &cs);
OSTD_EXPORT void cs_state::init_libs(int libs) { LIBCUBESCRIPT_EXPORT void cs_state::init_libs(int libs) {
if (libs & CS_LIB_MATH) { if (libs & CS_LIB_MATH) {
cs_init_lib_math(*this); cs_init_lib_math(*this);
} }

View File

@ -2,6 +2,7 @@
#include <optional> #include <optional>
#include <memory> #include <memory>
#include <iterator>
#include <ostd/platform.hh> #include <ostd/platform.hh>
#include <ostd/io.hh> #include <ostd/io.hh>
@ -292,8 +293,9 @@ static bool do_call(cs_state &cs, std::string_view line, bool file = false) {
} }
ostd::writeln(!is_lnum ? "stdin: " : "stdin:", e.what()); ostd::writeln(!is_lnum ? "stdin: " : "stdin:", e.what());
if (e.get_stack().get()) { if (e.get_stack().get()) {
cscript::util::print_stack(ostd::cout.iter(), e.get_stack()); std::string str;
ostd::write('\n'); cscript::util::print_stack(std::back_inserter(str), e.get_stack());
ostd::writeln(str);
} }
return false; return false;
} }