remove file added by mistake
[protos/libecoli.git] / src / editline.c
diff --git a/src/editline.c b/src/editline.c
deleted file mode 100644 (file)
index 449aebb..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright 2018 6WIND S.A.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <histedit.h>
-
-#include "string_utils.h"
-#include "editline.h"
-
-#define NC_CLI_HISTORY_SIZE 128
-
-struct nc_cli_editline {
-       EditLine *editline;
-       History *history;
-       HistEvent histev;
-       bool break_received;
-       nc_cli_editline_complete_t complete;
-       FILE *null_out;
-       bool interactive;
-       bool incomplete_line;
-       char *full_line;
-       char *(*prompt_cb)(EditLine *);
-};
-
-struct nc_cli_editline *nc_cli_el;
-
-static int check_quotes(const char *str)
-{
-       char quote = 0;
-       size_t i = 0;
-
-       while (str[i] != '\0') {
-               if (quote == 0) {
-                       if (str[i] == '"' || str[i] == '\'') {
-                               quote = str[i];
-                       }
-                       i++;
-                       continue;
-               } else {
-                       if (str[i] == quote) {
-                               i++;
-                               quote = 0;
-                       } else if (str[i] == '\\' && str[i+1] == quote) {
-                               i += 2;
-                       } else {
-                               i++;
-                       }
-                       continue;
-               }
-       }
-
-       return quote;
-}
-
-static int
-editline_break(EditLine *editline, int c)
-{
-       struct nc_cli_editline *el;
-       void *ptr;
-
-       (void)c;
-
-       if (el_get(editline, EL_CLIENTDATA, &ptr))
-               return CC_ERROR;
-
-       el = ptr;
-       el->break_received = true;
-       nc_cli_printf(el, "\n");
-
-       return CC_EOF;
-}
-
-static int
-editline_suspend(EditLine *editline, int c)
-{
-       (void)editline;
-       (void)c;
-
-       kill(getpid(), SIGSTOP);
-
-       return CC_NORM;
-}
-
-int
-editline_get_screen_size(struct nc_cli_editline *el, size_t *rows, size_t *cols)
-{
-       int w, h;
-
-       if (rows != NULL) {
-               if (el_get(el->editline, EL_GETTC, "li", &h, (void *)0))
-                       return -1;
-               *rows = h;
-       }
-       if (cols != NULL) {
-               if (el_get(el->editline, EL_GETTC, "co", &w, (void *)0))
-                       return -1;
-               *cols = w;
-       }
-       return 0;
-}
-
-FILE *
-nc_cli_editline_get_file(struct nc_cli_editline *el, int num)
-{
-       FILE *f;
-
-       if (el == NULL)
-               return NULL;
-       if (num > 2)
-               return NULL;
-       if (el_get(el->editline, EL_GETFP, num, &f))
-               return NULL;
-
-       return f;
-}
-
-/* match the prototype expected by qsort() */
-static int
-strcasecmp_cb(const void *p1, const void *p2)
-{
-       return strcasecmp(*(char * const *)p1, *(char * const *)p2);
-}
-
-/* Show the matches as a multi-columns list */
-int
-nc_cli_editline_print_cols(struct nc_cli_editline *el,
-                       char const * const *matches, size_t n)
-{
-       size_t max_strlen = 0, len, i, j, ncols;
-       size_t width, height;
-       const char *space;
-       char **matches_copy = NULL;
-
-       nc_cli_printf(nc_cli_el, "\n");
-       if (n == 0)
-               return 0;
-
-       if (editline_get_screen_size(el, &height, &width) < 0)
-               width = 80;
-
-       /* duplicate the matches table, and sort it */
-       matches_copy = calloc(n, sizeof(const char *));
-       if (matches_copy == NULL)
-               return -1;
-       memcpy(matches_copy, matches, sizeof(const char *) * n);
-       qsort(matches_copy, n, sizeof(char *), strcasecmp_cb);
-
-       /* get max string length */
-       for (i = 0; i < n; i++) {
-               len = strlen(matches_copy[i]);
-               if (len > max_strlen)
-                       max_strlen = len;
-       }
-
-       /* write the columns */
-       ncols = width / (max_strlen + 4);
-       if (ncols == 0)
-               ncols = 1;
-       for (i = 0; i < n; i+= ncols) {
-               for (j = 0; j < ncols; j++) {
-                       if (i + j >= n)
-                               break;
-                       if (j == 0)
-                               space = "";
-                       else
-                               space = "    ";
-                       nc_cli_printf(nc_cli_el, "%s%-*s", space,
-                               (int)max_strlen, matches[i+j]);
-               }
-               nc_cli_printf(nc_cli_el, "\n");
-       }
-
-       free(matches_copy);
-       return 0;
-}
-
-static int
-editline_complete(EditLine *editline, int c)
-{
-       enum nc_cli_editline_complete_status ret;
-       const LineInfo *line_info;
-       struct nc_cli_editline *el;
-       int len;
-       char *line;
-       void *ptr;
-
-       if (el_get(editline, EL_CLIENTDATA, &ptr))
-               return CC_ERROR;
-
-       el = ptr;
-
-       if (el->complete == NULL)
-               return CC_NORM;
-
-       line_info = el_line(editline);
-       if (line_info == NULL)
-               return CC_ERROR;
-
-       len = line_info->cursor - line_info->buffer;
-       if (asprintf(&line, "%s%.*s", el->full_line ? : "", len,
-                       line_info->buffer) < 0)
-               return CC_ERROR;
-
-       if (c == '?' && check_quotes(line) != 0) {
-               free(line);
-               el_insertstr(editline, "?");
-               return CC_REFRESH;
-       }
-
-       ret = el->complete(c, line);
-       free(line);
-
-       if (ret == ERROR)
-               return CC_ERROR;
-       else if (ret == REDISPLAY)
-               return CC_REDISPLAY;
-       else
-               return CC_REFRESH;
-}
-
-static bool is_blank_string(const char *s)
-{
-       while (*s) {
-               if (!isspace(*s))
-                       return false;
-               s++;
-       }
-       return true;
-}
-
-static char *
-multiline_prompt_cb(EditLine *e)
-{
-       (void)e;
-       return strdup("... ");
-}
-
-const char *
-nc_cli_editline_edit(struct nc_cli_editline *el)
-{
-       const char *line;
-       int count;
-
-       assert(el->editline != NULL);
-
-       if (el->incomplete_line == false) {
-               free(el->full_line);
-               el->full_line = NULL;
-       }
-
-       el->break_received = false;
-
-       if (el->incomplete_line)
-               el_set(el->editline, EL_PROMPT, multiline_prompt_cb);
-       else
-               el_set(el->editline, EL_PROMPT, el->prompt_cb);
-
-       line = el_gets(el->editline, &count);
-
-       if (line == NULL && el->break_received) {
-               free(el->full_line);
-               el->full_line = NULL;
-               el->incomplete_line = false;
-               return ""; /* abort current line */
-       }
-
-       if (line == NULL || astrcat(&el->full_line, line) < 0) {
-               free(el->full_line);
-               el->full_line = NULL;
-               el->incomplete_line = false;
-               return NULL; /* error / eof */
-       }
-
-       if (check_quotes(el->full_line) != 0) {
-               el->incomplete_line = true;
-               return "";
-       }
-
-       el->incomplete_line = false;
-       if (el->history != NULL && !is_blank_string(el->full_line))
-               history(el->history, &el->histev,
-                       H_ENTER, el->full_line);
-
-       return el->full_line;
-}
-
-int
-nc_cli_editline_register_complete(struct nc_cli_editline *el,
-                               nc_cli_editline_complete_t complete)
-{
-       const char *name;
-
-       if (el_set(el->editline, EL_ADDFN, "ed-complete",
-                       "Complete buffer",
-                       editline_complete))
-               return -1;
-
-       if (complete != NULL)
-               name = "ed-complete";
-       else
-               name = "ed-unassigned";
-       if (el_set(el->editline, EL_BIND, "^I", name, NULL))
-               return -1;
-
-       if (complete != NULL)
-               name = "ed-complete";
-       else
-               name = "ed-insert";
-       if (el_set(el->editline, EL_BIND, "?", name, NULL))
-               return -1;
-
-       el->complete = complete;
-
-       return 0;
-}
-
-int
-nc_cli_editline_insert_str(struct nc_cli_editline *el, const char *str)
-{
-       return el_insertstr(el->editline, str);
-}
-
-int nc_cli_printf(struct nc_cli_editline *el, const char *format, ...)
-{
-       FILE *out = nc_cli_editline_get_file(el, 1);
-       va_list ap;
-       int ret;
-
-       if (out == NULL)
-               out = stdout;
-
-       va_start(ap, format);
-       ret = vfprintf(out, format, ap);
-       va_end(ap);
-
-       return ret;
-}
-
-int nc_cli_eprintf(struct nc_cli_editline *el, const char *format, ...)
-{
-       FILE *out = nc_cli_editline_get_file(el, 2);
-       va_list ap;
-       int ret;
-
-       if (out == NULL)
-               out = stderr;
-
-       va_start(ap, format);
-       ret = vfprintf(out, format, ap);
-       va_end(ap);
-
-       return ret;
-}
-
-bool
-nc_cli_editline_is_interactive(struct nc_cli_editline *el)
-{
-       return el->interactive;
-}
-
-bool
-nc_cli_editline_is_running(struct nc_cli_editline *el)
-{
-       return el == nc_cli_el;
-}
-
-void
-nc_cli_editline_start(struct nc_cli_editline *el)
-{
-       nc_cli_el = el;
-}
-
-void
-nc_cli_editline_stop(struct nc_cli_editline *el)
-{
-       if (el == nc_cli_el)
-               nc_cli_el = NULL;
-}
-
-int
-nc_cli_editline_getc(struct nc_cli_editline *el)
-{
-       char c;
-
-       if (el->interactive == false)
-               return -1;
-
-       if (el_getc(el->editline, &c) != 1)
-               return -1;
-
-       return c;
-}
-
-int
-nc_cli_editline_resize(struct nc_cli_editline *el)
-{
-       el_resize(el->editline);
-       return 0;
-}
-
-int nc_cli_editline_set_prompt_cb(struct nc_cli_editline *el,
-                               char *(*prompt_cb)(EditLine *el))
-{
-       el->prompt_cb = prompt_cb;
-       return 0;
-}
-
-int
-nc_cli_editline_mask_interrupts(bool do_mask)
-{
-       const char *setty = do_mask ? "-isig" : "+isig";
-
-       if (nc_cli_el == NULL)
-               return -1;
-
-       if (nc_cli_el->interactive == false)
-               return 0;
-
-       if (el_set(nc_cli_el->editline, EL_SETTY, "-d", setty, NULL))
-               return -1;
-
-       return 0;
-}
-
-struct nc_cli_editline *
-nc_cli_editline_init(FILE *f_in, FILE *f_out, FILE *f_err, bool interactive,
-               char *(*prompt_cb)(EditLine *el))
-{
-       struct nc_cli_editline *el = NULL;
-
-       el = calloc(1, sizeof(*el));
-       if (el == NULL)
-               goto fail;
-       if (f_in == NULL) {
-               errno = EINVAL;
-               goto fail;
-       }
-       if (f_out == NULL || f_err == NULL) {
-               el->null_out = fopen("/dev/null", "w");
-               if (el->null_out == NULL)
-                       goto fail;
-       }
-       if (f_out == NULL)
-               f_out = el->null_out;
-       if (f_err == NULL)
-               f_err = el->null_out;
-
-       el->interactive = interactive;
-       el->prompt_cb = prompt_cb;
-
-       el->editline = el_init("nc-cli", f_in, f_out, f_err);
-       if (el->editline == NULL)
-               goto fail;
-
-       if (el_set(el->editline, EL_SIGNAL, 1))
-               goto fail;
-
-       if (el_set(el->editline, EL_CLIENTDATA, el))
-               goto fail;
-
-       if (el_set(el->editline, EL_PROMPT, prompt_cb))
-               goto fail;
-
-       if (interactive == false)
-               goto end;
-
-       if (el_set(el->editline, EL_PREP_TERM, 0))
-               goto fail;
-
-       if (el_set(el->editline, EL_EDITOR, "emacs"))
-               goto fail;
-
-       if (el_set(el->editline, EL_SETTY, "-d", "-isig", NULL))
-               goto fail;
-       if (el_set(el->editline, EL_ADDFN, "ed-break",
-                       "Break and flush the buffer",
-                       editline_break))
-               goto fail;
-       if (el_set(el->editline, EL_BIND, "^C", "ed-break", NULL))
-               goto fail;
-       if (el_set(el->editline, EL_ADDFN, "ed-suspend",
-                       "Suspend the terminal",
-                       editline_suspend))
-               goto fail;
-       if (el_set(el->editline, EL_BIND, "^Z", "ed-suspend", NULL))
-               goto fail;
-       if (el_set(el->editline, EL_BIND, "^W", "ed-delete-prev-word", NULL))
-               goto fail;
-
-       el->history = history_init();
-       if (!el->history)
-               goto fail;
-       if (history(el->history, &el->histev, H_SETSIZE,
-                       NC_CLI_HISTORY_SIZE) < 0)
-               goto fail;
-       if (history(el->history, &el->histev,
-                       H_SETUNIQUE, 1))
-               goto fail;
-       if (el_set(el->editline, EL_HIST, history,
-                       el->history))
-               goto fail;
-
-end:
-       return el;
-
-fail:
-       if (el != NULL) {
-               if (el->null_out != NULL)
-                       fclose(el->null_out);
-               if (el->history != NULL)
-                       history_end(el->history);
-               if (el->editline != NULL)
-                       el_end(el->editline);
-               free(el);
-       }
-       return NULL;
-}
-
-void
-nc_cli_editline_free(struct nc_cli_editline *el)
-{
-       if (el == NULL)
-               return;
-       nc_cli_editline_stop(el);
-       if (el->null_out != NULL)
-               fclose(el->null_out);
-       if (el->history != NULL)
-               history_end(el->history);
-       el_end(el->editline);
-       free(el->full_line);
-       free(el);
-}