From db660e6002e8834814ea9beb943dc8dd951fe21c Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Thu, 26 Jan 2023 23:34:22 +0100 Subject: [PATCH] full completion feature --- calc.c | 31 +++++++++++++++++++++++++++++++ parser.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/calc.c b/calc.c index f84cf91..eee39fe 100644 --- a/calc.c +++ b/calc.c @@ -46,6 +46,35 @@ int usage (int ret) return ret; } +/* completion function */ + +char *generator (const char *text, int state); + +char **completion (const char *text, __attribute__((unused)) int start, __attribute__((unused)) int end) +{ + rl_attempted_completion_over = 1; + return rl_completion_matches (text, generator); +} + +char *generator (const char *text, int state) +{ + static int index, len; + char *name; + + if (!state) { + index = 0; + len = strlen(text); + } + + while ((name = completion_list[index++])) { + if (strncmp (name, text, len) == 0) { + return strdup (name); + } + } + + return NULL; +} + /* main function */ int main (int argc, char *argv[]) @@ -109,6 +138,7 @@ int main (int argc, char *argv[]) /* completion list*/ completion_list = generate_completion_list (); + rl_attempted_completion_function = completion; /* read from input stream */ @@ -304,6 +334,7 @@ int main (int argc, char *argv[]) // test: echo -e '{sto (1, 1 + 1), rcl (1) * 3}' | calc.exe | grep -q '=> 6' // test: echo -e '{\n{}\n{1, 2\n{sto (1, 1 + 1),\npow(2, {sto (1, 1 + 2), 2}, {rcl(2)})\n2 {sto (1, 1 + 1)}' | calc.exe | grep -c error | xargs test 6 = // test: echo -e '1 }\n1 )\n1 , 2\n ' | calc.exe | grep -c error | xargs test 3 = +// test: echo -e 'si\t\t (pi / 2)' | calc.exe | grep -q '=> 1' // Fibonacci sequence // test: echo -e '{sto (1, 1), sto (2, 1), sto (10, 1), while (inc (10) < 12 - 1, {sto (3, rcl (1) + rcl (2)), sto (1, rcl (2)), sto (2, rcl (3))})}' | calc.exe | grep '=> 144' diff --git a/parser.c b/parser.c index b4381ac..eef0846 100644 --- a/parser.c +++ b/parser.c @@ -150,6 +150,11 @@ keyword_t constants[NB_CONSTANTS] = { { "pi", Pi, 0, 2, 5} }; +#define NB_SYMBOLS 4 +char *symbols[NB_SYMBOLS] = { + "(", ")", "{", "}" +}; + /* subparser function */ element_t *subparser (element_t **proot, char **pstr, func_t func, int nbops, int prio) @@ -802,13 +807,27 @@ double evaluate_element (element_t *root, char mask) char **generate_completion_list () { - int i, l = 0; - char **list = (char **) calloc (NB_FUNCTIONS + NB_CONSTANTS + 1, sizeof (char *)); + int i, j, l = 0; + char **list = (char **) calloc (NB_OPERATORS + NB_FUNCTIONS + NB_CONSTANTS + NB_SYMBOLS + 1, sizeof (char *)); if (list == NULL) { VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); exit (1); } + for (i = 0; i < NB_OPERATORS; i++) { + list[l] = strdup ((operators + i)->keyword); + for (j = 0; j < (int)strlen (list[l]); j++) { + if (list[i][j] == '\t') { + list[i][j] = '\0'; + } + } + if (list[l] == NULL) { + VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); + exit (1); + } + l++; + } + for (i = 0; i < NB_FUNCTIONS; i++) { list[l] = strdup ((functions + i)->keyword); if (list[l] == NULL) { @@ -827,6 +846,15 @@ char **generate_completion_list () l++; } + for (i = 0; i < NB_SYMBOLS; i++) { + list[l] = strdup (symbols[i]); + if (list[l] == NULL) { + VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); + exit (1); + } + l++; + } + return (list); } -- 2.30.2