From: Laurent Mazet Date: Mon, 6 Mar 2023 20:54:34 +0000 (+0100) Subject: move all code relative to readline into separate file X-Git-Tag: v1.2~3 X-Git-Url: https://secure.softndesign.org/git/?p=calc.git;a=commitdiff_plain;h=8fbd465183a1657cc20a75caa4c2f00010f38c2d move all code relative to readline into separate file --- diff --git a/calc.c b/calc.c index 98372ce..e351369 100644 --- 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 #include #include #include +#include #include -#include -#include - #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 index 0000000..4b234f4 --- /dev/null +++ b/readline.c @@ -0,0 +1,140 @@ +#include +#include +#include + +#include +#include + +#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 index 0000000..dcd143c --- /dev/null +++ b/readline.h @@ -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__ */