repl cleanup

master
Daniel Kolesa 2016-09-11 23:33:02 +02:00
parent 083f905913
commit 931f7294de
4 changed files with 44 additions and 39 deletions

View File

@ -4,10 +4,10 @@
#include <ostd/string.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::String ret;
/* 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);
}
static void add_history(ostd::ConstCharRange) {
static void add_history(CsState &, ostd::ConstCharRange) {
}
#endif

View File

@ -13,10 +13,12 @@
#include "linenoise.hh"
static CsState *ln_cs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE
static void ln_complete(char const *buf, linenoiseCompletions *lc) {
ostd::ConstCharRange cmd = get_complete_cmd(buf);
for (auto id: gcs->identmap.iter()) {
for (auto id: ln_cs->identmap.iter()) {
if (!id->is_command()) {
continue;
}
@ -33,7 +35,7 @@ static void ln_complete(char const *buf, linenoiseCompletions *lc) {
#ifdef CS_REPL_HAS_HINTS
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) {
return nullptr;
}
@ -52,9 +54,10 @@ static void ln_hint_free(void *hint) {
}
#endif /* CS_REPL_HAS_HINTS */
static void init_lineedit(ostd::ConstCharRange) {
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
/* sensible default history size */
linenoiseHistorySetMaxLen(1000);
ln_cs = &cs;
#ifdef CS_REPL_HAS_COMPLETE
linenoiseSetCompletionCallback(ln_complete);
#endif
@ -64,7 +67,7 @@ static void init_lineedit(ostd::ConstCharRange) {
#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());
if (!line) {
/* 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);
}
static void add_history(ostd::ConstCharRange line) {
static void add_history(CsState &, ostd::ConstCharRange line) {
/* backed by ostd::String so it's terminated */
linenoiseHistoryAdd(line.data());
}

View File

@ -11,6 +11,8 @@
#include <readline/readline.h>
#include <readline/history.h>
static CsState *rd_cs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE
static char *ln_complete_list(char const *buf, int state) {
static ostd::ConstCharRange cmd;
@ -18,7 +20,7 @@ static char *ln_complete_list(char const *buf, int state) {
if (!state) {
cmd = get_complete_cmd(buf);
itr = gcs->identmap.iter();
itr = rd_cs->identmap.iter();
}
for (; !itr.empty(); itr.pop_front()) {
@ -47,7 +49,7 @@ static char **ln_complete(char const *buf, int, int) {
#ifdef CS_REPL_HAS_HINTS
void ln_hint() {
CsCommand *cmd = get_hint_cmd(rl_line_buffer);
CsCommand *cmd = get_hint_cmd(*rd_cs, rl_line_buffer);
if (!cmd) {
rl_redisplay();
return;
@ -64,7 +66,8 @@ void ln_hint() {
}
#endif
static void init_lineedit(ostd::ConstCharRange) {
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
rd_cs = &cs;
#ifdef CS_REPL_HAS_COMPLETE
rl_attempted_completion_function = ln_complete;
#endif
@ -73,7 +76,7 @@ static void init_lineedit(ostd::ConstCharRange) {
#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());
if (!line) {
return ostd::String();
@ -83,7 +86,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
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 */
add_history(line.data());
}

View File

@ -27,8 +27,6 @@ static bool stdin_is_tty() {
/* line editing support */
CsState *gcs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE
static ostd::ConstCharRange get_complete_cmd(ostd::ConstCharRange buf) {
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 = "([;";
auto lp = ostd::find_one_of(buf, nextchars);
if (!lp.empty()) {
CsCommand *cmd = get_hint_cmd(buf + 1);
CsCommand *cmd = get_hint_cmd(cs, buf + 1);
if (cmd) {
return cmd;
}
@ -150,7 +148,7 @@ static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
buf = ostd::slice_until(buf, s);
}
if (!buf.empty()) {
auto cmd = gcs->get_ident(buf);
auto cmd = cs.get_ident(buf);
return cmd ? cmd->get_command() : nullptr;
}
return nullptr;
@ -182,19 +180,19 @@ void print_version() {
ostd::writeln(version);
}
static CsState *scs = nullptr;
static void do_sigint(int n) {
/* in case another SIGINT happens, terminate normally */
signal(n, SIG_DFL);
if (gcs) {
gcs->set_call_hook([](CsState &cs) {
cs.set_call_hook(nullptr);
cs.error("<execution interrupted>");
});
}
scs->set_call_hook([](CsState &cs) {
cs.set_call_hook(nullptr);
cs.error("<execution interrupted>");
});
}
static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
CsValue ret;
scs = &cs;
signal(SIGINT, do_sigint);
ostd::String err;
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)) {
signal(SIGINT, SIG_DFL);
scs = nullptr;
ostd::ConstCharRange terr = err;
auto col = ostd::find(terr, ':');
if (!col.empty()) {
@ -225,6 +224,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
return false;
}
signal(SIGINT, SIG_DFL);
scs = nullptr;
if (ret.get_type() != CsValueType::Null) {
ostd::writeln(ret.get_str());
}
@ -242,7 +242,7 @@ static void do_tty(CsState &cs) {
ostd::writeln(version, " (REPL mode)");
for (;;) {
auto line = read_line(prompt);
auto line = read_line(cs, prompt);
if (!line) {
return;
}
@ -255,7 +255,7 @@ static void do_tty(CsState &cs) {
if (bsl) {
lv.resize(lv.size() - 1);
}
auto line2 = read_line(prompt2);
auto line2 = read_line(cs, prompt2);
if (!line2) {
return;
}
@ -264,7 +264,7 @@ static void do_tty(CsState &cs) {
}
lv += line2.value();
}
add_history(lv);
add_history(cs, lv);
if (do_exit) {
return;
}
@ -272,11 +272,10 @@ static void do_tty(CsState &cs) {
}
int main(int argc, char **argv) {
CsState csg;
gcs = &csg;
csg.init_libs();
CsState gcs;
gcs.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();
bool ret = cs.run_file(file);
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());
});
@ -366,31 +365,31 @@ endargs:
if (*str == '\0') {
str = argv[++i];
}
do_call(csg, str);
do_call(gcs, str);
break;
}
}
}
if (firstarg) {
do_call(csg, argv[firstarg], true);
do_call(gcs, argv[firstarg], true);
}
if (!firstarg && !has_str && !has_ver) {
if (stdin_is_tty()) {
init_lineedit(argv[0]);
do_tty(csg);
init_lineedit(gcs, argv[0]);
do_tty(gcs);
return 0;
} else {
ostd::String str;
for (char c = '\0'; (c = ostd::in.getchar()) != EOF;) {
str += c;
}
do_call(csg, str);
do_call(gcs, str);
}
}
if (has_inter) {
if (stdin_is_tty()) {
init_lineedit(argv[0]);
do_tty(csg);
init_lineedit(gcs, argv[0]);
do_tty(gcs);
}
return 0;
}