Merge branch 'no-way-out-if-ctrlc' into develop

This commit is contained in:
Louis Rubet 2018-06-01 12:56:48 +02:00
commit 9b46aefd3a
6 changed files with 56 additions and 28 deletions

6
.gitmodules vendored Normal file
View file

@ -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

View file

@ -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") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer -s")
endif() 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 # includes
include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/linenoise-ng/include)
# build # build
add_executable( add_executable(
rpn rpn
src/main.cpp ${PROJECT_SOURCE_DIR}/src/main.cpp
src/object.cpp ${PROJECT_SOURCE_DIR}/src/object.cpp
src/program.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) target_link_libraries(rpn mpfr)
# man # man
add_custom_target(man ALL) add_custom_target(man ALL)
add_custom_command( add_custom_command(
TARGET man 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 OUTPUTS ${CMAKE_CURRENT_SOURCE_DIR}/rpn.1.gz
) )

1
linenoise-ng Submodule

@ -0,0 +1 @@
Subproject commit 32d3c3dcd65e2ce622084cd8057b25271561512e

View file

@ -55,6 +55,7 @@ typedef enum {
ret_internal, ret_internal,
ret_deadly, ret_deadly,
ret_good_bye, ret_good_bye,
ret_abort_current_entry,
ret_not_impl, ret_not_impl,
ret_nop, ret_nop,
ret_syntax, ret_syntax,
@ -65,7 +66,7 @@ typedef enum {
#define RET_VALUE_STRINGS { \ #define RET_VALUE_STRINGS { \
"ok", "unknown command", "missing operand", "bad operand type", "out of range", "unknown variable", "internal error, aborting", \ "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 // command types

View file

@ -8,7 +8,7 @@
#include <pwd.h> #include <pwd.h>
#include <linux/limits.h> #include <linux/limits.h>
// internal includes // internal includes
#include "program.hpp" #include "program.hpp"
static heap s_global_heap; static heap s_global_heap;
@ -90,10 +90,11 @@ static void catch_signals(program* prog)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int ret = 0; int ret = 0;
bool go_on = true;
// apply default configuration // apply default configuration
program::apply_default(); program::apply_default();
// run with interactive prompt // run with interactive prompt
if (argc == 1) if (argc == 1)
{ {
@ -101,22 +102,27 @@ int main(int argc, char* argv[])
init_interactive_rpn(); init_interactive_rpn();
// entry loop // entry loop
for (;;) while(go_on)
{ {
// make program from interactive entry // make program from interactive entry
program prog; program prog;
if (program::entry(prog) == ret_good_bye) switch (program::entry(prog))
break;
else
{ {
// user could stop prog with CtrlC case ret_good_bye:
catch_signals(&prog); go_on = false;
break;
// run it case ret_abort_current_entry:
if (prog.run(s_global_stack, s_global_heap) == ret_good_bye) 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; 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); program::show_stack(s_global_stack, true);
} }
} }
mpfr_free_cache(); mpfr_free_cache();
return ret; return ret;
} }

View file

@ -32,17 +32,23 @@ static ret_value parse(const char* entry, program& prog)
static ret_value entry(program& prog) static ret_value entry(program& prog)
{ {
char* entry; char* entry;
int entry_len;
ret_value ret; ret_value ret;
// linenoise for entry // linenoise for entry
linenoiseSetCompletionCallback(program::entry_completion_generator); linenoiseSetCompletionCallback(program::entry_completion_generator);
// get user entry // get user entry
entry = linenoise(PROMPT); entry = linenoise(PROMPT, &entry_len);
// Ctrl-C // Ctrl-C
if (linenoiseKeyType() == 1) if (linenoiseKeyType() == 1)
ret = ret_good_bye; {
if (entry_len > 0)
ret = ret_abort_current_entry;
else
ret = ret_good_bye;
}
else else
{ {
if (entry != NULL) if (entry != NULL)
@ -162,7 +168,7 @@ static bool _cut(const char* entry, vector<string>& entries)
i++; i++;
} }
else if (strncmp(&entry[i], ">>", 2) == 0) else if (strncmp(&entry[i], ">>", 2) == 0)
{ {
if (isspace(entry[i-1]) && entry[i-2]!='>') if (isspace(entry[i-1]) && entry[i-2]!='>')
tmp += ">>"; tmp += ">>";
else 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) static bool _obj_from_string(string& entry, program& prog, string& remaining_entry)
{ {
bool ret = false; bool ret = false;
remaining_entry.erase(); remaining_entry.erase();
if (get_number(entry, prog, remaining_entry)) if (get_number(entry, prog, remaining_entry))