diff --git a/Makefile.am b/Makefile.am index 5d0a000..51250dc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} + bin_PROGRAMS = rpn rpn_SOURCES = src/rpn.cpp \ src/rpn-branch.h \ @@ -15,4 +16,6 @@ rpn_SOURCES = src/rpn.cpp \ src/rpn-trig.h \ src/stack.h +rpn_LDFLAGS = -lreadline + dist_noinst_SCRIPTS = autogen.sh diff --git a/src/parse.h b/src/parse.h index 83d3cf9..cdb65f6 100644 --- a/src/parse.h +++ b/src/parse.h @@ -266,30 +266,89 @@ static ret_value parse(const string& entry, program& prog) return ret; } -static ret_value parse_line(const string& entry, program& prog) +// interactive entry and decoding +static ret_value entry(program& prog) { - vector entries; - ret_value ret = ret_ok; - cmd_type_t type; - unsigned int obj_size; - object* obj; + char *buf; + ret_value ret; - //1. cut global entry string into shorter strings - if (_cut(entry, entries)) + // declare completion fn + rl_attempted_completion_function = entry_completion; + + // get user entry + buf = readline(prompt); + if (buf != NULL) { - //2. make an object from each entry, and add it to the program - for (vector::iterator it = entries.begin(); it != entries.end(); it++) - { - if(_obj_from_string((*it), obj, obj_size, type)) - { - prog.push_back(obj, obj_size, type); - } - else - { - // no syntax error for now, an unknown obj form is considered as a symbol - } - } - } + string entry = buf; - return ret; + //enable auto-complete + rl_bind_key('\t',rl_complete); + + // parse it + ret = parse(entry, prog); + + // keep history + if (buf[0]!=0) + add_history(buf); + } + else + ret = ret_internal; + + free(buf); +} + +static char** entry_completion(const char* text, int start, int end) +{ + char** matches; + + matches = (char**)NULL; + + if (start == 0) + matches = rl_completion_matches((char*)text, &entry_completion_generator); + else + rl_bind_key('\t',rl_abort); + + return matches; +} + +static char* entry_completion_generator(const char* text, int state) +{ + static int list_index, len, too_far; + char* name; + + if (!state) + { + list_index = 0; + too_far = 0; + len = strlen(text); + } + + while(too_far == 0) + { + if (_keywords[list_index].fn == NULL) + { + if (_keywords[list_index].comment.size() == 0) + too_far = 1; + break; + } + + list_index++; + + // mpo ! ne pas stocker c_str + name = (char*)_keywords[list_index].name.c_str(); + if (strncmp(name, text, len) == 0) + return entry_completion_dupstr(name); + } + + /* If no names matched, then return NULL. */ + return NULL; + +} + +static char* entry_completion_dupstr(char* s) +{ + char* r = (char*)malloc((strlen(s)+1)); + if (r != NULL) + strcpy(r, s); + return r; } diff --git a/src/rpn.cpp b/src/rpn.cpp index 9f90e76..bdc1ac5 100644 --- a/src/rpn.cpp +++ b/src/rpn.cpp @@ -29,12 +29,16 @@ #endif #include +extern "C" { +#include +#include +} + #include #include #include #include #include -//#include using namespace std; #include "stack.h" @@ -538,26 +542,6 @@ public: ret_value get_err(void) { return _err; } - // interactive entry and decoding - static ret_value entry(program& prog) - { - ret_value ret; - string entry; - - // show cursor - cout<