full completion feature
authorLaurent Mazet <mazet@softndesign.org>
Thu, 26 Jan 2023 22:34:22 +0000 (23:34 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 26 Jan 2023 22:34:22 +0000 (23:34 +0100)
calc.c
parser.c

diff --git a/calc.c b/calc.c
index f84cf91af829d63256a9a57e7ffe4e72715f6b73..eee39fe0b54cc34dcd1fb13eab0f0d85d94ef08a 100644 (file)
--- 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'
index b4381ac338dab2381eab0516100b276ad4779939..eef08464a87fa3855fa3d2abda00c9f52b4103f2 100644 (file)
--- 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);
 }