forked from OctaForge/libcubescript
repl cleanup
parent
083f905913
commit
931f7294de
|
@ -4,10 +4,10 @@
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
#include <ostd/maybe.hh>
|
#include <ostd/maybe.hh>
|
||||||
|
|
||||||
static void init_lineedit(ostd::ConstCharRange) {
|
static void init_lineedit(CsState &, ostd::ConstCharRange) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
|
||||||
ostd::write(pr->get_value());
|
ostd::write(pr->get_value());
|
||||||
ostd::String ret;
|
ostd::String ret;
|
||||||
/* i really need to implement some sort of get_line for ostd streams */
|
/* i really need to implement some sort of get_line for ostd streams */
|
||||||
|
@ -17,7 +17,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
||||||
return ostd::move(ret);
|
return ostd::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_history(ostd::ConstCharRange) {
|
static void add_history(CsState &, ostd::ConstCharRange) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
|
|
||||||
#include "linenoise.hh"
|
#include "linenoise.hh"
|
||||||
|
|
||||||
|
static CsState *ln_cs = nullptr;
|
||||||
|
|
||||||
#ifdef CS_REPL_HAS_COMPLETE
|
#ifdef CS_REPL_HAS_COMPLETE
|
||||||
static void ln_complete(char const *buf, linenoiseCompletions *lc) {
|
static void ln_complete(char const *buf, linenoiseCompletions *lc) {
|
||||||
ostd::ConstCharRange cmd = get_complete_cmd(buf);
|
ostd::ConstCharRange cmd = get_complete_cmd(buf);
|
||||||
for (auto id: gcs->identmap.iter()) {
|
for (auto id: ln_cs->identmap.iter()) {
|
||||||
if (!id->is_command()) {
|
if (!id->is_command()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,7 @@ static void ln_complete(char const *buf, linenoiseCompletions *lc) {
|
||||||
|
|
||||||
#ifdef CS_REPL_HAS_HINTS
|
#ifdef CS_REPL_HAS_HINTS
|
||||||
static char *ln_hint(char const *buf, int *color, int *bold) {
|
static char *ln_hint(char const *buf, int *color, int *bold) {
|
||||||
CsCommand *cmd = get_hint_cmd(buf);
|
CsCommand *cmd = get_hint_cmd(*ln_cs, buf);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -52,9 +54,10 @@ static void ln_hint_free(void *hint) {
|
||||||
}
|
}
|
||||||
#endif /* CS_REPL_HAS_HINTS */
|
#endif /* CS_REPL_HAS_HINTS */
|
||||||
|
|
||||||
static void init_lineedit(ostd::ConstCharRange) {
|
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
|
||||||
/* sensible default history size */
|
/* sensible default history size */
|
||||||
linenoiseHistorySetMaxLen(1000);
|
linenoiseHistorySetMaxLen(1000);
|
||||||
|
ln_cs = &cs;
|
||||||
#ifdef CS_REPL_HAS_COMPLETE
|
#ifdef CS_REPL_HAS_COMPLETE
|
||||||
linenoiseSetCompletionCallback(ln_complete);
|
linenoiseSetCompletionCallback(ln_complete);
|
||||||
#endif
|
#endif
|
||||||
|
@ -64,7 +67,7 @@ static void init_lineedit(ostd::ConstCharRange) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
|
||||||
auto line = linenoise(pr->get_value().data());
|
auto line = linenoise(pr->get_value().data());
|
||||||
if (!line) {
|
if (!line) {
|
||||||
/* linenoise traps ctrl-c, detect it and let the user exit */
|
/* linenoise traps ctrl-c, detect it and let the user exit */
|
||||||
|
@ -79,7 +82,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
||||||
return ostd::move(ret);
|
return ostd::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_history(ostd::ConstCharRange line) {
|
static void add_history(CsState &, ostd::ConstCharRange line) {
|
||||||
/* backed by ostd::String so it's terminated */
|
/* backed by ostd::String so it's terminated */
|
||||||
linenoiseHistoryAdd(line.data());
|
linenoiseHistoryAdd(line.data());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
|
static CsState *rd_cs = nullptr;
|
||||||
|
|
||||||
#ifdef CS_REPL_HAS_COMPLETE
|
#ifdef CS_REPL_HAS_COMPLETE
|
||||||
static char *ln_complete_list(char const *buf, int state) {
|
static char *ln_complete_list(char const *buf, int state) {
|
||||||
static ostd::ConstCharRange cmd;
|
static ostd::ConstCharRange cmd;
|
||||||
|
@ -18,7 +20,7 @@ static char *ln_complete_list(char const *buf, int state) {
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
cmd = get_complete_cmd(buf);
|
cmd = get_complete_cmd(buf);
|
||||||
itr = gcs->identmap.iter();
|
itr = rd_cs->identmap.iter();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; !itr.empty(); itr.pop_front()) {
|
for (; !itr.empty(); itr.pop_front()) {
|
||||||
|
@ -47,7 +49,7 @@ static char **ln_complete(char const *buf, int, int) {
|
||||||
|
|
||||||
#ifdef CS_REPL_HAS_HINTS
|
#ifdef CS_REPL_HAS_HINTS
|
||||||
void ln_hint() {
|
void ln_hint() {
|
||||||
CsCommand *cmd = get_hint_cmd(rl_line_buffer);
|
CsCommand *cmd = get_hint_cmd(*rd_cs, rl_line_buffer);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
rl_redisplay();
|
rl_redisplay();
|
||||||
return;
|
return;
|
||||||
|
@ -64,7 +66,8 @@ void ln_hint() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void init_lineedit(ostd::ConstCharRange) {
|
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
|
||||||
|
rd_cs = &cs;
|
||||||
#ifdef CS_REPL_HAS_COMPLETE
|
#ifdef CS_REPL_HAS_COMPLETE
|
||||||
rl_attempted_completion_function = ln_complete;
|
rl_attempted_completion_function = ln_complete;
|
||||||
#endif
|
#endif
|
||||||
|
@ -73,7 +76,7 @@ static void init_lineedit(ostd::ConstCharRange) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
|
||||||
auto line = readline(pr->get_value().data());
|
auto line = readline(pr->get_value().data());
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return ostd::String();
|
return ostd::String();
|
||||||
|
@ -83,7 +86,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
|
||||||
return ostd::move(ret);
|
return ostd::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_history(ostd::ConstCharRange line) {
|
static void add_history(CsState &, ostd::ConstCharRange line) {
|
||||||
/* backed by ostd::String so it's terminated */
|
/* backed by ostd::String so it's terminated */
|
||||||
add_history(line.data());
|
add_history(line.data());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ static bool stdin_is_tty() {
|
||||||
|
|
||||||
/* line editing support */
|
/* line editing support */
|
||||||
|
|
||||||
CsState *gcs = nullptr;
|
|
||||||
|
|
||||||
#ifdef CS_REPL_HAS_COMPLETE
|
#ifdef CS_REPL_HAS_COMPLETE
|
||||||
static ostd::ConstCharRange get_complete_cmd(ostd::ConstCharRange buf) {
|
static ostd::ConstCharRange get_complete_cmd(ostd::ConstCharRange buf) {
|
||||||
ostd::ConstCharRange not_allowed = "\"/;()[] \t\r\n\0";
|
ostd::ConstCharRange not_allowed = "\"/;()[] \t\r\n\0";
|
||||||
|
@ -132,11 +130,11 @@ static void fill_cmd_args(ostd::String &writer, ostd::ConstCharRange args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
|
static CsCommand *get_hint_cmd(CsState &cs, ostd::ConstCharRange buf) {
|
||||||
ostd::ConstCharRange nextchars = "([;";
|
ostd::ConstCharRange nextchars = "([;";
|
||||||
auto lp = ostd::find_one_of(buf, nextchars);
|
auto lp = ostd::find_one_of(buf, nextchars);
|
||||||
if (!lp.empty()) {
|
if (!lp.empty()) {
|
||||||
CsCommand *cmd = get_hint_cmd(buf + 1);
|
CsCommand *cmd = get_hint_cmd(cs, buf + 1);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +148,7 @@ static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
|
||||||
buf = ostd::slice_until(buf, s);
|
buf = ostd::slice_until(buf, s);
|
||||||
}
|
}
|
||||||
if (!buf.empty()) {
|
if (!buf.empty()) {
|
||||||
auto cmd = gcs->get_ident(buf);
|
auto cmd = cs.get_ident(buf);
|
||||||
return cmd ? cmd->get_command() : nullptr;
|
return cmd ? cmd->get_command() : nullptr;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -182,19 +180,19 @@ void print_version() {
|
||||||
ostd::writeln(version);
|
ostd::writeln(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CsState *scs = nullptr;
|
||||||
static void do_sigint(int n) {
|
static void do_sigint(int n) {
|
||||||
/* in case another SIGINT happens, terminate normally */
|
/* in case another SIGINT happens, terminate normally */
|
||||||
signal(n, SIG_DFL);
|
signal(n, SIG_DFL);
|
||||||
if (gcs) {
|
scs->set_call_hook([](CsState &cs) {
|
||||||
gcs->set_call_hook([](CsState &cs) {
|
cs.set_call_hook(nullptr);
|
||||||
cs.set_call_hook(nullptr);
|
cs.error("<execution interrupted>");
|
||||||
cs.error("<execution interrupted>");
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
||||||
CsValue ret;
|
CsValue ret;
|
||||||
|
scs = &cs;
|
||||||
signal(SIGINT, do_sigint);
|
signal(SIGINT, do_sigint);
|
||||||
ostd::String err;
|
ostd::String err;
|
||||||
cscript::CsStackState st;
|
cscript::CsStackState st;
|
||||||
|
@ -209,6 +207,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
||||||
};
|
};
|
||||||
if (!cs.pcall(ostd::move(tocall), &err, &st)) {
|
if (!cs.pcall(ostd::move(tocall), &err, &st)) {
|
||||||
signal(SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
|
scs = nullptr;
|
||||||
ostd::ConstCharRange terr = err;
|
ostd::ConstCharRange terr = err;
|
||||||
auto col = ostd::find(terr, ':');
|
auto col = ostd::find(terr, ':');
|
||||||
if (!col.empty()) {
|
if (!col.empty()) {
|
||||||
|
@ -225,6 +224,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
signal(SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
|
scs = nullptr;
|
||||||
if (ret.get_type() != CsValueType::Null) {
|
if (ret.get_type() != CsValueType::Null) {
|
||||||
ostd::writeln(ret.get_str());
|
ostd::writeln(ret.get_str());
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ static void do_tty(CsState &cs) {
|
||||||
|
|
||||||
ostd::writeln(version, " (REPL mode)");
|
ostd::writeln(version, " (REPL mode)");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto line = read_line(prompt);
|
auto line = read_line(cs, prompt);
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ static void do_tty(CsState &cs) {
|
||||||
if (bsl) {
|
if (bsl) {
|
||||||
lv.resize(lv.size() - 1);
|
lv.resize(lv.size() - 1);
|
||||||
}
|
}
|
||||||
auto line2 = read_line(prompt2);
|
auto line2 = read_line(cs, prompt2);
|
||||||
if (!line2) {
|
if (!line2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ static void do_tty(CsState &cs) {
|
||||||
}
|
}
|
||||||
lv += line2.value();
|
lv += line2.value();
|
||||||
}
|
}
|
||||||
add_history(lv);
|
add_history(cs, lv);
|
||||||
if (do_exit) {
|
if (do_exit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,11 +272,10 @@ static void do_tty(CsState &cs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
CsState csg;
|
CsState gcs;
|
||||||
gcs = &csg;
|
gcs.init_libs();
|
||||||
csg.init_libs();
|
|
||||||
|
|
||||||
csg.new_command("exec", "sb", [](CsState &cs, auto args, auto &res) {
|
gcs.new_command("exec", "sb", [](CsState &cs, auto args, auto &res) {
|
||||||
auto file = args[0].get_strr();
|
auto file = args[0].get_strr();
|
||||||
bool ret = cs.run_file(file);
|
bool ret = cs.run_file(file);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -289,7 +288,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
csg.new_command("echo", "C", [](CsState &cs, auto args, auto &) {
|
gcs.new_command("echo", "C", [](CsState &cs, auto args, auto &) {
|
||||||
cs.get_out().writeln(args[0].get_strr());
|
cs.get_out().writeln(args[0].get_strr());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -366,31 +365,31 @@ endargs:
|
||||||
if (*str == '\0') {
|
if (*str == '\0') {
|
||||||
str = argv[++i];
|
str = argv[++i];
|
||||||
}
|
}
|
||||||
do_call(csg, str);
|
do_call(gcs, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstarg) {
|
if (firstarg) {
|
||||||
do_call(csg, argv[firstarg], true);
|
do_call(gcs, argv[firstarg], true);
|
||||||
}
|
}
|
||||||
if (!firstarg && !has_str && !has_ver) {
|
if (!firstarg && !has_str && !has_ver) {
|
||||||
if (stdin_is_tty()) {
|
if (stdin_is_tty()) {
|
||||||
init_lineedit(argv[0]);
|
init_lineedit(gcs, argv[0]);
|
||||||
do_tty(csg);
|
do_tty(gcs);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
ostd::String str;
|
ostd::String str;
|
||||||
for (char c = '\0'; (c = ostd::in.getchar()) != EOF;) {
|
for (char c = '\0'; (c = ostd::in.getchar()) != EOF;) {
|
||||||
str += c;
|
str += c;
|
||||||
}
|
}
|
||||||
do_call(csg, str);
|
do_call(gcs, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_inter) {
|
if (has_inter) {
|
||||||
if (stdin_is_tty()) {
|
if (stdin_is_tty()) {
|
||||||
init_lineedit(argv[0]);
|
init_lineedit(gcs, argv[0]);
|
||||||
do_tty(csg);
|
do_tty(gcs);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue