]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
edit: Use struct dl_list for history buffer
authorJouni Malinen <j@w1.fi>
Sun, 21 Nov 2010 09:25:34 +0000 (11:25 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 21 Nov 2010 09:25:34 +0000 (11:25 +0200)
src/utils/edit.c
src/utils/list.h

index f4d50aca28fb680e522321bcb8230cfa3776f633..a2572c7a7fb0bbf6a46bc2da684a2d641ae083d3 100644 (file)
 
 #include "common.h"
 #include "eloop.h"
+#include "list.h"
 #include "edit.h"
 
 #define CMD_BUF_LEN 256
 static char cmdbuf[CMD_BUF_LEN];
 static int cmdbuf_pos = 0;
 static int cmdbuf_len = 0;
-#define CMD_HISTORY_LEN 20
-static char history_buf[CMD_HISTORY_LEN][CMD_BUF_LEN];
-static int history_pos = 0;
-static int history_current = 0;
+
+struct edit_history {
+       struct dl_list list;
+       char str[1];
+};
+
+static struct dl_list history_list;
+static struct edit_history *history_curr;
 
 static void *edit_cb_ctx;
 static void (*edit_cmd_cb)(void *ctx, char *cmd);
@@ -171,87 +176,84 @@ static void clear_right(void)
 
 static void history_add(const char *str)
 {
-       int prev;
+       struct edit_history *h, *match = NULL;
+       size_t len;
 
        if (str[0] == '\0')
                return;
 
-       if (history_pos == 0)
-               prev = CMD_HISTORY_LEN - 1;
-       else
-               prev = history_pos - 1;
-       if (os_strcmp(history_buf[prev], str) == 0)
+       dl_list_for_each(h, &history_list, struct edit_history, list) {
+               if (os_strcmp(str, h->str) == 0) {
+                       match = h;
+                       break;
+               }
+       }
+
+       if (match) {
+               dl_list_del(&h->list);
+               dl_list_add(&history_list, &h->list);
+               history_curr = h;
                return;
+       }
 
-       os_strlcpy(history_buf[history_pos], str, CMD_BUF_LEN);
-       history_pos++;
-       if (history_pos == CMD_HISTORY_LEN)
-               history_pos = 0;
-       history_current = history_pos;
+       len = os_strlen(str);
+       h = os_zalloc(sizeof(*h) + len);
+       if (h == NULL)
+               return;
+       dl_list_add(&history_list, &h->list);
+       os_strlcpy(h->str, str, len + 1);
+       history_curr = h;
 }
 
 
-static void history_prev(void)
+static void history_use(void)
 {
-       int pos;
+       edit_clear_line();
+       cmdbuf_len = cmdbuf_pos = os_strlen(history_curr->str);
+       os_memcpy(cmdbuf, history_curr->str, cmdbuf_len);
+       edit_redraw();
+}
 
-       if (history_current == (history_pos + 1) % CMD_HISTORY_LEN)
-               return;
 
-       pos = history_current;
+static void history_prev(void)
+{
+       if (history_curr == NULL ||
+           history_curr ==
+           dl_list_last(&history_list, struct edit_history, list))
+               return;
 
-       if (history_current == history_pos && cmdbuf_len) {
+       if (history_curr ==
+           dl_list_first(&history_list, struct edit_history, list)) {
                cmdbuf[cmdbuf_len] = '\0';
                history_add(cmdbuf);
        }
 
-       if (pos > 0)
-               pos--;
-       else
-               pos = CMD_HISTORY_LEN - 1;
-       if (history_buf[pos][0] == '\0')
-               return;
-       history_current = pos;
-
-       edit_clear_line();
-       cmdbuf_len = cmdbuf_pos = os_strlen(history_buf[history_current]);
-       os_memcpy(cmdbuf, history_buf[history_current], cmdbuf_len);
-       edit_redraw();
+       history_curr = dl_list_entry(history_curr->list.next,
+                                    struct edit_history, list);
+       history_use();
 }
 
 
 static void history_next(void)
 {
-       if (history_current == history_pos)
+       if (history_curr == NULL ||
+           history_curr ==
+           dl_list_first(&history_list, struct edit_history, list))
                return;
 
-       history_current++;
-       if (history_current == CMD_HISTORY_LEN)
-           history_current = 0;
-
-       edit_clear_line();
-       cmdbuf_len = cmdbuf_pos = os_strlen(history_buf[history_current]);
-       os_memcpy(cmdbuf, history_buf[history_current], cmdbuf_len);
-       edit_redraw();
+       history_curr = dl_list_entry(history_curr->list.prev,
+                                    struct edit_history, list);
+       history_use();
 }
 
 
 static void history_debug_dump(void)
 {
-       int p;
+       struct edit_history *h;
        edit_clear_line();
        printf("\r");
-       p = (history_pos + 1) % CMD_HISTORY_LEN;
-       for (;;) {
-               printf("[%d%s%s] %s\n",
-                      p, p == history_current ? "C" : "",
-                      p == history_pos ? "P" : "", history_buf[p]);
-               if (p == history_pos)
-                       break;
-               p++;
-               if (p == CMD_HISTORY_LEN)
-                       p = 0;
-       }
+       dl_list_for_each_reverse(h, &history_list, struct edit_history, list)
+               printf("%s%s\n", h == history_curr ? "[C]" : "", h->str);
        edit_redraw();
 }
 
@@ -797,29 +799,23 @@ static int search_skip;
 
 static char * search_find(void)
 {
-       int pos = history_pos;
+       struct edit_history *h;
        size_t len = os_strlen(search_buf);
        int skip = search_skip;
 
        if (len == 0)
                return NULL;
 
-       for (;;) {
-               if (pos == 0)
-                       pos = CMD_HISTORY_LEN - 1;
-               else
-                       pos--;
-               if (pos == history_pos) {
-                       search_skip = 0;
-                       return NULL;
-               }
-
-               if (os_strstr(history_buf[pos], search_buf)) {
+       dl_list_for_each(h, &history_list, struct edit_history, list) {
+               if (os_strstr(h->str, search_buf)) {
                        if (skip == 0)
-                               return history_buf[pos];
+                               return h->str;
                        skip--;
                }
        }
+
+       search_skip = 0;
+       return NULL;
 }
 
 
@@ -1051,7 +1047,8 @@ int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
              void (*eof_cb)(void *ctx),
              void *ctx)
 {
-       os_memset(history_buf, 0, sizeof(history_buf));
+       dl_list_init(&history_list);
+       history_curr = NULL;
 
        edit_cb_ctx = ctx;
        edit_cmd_cb = cmd_cb;
@@ -1073,6 +1070,11 @@ int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
 
 void edit_deinit(void)
 {
+       struct edit_history *h;
+       while ((h = dl_list_first(&history_list, struct edit_history, list))) {
+               dl_list_del(&h->list);
+               os_free(h);
+       }
        eloop_unregister_read_sock(STDIN_FILENO);
        tcsetattr(STDIN_FILENO, TCSANOW, &prevt);
 }
index ed7c0227264f879123a2e6ee1a2efacc6dfc65d3..ded78464ab4241631ef87ba79488707c123e313d 100644 (file)
@@ -75,6 +75,10 @@ static inline unsigned int dl_list_len(struct dl_list *list)
        (dl_list_empty((list)) ? NULL : \
         dl_list_entry((list)->next, type, member))
 
+#define dl_list_last(list, type, member) \
+       (dl_list_empty((list)) ? NULL : \
+        dl_list_entry((list)->prev, type, member))
+
 #define dl_list_for_each(item, list, type, member) \
        for (item = dl_list_entry((list)->next, type, member); \
             &item->member != (list); \
@@ -86,4 +90,9 @@ static inline unsigned int dl_list_len(struct dl_list *list)
             &item->member != (list); \
             item = n, n = dl_list_entry(n->member.next, type, member))
 
+#define dl_list_for_each_reverse(item, list, type, member) \
+       for (item = dl_list_entry((list)->prev, type, member); \
+            &item->member != (list); \
+            item = dl_list_entry(item->member.prev, type, member))
+
 #endif /* LIST_H */