move all code relative to readline into separate file
authorLaurent Mazet <mazet@softndesign.org>
Mon, 6 Mar 2023 20:54:34 +0000 (21:54 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Mon, 6 Mar 2023 20:54:34 +0000 (21:54 +0100)
calc.c
readline.c [new file with mode: 0644]
readline.h [new file with mode: 0644]

diff --git a/calc.c b/calc.c
index 98372cef9f0c62d66a04b05619775ecb043d3661..e351369c9d817dd550e9cdc8acdd901a31ebfa88 100644 (file)
--- a/calc.c
+++ b/calc.c
@@ -1,32 +1,26 @@
 /* depend: */
 /* cflags: */
-/* linker: alloc.o argument.o color.o debug.o element.o format.o parser.o program.o stack.o storage.o tabular.o workspace.o -lm -lreadline */
+/* linker: alloc.o argument.o color.o debug.o element.o format.o parser.o program.o readline.o stack.o storage.o tabular.o workspace.o -lm -lreadline */
 
 #include <malloc.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
-#include <readline/readline.h>
-#include <readline/history.h>
-
 #include "debug.h"
 #include "element.h"
 #include "format.h"
 #include "parser.h"
+#include "readline.h"
 
 /* constants */
 
 #define BUFFER_SIZE 4096
-#define HISTORY_LEN 10
 
 /* macros */
 
-#define CEIL(x, y) (((x) + (y) - 1) / (y))
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#define MAX(x, y) (((x) > (y)) ? (x) : (y))
-
 /* gobal variables */
 
 char *progname = NULL;
@@ -34,7 +28,6 @@ char *iprompt = "<= ";
 int mode = 1;
 char *oprompt = "=> ";
 int precision = 6;
-char **completion_list = NULL;
 
 /* help function */
 
@@ -53,68 +46,6 @@ 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;
-}
-
-/* edit line */
-char *edit_line = NULL;
-int edit_hook ()
-{
-    static int state = 0;
-    if (edit_line) {
-        if (state == 0) {
-            state = 1;
-        } else {
-            state = 0;
-            free (edit_line);
-            edit_line = NULL;
-        }
-    }
-    return rl_insert_text (edit_line);
-}
-
-/* history management */
-
-void history ()
-{
-    HIST_ENTRY **entries = history_list ();
-    if (entries == NULL) {
-        VERBOSE (WARNING, fprintf (stdout, "no history\n"));
-    } else {
-        int i = 0;
-        while (entries[i] != NULL) {
-            printf ("%d: %s\n", history_length - i, entries[i]->line);
-            i++;
-        }
-    }
-}
-
 /* main function */
 
 int main (int argc, char *argv[])
@@ -210,14 +141,10 @@ int main (int argc, char *argv[])
     /* set format */
     set_format ();
 
-    /* completion list*/
-    completion_list = generate_completion_list ();
-    rl_attempted_completion_function = completion;
-
-    /* readline parameters */
-    rl_startup_hook = edit_hook;
-    rl_variable_bind ("blink-matching-paren", "On");
-    //rl_set_screen_size (50, 40);
+    /* init readline */
+    if (mode) {
+        init_read_line ();
+    }
 
     /* read from input stream */
 
