+#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);
+ }
+}