diff --git a/cs_vm.cc b/cs_vm.cc
index a1e98927..8e080609 100644
--- a/cs_vm.cc
+++ b/cs_vm.cc
@@ -139,9 +139,9 @@ void cs_debug_alias(CsState &cs) {
CsIdent *id = l->id;
++depth;
if (depth < dalias->get_value()) {
- ostd::err.writefln(" %d) %s", total - depth + 1, id->get_name());
+ cs.get_err().writefln(" %d) %s", total - depth + 1, id->get_name());
} else if (l->next == &cs.noalias) {
- ostd::err.writefln(
+ cs.get_err().writefln(
depth == dalias->get_value() ? " %d) %s" : " ..%d) %s",
total - depth + 1, id->get_name()
);
diff --git a/cs_vm.hh b/cs_vm.hh
index 50b780ce..74a72947 100644
--- a/cs_vm.hh
+++ b/cs_vm.hh
@@ -119,7 +119,7 @@ void cs_debug_code(CsState &cs, ostd::ConstCharRange fmt, A &&...args) {
if (cs.nodebug) {
return;
}
- ostd::err.writefln(fmt, ostd::forward(args)...);
+ cs.get_err().writefln(fmt, ostd::forward(args)...);
cs_debug_alias(cs);
}
@@ -131,7 +131,7 @@ void cs_debug_code_line(
return;
}
ostd::Array buf;
- ostd::err.writefln(
+ cs.get_err().writefln(
cs_debug_line(p, fmt, ostd::CharRange(buf.data(), buf.size())),
ostd::forward(args)...
);
diff --git a/cubescript.cc b/cubescript.cc
index 5bf3b640..7d4ec8a6 100644
--- a/cubescript.cc
+++ b/cubescript.cc
@@ -254,7 +254,7 @@ void CsSvar::set_value(CsString val) {
void cs_init_lib_base(CsState &cs);
-CsState::CsState() {
+CsState::CsState(): p_out(&ostd::out), p_err(&ostd::err) {
noalias.id = nullptr;
noalias.next = nullptr;
noalias.usedargs = (1 << MaxArguments) - 1;
@@ -360,6 +360,30 @@ CsState::~CsState() {
}
}
+CsStream const &CsState::get_out() const {
+ return *p_out;
+}
+
+CsStream &CsState::get_out() {
+ return *p_out;
+}
+
+void CsState::set_out(CsStream &s) {
+ p_out = &s;
+}
+
+CsStream const &CsState::get_err() const {
+ return *p_err;
+}
+
+CsStream &CsState::get_err() {
+ return *p_err;
+}
+
+void CsState::set_err(CsStream &s) {
+ p_err = &s;
+}
+
void CsState::clear_override(CsIdent &id) {
if (!(id.get_flags() & IDF_OVERRIDDEN)) {
return;
@@ -523,34 +547,36 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) {
}
}
-void CsState::print_var_int(CsIvar *iv, CsInt i) {
+void CsState::print_var(CsIvar *iv) {
+ CsInt i = iv->get_value();
if (i < 0) {
- writefln("%s = %d", iv->get_name(), i);
+ get_out().writefln("%s = %d", iv->get_name(), i);
return;
}
if (iv->get_flags() & IDF_HEX) {
if (iv->get_val_max() == 0xFFFFFF) {
- writefln(
+ get_out().writefln(
"%s = 0x%.6X (%d, %d, %d)", iv->get_name(),
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
);
} else {
- writefln("%s = 0x%X", iv->get_name(), i);
+ get_out().writefln("%s = 0x%X", iv->get_name(), i);
}
} else {
- writefln("%s = %d", iv->get_name(), i);
+ get_out().writefln("%s = %d", iv->get_name(), i);
}
}
-void CsState::print_var_float(CsFvar *fv, CsFloat f) {
- writefln("%s = %s", fv->get_name(), floatstr(f));
+void CsState::print_var(CsFvar *fv) {
+ get_out().writefln("%s = %s", fv->get_name(), floatstr(fv->get_value()));
}
-void CsState::print_var_str(CsSvar *sv, ostd::ConstCharRange s) {
- if (ostd::find(s, '"').empty()) {
- writefln("%s = \"%s\"", sv->get_name(), s);
+void CsState::print_var(CsSvar *sv) {
+ ostd::ConstCharRange sval = sv->get_value();
+ if (ostd::find(sval, '"').empty()) {
+ get_out().writefln("%s = \"%s\"", sv->get_name(), sval);
} else {
- writefln("%s = [%s]", sv->get_name(), s);
+ get_out().writefln("%s = [%s]", sv->get_name(), sval);
}
}
@@ -558,17 +584,17 @@ void CsState::print_var(CsVar *v) {
switch (v->get_type()) {
case CsIdentType::ivar: {
CsIvar *iv = static_cast(v);
- print_var_int(iv, iv->get_value());
+ print_var(iv);
break;
}
case CsIdentType::fvar: {
CsFvar *fv = static_cast(v);
- print_var_float(fv, fv->get_value());
+ print_var(fv);
break;
}
case CsIdentType::svar: {
CsSvar *sv = static_cast(v);
- print_var_str(sv, sv->get_value());
+ print_var(sv);
break;
}
default:
@@ -1234,7 +1260,7 @@ CsCommand *CsState::new_command(
case 'V':
break;
default:
- ostd::err.writefln(
+ get_err().writefln(
"builtin %s declared with illegal type: %c",
name, fmt.front()
);
diff --git a/cubescript.hh b/cubescript.hh
index e20a4d7d..7152844d 100644
--- a/cubescript.hh
+++ b/cubescript.hh
@@ -342,6 +342,14 @@ struct OSTD_EXPORT CsState {
CsState();
~CsState();
+ CsStream const &get_out() const;
+ CsStream &get_out();
+ void set_out(CsStream &s);
+
+ CsStream const &get_err() const;
+ CsStream &get_err();
+ void set_err(CsStream &s);
+
void init_libs(int libs = CS_LIB_ALL);
void clear_override(CsIdent &id);
@@ -453,12 +461,14 @@ struct OSTD_EXPORT CsState {
ostd::Maybe get_alias_val(ostd::ConstCharRange name);
void print_var(CsVar *v);
- void print_var_int(CsIvar *iv, CsInt i);
- void print_var_float(CsFvar *fv, CsFloat f);
- void print_var_str(CsSvar *sv, ostd::ConstCharRange s);
+ virtual void print_var(CsIvar *iv);
+ virtual void print_var(CsFvar *fv);
+ virtual void print_var(CsSvar *sv);
private:
CsIdent *add_ident(CsIdent *id);
+
+ CsStream *p_out, *p_err;
};
struct OSTD_EXPORT CsStackedValue: CsValue {
diff --git a/cubescript_conf.hh b/cubescript_conf.hh
index 1017e8b6..1e08c7e8 100644
--- a/cubescript_conf.hh
+++ b/cubescript_conf.hh
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
namespace cscript {
template
@@ -25,6 +26,8 @@ namespace cscript {
template
using CsVector = ostd::Vector>;
+ using CsStream = ostd::Stream;
+
constexpr CsInt const CsIntMin = INT_MIN;
constexpr CsInt const CsIntMax = INT_MAX;
diff --git a/tools/repl.cc b/tools/repl.cc
index 512356bf..4108cd0f 100644
--- a/tools/repl.cc
+++ b/tools/repl.cc
@@ -176,7 +176,7 @@ static void do_tty(CsState &cs) {
bool ret = cs.run_file(file);
if (!ret) {
if (args[1].get_int()) {
- ostd::err.writefln("could not run file \"%s\"", file);
+ cs.get_err().writefln("could not run file \"%s\"", file);
}
res.set_int(0);
} else {
@@ -184,8 +184,8 @@ static void do_tty(CsState &cs) {
}
});
- cs.new_command("echo", "C", [](CsValueRange args, CsValue &) {
- ostd::writeln(args[0].get_strr());
+ cs.new_command("echo", "C", [&cs](CsValueRange args, CsValue &) {
+ cs.get_out().writeln(args[0].get_strr());
});
ostd::writeln(version);