]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/utils/edit.c
tests: HE AP parameters
[thirdparty/hostap.git] / src / utils / edit.c
index 96cf736fae350f3f871125ca75a6de7f64d53a4c..d340bfadd1f13b746973b7f0a55723c693b50e4e 100644 (file)
@@ -1,15 +1,9 @@
 /*
  * Command line editing and history
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
 #include "list.h"
 #include "edit.h"
 
-#define CMD_BUF_LEN 256
+#define CMD_BUF_LEN 4096
 static char cmdbuf[CMD_BUF_LEN];
 static int cmdbuf_pos = 0;
 static int cmdbuf_len = 0;
+static char currbuf[CMD_BUF_LEN];
+static int currbuf_valid = 0;
+static const char *ps2 = NULL;
+
+#define HISTORY_MAX 100
 
 struct edit_history {
        struct dl_list list;
@@ -49,7 +48,7 @@ void edit_clear_line(void)
 {
        int i;
        putchar('\r');
-       for (i = 0; i < cmdbuf_len + 2; i++)
+       for (i = 0; i < cmdbuf_len + 2 + (ps2 ? (int) os_strlen(ps2) : 0); i++)
                putchar(' ');
 }
 
@@ -176,8 +175,8 @@ static void clear_right(void)
 
 static void history_add(const char *str)
 {
-       struct edit_history *h, *match = NULL;
-       size_t len;
+       struct edit_history *h, *match = NULL, *last = NULL;
+       size_t len, count = 0;
 
        if (str[0] == '\0')
                return;
@@ -187,6 +186,8 @@ static void history_add(const char *str)
                        match = h;
                        break;
                }
+               last = h;
+               count++;
        }
 
        if (match) {
@@ -196,6 +197,11 @@ static void history_add(const char *str)
                return;
        }
 
+       if (count >= HISTORY_MAX && last) {
+               dl_list_del(&last->list);
+               os_free(last);
+       }
+
        len = os_strlen(str);
        h = os_zalloc(sizeof(*h) + len);
        if (h == NULL)
@@ -217,17 +223,24 @@ static void history_use(void)
 
 static void history_prev(void)
 {
-       if (history_curr == NULL ||
-           history_curr ==
-           dl_list_last(&history_list, struct edit_history, list))
+       if (history_curr == NULL)
                return;
 
        if (history_curr ==
            dl_list_first(&history_list, struct edit_history, list)) {
-               cmdbuf[cmdbuf_len] = '\0';
-               history_add(cmdbuf);
+               if (!currbuf_valid) {
+                       cmdbuf[cmdbuf_len] = '\0';
+                       os_memcpy(currbuf, cmdbuf, cmdbuf_len + 1);
+                       currbuf_valid = 1;
+                       history_use();
+                       return;
+               }
        }
 
+       if (history_curr ==
+           dl_list_last(&history_list, struct edit_history, list))
+               return;
+
        history_curr = dl_list_entry(history_curr->list.next,
                                     struct edit_history, list);
        history_use();
@@ -238,8 +251,16 @@ static void history_next(void)
 {
        if (history_curr == NULL ||
            history_curr ==
-           dl_list_first(&history_list, struct edit_history, list))
+           dl_list_first(&history_list, struct edit_history, list)) {
+               if (currbuf_valid) {
+                       currbuf_valid = 0;
+                       edit_clear_line();
+                       cmdbuf_len = cmdbuf_pos = os_strlen(currbuf);
+                       os_memcpy(cmdbuf, currbuf, cmdbuf_len);
+                       edit_redraw();
+               }
                return;
+       }
 
        history_curr = dl_list_entry(history_curr->list.prev,
                                     struct edit_history, list);
@@ -247,6 +268,49 @@ static void history_next(void)
 }
 
 
+static void history_read(const char *fname)
+{
+       FILE *f;
+       char buf[CMD_BUF_LEN], *pos;
+
+       f = fopen(fname, "r");
+       if (f == NULL)
+               return;
+
+       while (fgets(buf, CMD_BUF_LEN, f)) {
+               for (pos = buf; *pos; pos++) {
+                       if (*pos == '\r' || *pos == '\n') {
+                               *pos = '\0';
+                               break;
+                       }
+               }
+               history_add(buf);
+       }
+
+       fclose(f);
+}
+
+
+static void history_write(const char *fname,
+                         int (*filter_cb)(void *ctx, const char *cmd))
+{
+       FILE *f;
+       struct edit_history *h;
+
+       f = fopen(fname, "w");
+       if (f == NULL)
+               return;
+
+       dl_list_for_each_reverse(h, &history_list, struct edit_history, list) {
+               if (filter_cb && filter_cb(edit_cb_ctx, h->str))
+                       continue;
+               fprintf(f, "%s\n", h->str);
+       }
+
+       fclose(f);
+}
+
+
 static void history_debug_dump(void)
 {
        struct edit_history *h;
@@ -254,6 +318,8 @@ static void history_debug_dump(void)
        printf("\r");
        dl_list_for_each_reverse(h, &history_list, struct edit_history, list)
                printf("%s%s\n", h == history_curr ? "[C]" : "", h->str);
+       if (currbuf_valid)
+               printf("{%s}\n", currbuf);
        edit_redraw();
 }
 
@@ -279,9 +345,9 @@ static void insert_char(int c)
 
 static void process_cmd(void)
 {
-
+       currbuf_valid = 0;
        if (cmdbuf_len == 0) {
-               printf("\n");
+               printf("\n%s> ", ps2 ? ps2 : "");
                fflush(stdout);
                return;
        }
@@ -291,7 +357,7 @@ static void process_cmd(void)
        cmdbuf_pos = 0;
        cmdbuf_len = 0;
        edit_cmd_cb(edit_cb_ctx, cmdbuf);
-       printf("");
+       printf("%s> ", ps2 ? ps2 : "");
        fflush(stdout);
 }
 
@@ -663,6 +729,7 @@ static enum edit_key_code esc_seq_to_key(char *seq)
        int param1 = -1, param2 = -1;
        enum edit_key_code ret = EDIT_KEY_NONE;
 
+       last = '\0';
        for (pos = seq; *pos; pos++)
                last = *pos;
 
@@ -1046,10 +1113,13 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
 int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
              void (*eof_cb)(void *ctx),
              char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
-             void *ctx, const char *history_file)
+             void *ctx, const char *history_file, const char *ps)
 {
+       currbuf[0] = '\0';
        dl_list_init(&history_list);
        history_curr = NULL;
+       if (history_file)
+               history_read(history_file);
 
        edit_cb_ctx = ctx;
        edit_cmd_cb = cmd_cb;
@@ -1063,7 +1133,8 @@ int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
 
        eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);
 
-       printf("> ");
+       ps2 = ps;
+       printf("%s> ", ps2 ? ps2 : "");
        fflush(stdout);
 
        return 0;
@@ -1074,10 +1145,15 @@ void edit_deinit(const char *history_file,
                 int (*filter_cb)(void *ctx, const char *cmd))
 {
        struct edit_history *h;
+       if (history_file)
+               history_write(history_file, filter_cb);
        while ((h = dl_list_first(&history_list, struct edit_history, list))) {
                dl_list_del(&h->list);
                os_free(h);
        }
+       edit_clear_line();
+       putchar('\r');
+       fflush(stdout);
        eloop_unregister_read_sock(STDIN_FILENO);
        tcsetattr(STDIN_FILENO, TCSANOW, &prevt);
 }
@@ -1087,11 +1163,11 @@ void edit_redraw(void)
 {
        char tmp;
        cmdbuf[cmdbuf_len] = '\0';
-       printf("\r> %s", cmdbuf);
+       printf("\r%s> %s", ps2 ? ps2 : "", cmdbuf);
        if (cmdbuf_pos != cmdbuf_len) {
                tmp = cmdbuf[cmdbuf_pos];
                cmdbuf[cmdbuf_pos] = '\0';
-               printf("\r> %s", cmdbuf);
+               printf("\r%s> %s", ps2 ? ps2 : "", cmdbuf);
                cmdbuf[cmdbuf_pos] = tmp;
        }
        fflush(stdout);