@@ -225,35 +152,27 @@ int main (int argc, char *argv[])
         char *line[BUFFER_SIZE] = {0};
 
         if (mode) {
-            if ((buffer = readline (iprompt)) == NULL) {
+            if (read_line (&buffer, iprompt)) {
                 break;
             }
 
             /* check empty line */
-            if (strlen (buffer) == 0) {
-                free (buffer);
+            if (buffer == NULL) {
                 continue;
-            } else if (strcmp (buffer, ".") == 0) {
-                free (buffer);
-                break;
             }
 
             /* add line into history */
-            add_history (buffer);
-            VERBOSE (INFO, fprintf (stdout, "line (%d/%d): '%s'\n",
-                                    where_history (), history_length, buffer));
-            if (history_length > HISTORY_LEN) {
-                HIST_ENTRY *last = remove_history (0);
-                if (last) {
-                    free_history_entry (last);
-                }
-            }
+            manage_history (buffer);
+
         } else {
             printf ("%s", iprompt);
             if (read (STDIN_FILENO, buffer, BUFFER_SIZE) == 0) {
                 break;
             }
-            VERBOSE (INFO, fprintf (stdout, "line: '%s'\n", buffer));
+        }
+
+        if (strcmp (buffer, ".") == 0) {
+            break;
         }
 
         /* pre-process buffer */
@@ -298,7 +217,7 @@ int main (int argc, char *argv[])
         fflush (stdout);
     }
 
-    free_completion_list (completion_list);
+    clean_read_line (buffer);
 
     free_format ();
 
diff --git a/readline.c b/readline.c
new file mode 100644 (file)
index 0000000..4b234f4
--- /dev/null
@@ -0,0 +1,140 @@
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "debug.h"
+#include "parser.h"
+
+#include "readline.h"
+
+/* constants */
+
+#define HISTORY_LEN 10
+
+/* macros */
+
+/* gobal variables */
+
+char **completion_list = NULL;
+
+/* completion function */
+
+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;
+}
+
+char **completion (const char *text, __attribute__((unused)) int start, __attribute__((unused)) int end)
+{
+    rl_attempted_completion_over = 1;
+    return rl_completion_matches (text, generator);
+}
+
+/* edit line */
+char *edit_line = NULL;
+int edit_hook ()
+{
+    static int state = 0;
+    if (edit_line) {
+        if (state == 0) {
+            state = 1;
+        } else {
+            state = 0;
+            free (edit_line);
+            edit_line = NULL;
+        }
+    }
+    return rl_insert_text (edit_line);
+}
+
+/* history management */
+
+void history ()
+{
+    HIST_ENTRY **entries = history_list ();
+    if (entries == NULL) {
+        VERBOSE (WARNING, fprintf (stdout, "no history\n"));
+    } else {
+        int i = 0;
+        while (entries[i] != NULL) {
+            printf ("%d: %s\n", history_length - i, entries[i]->line);
+            i++;
+        }
+    }
+}
+
+/* init readline */
+
+void init_read_line ()
+{
+    /* completion list*/
+    completion_list = generate_completion_list ();
+    rl_attempted_completion_function = completion;
+
+    /* edit program */
+    rl_startup_hook = edit_hook;
+
+    /* readline parameters */
+    rl_variable_bind ("blink-matching-paren", "On");
+    //rl_set_screen_size (50, 40);
+}
+
+/* read line */
+
+int read_line (char **buffer, char *prompt)
+{
+    if ((*buffer = readline (prompt)) == NULL) {
+       return 1;
+    }
+
+    /* check empty line */
+    if (strlen (*buffer) == 0) {
+        free (*buffer);
+        *buffer = NULL;
+    }
+
+    return 0;
+}
+
+/* manage history */
+
+void manage_history (char *buffer)
+{
+    /* add line into history */
+    add_history (buffer);
+    VERBOSE (INFO, fprintf (stdout, "line (%d/%d): '%s'\n",
+                            where_history (), history_length, buffer));
+    if (history_length > HISTORY_LEN) {
+        HIST_ENTRY *last = remove_history (0);
+        if (last) {
+            free_history_entry (last);
+        }
+    }
+}
+
+/* clean readline */
+
+void clean_read_line (char *buffer)
+{
+    free_completion_list (completion_list);
+    if (buffer) {
+        free (buffer);
+    }
+}
diff --git a/readline.h b/readline.h
new file mode 100644 (file)
index 0000000..dcd143c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __READLINE_H__
+#define __READLINE_H__
+
+void init_read_line ();
+int read_line (char **buffer, char *prompt);
+void manage_history (char *buffer);
+void clean_read_line (char *buffer);
+
+#endif /* __READLINE_H__ */