From 70b97f02b79571ce1a37fee91c7eeaa4d0dbddf8 Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Sun, 13 May 2018 19:27:36 +0200 Subject: [PATCH] #146: new CtrlC management (don't go out if there is a current line) --- .gitmodules | 6 ++++++ CMakeLists.txt | 22 +++++++++++++++------- linenoise-ng | 1 + src/constant.h | 3 ++- src/main.cpp | 38 ++++++++++++++++++++++---------------- src/parse.hpp | 14 ++++++++++---- 6 files changed, 56 insertions(+), 28 deletions(-) create mode 100644 .gitmodules create mode 160000 linenoise-ng diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..335640d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "build/linenoise-ng"] + path = build/linenoise-ng + url = git@github.com:louisrubet/linenoise-ng.git +[submodule "linenoise-ng"] + path = linenoise-ng + url = git@github.com:louisrubet/linenoise-ng.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 62e1d85..74a38ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,25 +29,33 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer -s") endif() +# custom linenoise-ng +if(NOT EXISTS "${PROJECT_SOURCE_DIR}/linenoise-ng/.git") + execute_process(COMMAND git submodule init ${PROJECT_SOURCE_DIR}/linenoise-ng) + execute_process(COMMAND git submodule update ${PROJECT_SOURCE_DIR}/linenoise-ng) + execute_process(COMMAND git checkout v1.0.1-rpn WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/linenoise-ng) +endif() + # includes -include_directories(${PROJECT_SOURCE_DIR}/src) +include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/linenoise-ng/include) # build add_executable( rpn - src/main.cpp - src/object.cpp - src/program.cpp + ${PROJECT_SOURCE_DIR}/src/main.cpp + ${PROJECT_SOURCE_DIR}/src/object.cpp + ${PROJECT_SOURCE_DIR}/src/program.cpp + ${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp + ${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp + ${PROJECT_SOURCE_DIR}/linenoise-ng/src/wcwidth.cpp ) - -target_link_libraries(rpn liblinenoise.a) target_link_libraries(rpn mpfr) # man add_custom_target(man ALL) add_custom_command( TARGET man - COMMAND gzip -f -k ${CMAKE_CURRENT_SOURCE_DIR}/rpn.1 + COMMAND gzip -f -k ${CMAKE_CURRENT_SOURCE_DIR}/rpn.1 OUTPUTS ${CMAKE_CURRENT_SOURCE_DIR}/rpn.1.gz ) diff --git a/linenoise-ng b/linenoise-ng new file mode 160000 index 0000000..32d3c3d --- /dev/null +++ b/linenoise-ng @@ -0,0 +1 @@ +Subproject commit 32d3c3dcd65e2ce622084cd8057b25271561512e diff --git a/src/constant.h b/src/constant.h index 43684fc..4a969b2 100644 --- a/src/constant.h +++ b/src/constant.h @@ -55,6 +55,7 @@ typedef enum { ret_internal, ret_deadly, ret_good_bye, + ret_abort_current_entry, ret_not_impl, ret_nop, ret_syntax, @@ -65,7 +66,7 @@ typedef enum { #define RET_VALUE_STRINGS { \ "ok", "unknown command", "missing operand", "bad operand type", "out of range", "unknown variable", "internal error, aborting", \ - "deadly", "goodbye", "not implemented", "no operation", "syntax error", "division by zero", "runtime error" \ + "deadly", "goodbye", "aborted current entry", "not implemented", "no operation", "syntax error", "division by zero", "runtime error" \ } // command types diff --git a/src/main.cpp b/src/main.cpp index c340970..95eed92 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,7 @@ #include #include -// internal includes +// internal includes #include "program.hpp" static heap s_global_heap; @@ -90,10 +90,11 @@ static void catch_signals(program* prog) int main(int argc, char* argv[]) { int ret = 0; - + bool go_on = true; + // apply default configuration program::apply_default(); - + // run with interactive prompt if (argc == 1) { @@ -101,22 +102,27 @@ int main(int argc, char* argv[]) init_interactive_rpn(); // entry loop - for (;;) + while(go_on) { // make program from interactive entry program prog; - if (program::entry(prog) == ret_good_bye) - break; - else + switch (program::entry(prog)) { - // user could stop prog with CtrlC - catch_signals(&prog); - - // run it - if (prog.run(s_global_stack, s_global_heap) == ret_good_bye) + case ret_good_bye: + go_on = false; + break; + case ret_abort_current_entry: + break; + default: + // user could stop prog with CtrlC + catch_signals(&prog); + + // run it + if (prog.run(s_global_stack, s_global_heap) == ret_good_bye) + break; + else + program::show_stack(s_global_stack); break; - else - program::show_stack(s_global_stack); } } @@ -151,8 +157,8 @@ int main(int argc, char* argv[]) program::show_stack(s_global_stack, true); } } - + mpfr_free_cache(); - + return ret; } diff --git a/src/parse.hpp b/src/parse.hpp index 6c89664..96fb7e9 100644 --- a/src/parse.hpp +++ b/src/parse.hpp @@ -32,17 +32,23 @@ static ret_value parse(const char* entry, program& prog) static ret_value entry(program& prog) { char* entry; + int entry_len; ret_value ret; // linenoise for entry linenoiseSetCompletionCallback(program::entry_completion_generator); // get user entry - entry = linenoise(PROMPT); + entry = linenoise(PROMPT, &entry_len); // Ctrl-C if (linenoiseKeyType() == 1) - ret = ret_good_bye; + { + if (entry_len > 0) + ret = ret_abort_current_entry; + else + ret = ret_good_bye; + } else { if (entry != NULL) @@ -162,7 +168,7 @@ static bool _cut(const char* entry, vector& entries) i++; } else if (strncmp(&entry[i], ">>", 2) == 0) - { + { if (isspace(entry[i-1]) && entry[i-2]!='>') tmp += ">>"; else @@ -523,7 +529,7 @@ static bool get_complex(const string& entry, program& prog, string& remaining_en static bool _obj_from_string(string& entry, program& prog, string& remaining_entry) { bool ret = false; - + remaining_entry.erase(); if (get_number(entry, prog, remaining_entry))