home · contact · privacy
In client, keybinding databases now store keybindings as arrays instead
authorChristian Heller <c.heller@plomlompom.de>
Mon, 10 Mar 2014 11:55:57 +0000 (12:55 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 10 Mar 2014 11:55:57 +0000 (12:55 +0100)
of linked lists.

TODO
src/client/control.c
src/client/draw_wins.c
src/client/keybindings.c
src/client/keybindings.h
src/client/misc.c
src/client/windows.c

diff --git a/TODO b/TODO
index 7a18afd08450e12b115a2419ec82b4dadf76089d..766b12dc001273b7065848299cc03209d7d3b30c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -32,7 +32,3 @@ CLIENT:
 - enable toggling of showing "\n" in the window content either as newline breaks
   (as currently) or as " / " (without newline break) for more efficent screen
   estate use
-
-- does get_n_of_keybs() really need to be its own function? (only used once)
-
-- transform Keybindings struct series from a linked list into an array
index dff79ab34fe7ebf7430d6f519e9ffe6cf4a18df3..f236ecf9a8e808f79476e8d654e7568d4e631a02 100644 (file)
@@ -149,21 +149,21 @@ static uint8_t try_server_commands(struct Command * command)
 
 extern uint8_t try_key(uint16_t key)
 {
-    struct Command * command = get_command_to_keycode(world.kb_global.kbs, key);
+    struct Command * command = get_command_to_keycode(&world.kb_global, key);
     if (!command && world.winDB.active)
     {
         struct Win * w = get_win_by_id(world.winDB.active);
         if      (0 == w->view)
         {
-            command = get_command_to_keycode(w->kb.kbs, key);
+            command = get_command_to_keycode(&w->kb, key);
         }
         else if (1 == w->view)
         {
-            command = get_command_to_keycode(world.kb_wingeom.kbs, key);
+            command = get_command_to_keycode(&world.kb_wingeom, key);
         }
         else if (2 == w->view)
         {
-            command = get_command_to_keycode(world.kb_winkeys.kbs, key);
+            command = get_command_to_keycode(&world.kb_winkeys, key);
         }
     }
     if (command)
index 59b7c3aa444bb62642dc946737ce74bec0d3740a..46ef8ed93e838fbf30889a71c0b8beef708342fa 100644 (file)
@@ -38,19 +38,19 @@ static void add_line(struct Win * w, char * line, attr_t attri);
  */
 static void draw_text_from_bottom(struct Win * win, char * text);
 
-/* Return keybinding list line via "kb_pp", iterate pointer pointed to by it. */
-static char * get_kb_line_and_iterate(struct KeyBinding ** kb_pp);
+/* Return a properly formatted keybinding list line for "kb". */
+static char * get_kb_line(struct KeyBinding * kb);
 
 /* Draw from line "start" on config view for keybindings defined at "kb". */
 static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb,
                                    uint8_t start);
 
 /* Draw into window "w" from line "start" on a "title" followed by an empty
- * line followed by a list of all keybindings starting at kb_p.
+ * line followed by a list of all keybindings starting in "kbdb".
  */
 static uint16_t draw_titled_keybinding_list(char * title, struct Win * w,
                                             uint16_t start,
-                                            struct KeyBinding * kb_p);
+                                            struct KeyBindingDB * kbdb);
 
 
 
@@ -231,44 +231,40 @@ static void draw_text_from_bottom(struct Win * win, char * text)
 
 
 
-static char * get_kb_line_and_iterate(struct KeyBinding ** kb_pp)
+static char * get_kb_line(struct KeyBinding * kb)
 {
-    char * f_name = "get_kb_line_and_iterate()";
-    struct KeyBinding * kb_p = * kb_pp;
-    char * keyname = get_keyname_to_keycode(kb_p->keycode);
-    struct Command * command = get_command_to_keycode(kb_p, kb_p->keycode);
-    uint16_t size = 9 + 1 + strlen(command->dsc_long) + 1;
-    char * line = try_malloc(size, f_name);
-    sprintf(line, "%-9s %s", keyname, command->dsc_long);
+    char * f_name = "get_kb_line()";
+    char * keyname = get_keyname_to_keycode(kb->keycode);
+    uint16_t size = 9 + 1 + strlen(kb->command->dsc_long) + 1;
+    char * kb_line = try_malloc(size, f_name);
+    sprintf(kb_line, "%-9s %s", keyname, kb->command->dsc_long);
     free(keyname);
-    * kb_pp = kb_p->next;
-    return line;
+    return kb_line;
 }
 
 
 
-static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb,
+static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kbdb,
                                    uint8_t start)
 {
-    if (0 == kb->kbs)
+    if (0 == kbdb->n_of_kbs)
     {
         add_line(w, "(none)", 0);
         return;
     }
-    struct KeyBinding * kb_p = kb->kbs;
-    uint16_t y;
-    for (y = start; 0 != kb_p; y++)
+    uint16_t y, kb_n;
+    for (y = start, kb_n = 0; kb_n < kbdb->n_of_kbs; y++, kb_n++)
     {
         attr_t attri = 0;
-        if (y - start == kb->select)
+        if (y - start == kbdb->select)
         {
             attri = A_REVERSE;
-            if (1 == kb->edit)
+            if (1 == kbdb->edit)
             {
                 attri = attri | A_BLINK;
             }
         }
-        char * kb_line = get_kb_line_and_iterate(&kb_p);
+        char * kb_line = get_kb_line(&kbdb->kbs[kb_n]);
         add_line(w, kb_line, attri);
         free(kb_line);
     }
@@ -278,21 +274,22 @@ static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb,
 
 static uint16_t draw_titled_keybinding_list(char * title, struct Win * w,
                                             uint16_t start,
-                                            struct KeyBinding * kb_p)
+                                            struct KeyBindingDB * kbdb)
 {
     uint16_t y;
     uint8_t state = 0;
-    for (y = start; (0 == state || 0 != kb_p); y++)
+    uint16_t kb_n = 0;
+    for (y = start; (0 == state || kb_n < kbdb->n_of_kbs); y++, kb_n++)
     {
         if (0 == state)
         {
             add_line(w, title, 0);
             y++;
             add_line(w, " ", 0);
-            state = 1 + (0 == kb_p);
+            state = 1 + (0 == kbdb->n_of_kbs);
             continue;
         }
-        char * kb_line = get_kb_line_and_iterate(&kb_p);
+        char * kb_line = get_kb_line(&kbdb->kbs[kb_n]);
         add_line(w, kb_line, 0);
         free(kb_line);
     }
@@ -379,24 +376,24 @@ extern void draw_win_inventory(struct Win * win)
 extern void draw_win_available_keybindings(struct Win * win)
 {
     char * title = "Active window's keybindings:";
-    struct KeyBinding * kb_p;
+    struct KeyBindingDB * kbdb;
     struct Win * w = get_win_by_id(world.winDB.active);
     if     (0 == w->view)
     {
-        kb_p = w->kb.kbs;
+        kbdb = &w->kb;
     }
     else if (1 == w->view)
     {
-        kb_p = world.kb_wingeom.kbs;
+        kbdb = &world.kb_wingeom;
     }
     else if (2 == w->view)
     {
-        kb_p = world.kb_winkeys.kbs;
+        kbdb = &world.kb_winkeys;
     }
-    uint16_t offset = draw_titled_keybinding_list(title, win, 0, kb_p);
+    uint16_t offset = draw_titled_keybinding_list(title, win, 0, kbdb);
     add_line(win, " ", 0);
-    struct KeyBinding * kbs_glo = world.kb_global.kbs;
-    draw_titled_keybinding_list("Global keybindings", win, offset + 1, kbs_glo);
+    draw_titled_keybinding_list("Global keybindings", win, offset + 1,
+                                &world.kb_global);
 }
 
 
index bad527f57f4e66c97b90406d342af815188048f2..f148afa3371744a0c804ce84266bfb1858589f7d 100644 (file)
@@ -5,23 +5,18 @@
 #include <stddef.h> /* NULL */
 #include <stdint.h> /* uint8_t, uint16_t, uint32_t */
 #include <stdio.h> /* FILE, sprintf() */
-#include <stdlib.h> /* free(), atoi() */
+#include <stdlib.h> /* atoi() */
 #include <string.h> /* strlen(), strchr(), strcmp() */
 #include "../common/err_try_fgets.h" /* err_try_fgets(), err_line() */
 #include "../common/readwrite.h" /* try_fwrite()*/
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "command_db.h" /* get_command() */
+#include "misc.h" /* array_append() */
 #include "windows.h" /* draw_all_wins() */
 #include "world.h" /* global world */
 
 
 
-/* Return "n"-th keybinding in keybindings chain from "kb_p" on. */
-static struct KeyBinding * get_keyb_of_n(struct KeyBinding * kb_p, uint16_t n);
-
-/* Return number of keybindings in keybindings chain from "kb_p" on. */
-static uint16_t get_n_of_keybs(struct KeyBinding * kb_p);
-
 /* Return pointer to global keybindings or to keybindings for wingeometry config
  * (c = "g") or winkeys config (c = "k") or active window's keybindings ("w").
  */
@@ -35,58 +30,24 @@ static uint8_t try_keycode(uint16_t keycode_given, char * keyname,
 
 
 
-static struct KeyBinding * get_keyb_of_n(struct KeyBinding * kb_p, uint16_t n)
-{
-    uint16_t i = 0;
-    while (1)
-    {
-        if (n == i)
-        {
-            break;
-        }
-        i++;
-        kb_p = kb_p->next;
-    }
-    return kb_p;
-}
-
-
-
-static uint16_t get_n_of_keybs(struct KeyBinding * kb_p)
-{
-    uint16_t i = 0;
-    while (1)
-    {
-        if (0 == kb_p)
-        {
-            break;
-        }
-        i++;
-        kb_p = kb_p->next;
-    }
-    return i;
-}
-
-
-
 static struct KeyBindingDB * char_selected_kb_db(char c)
 {
-    struct KeyBindingDB * kbd;
-    kbd = &world.kb_global;
+    struct KeyBindingDB * kbdb;
+    kbdb = &world.kb_global;
     if      ('g' == c)
     {
-        kbd = &world.kb_wingeom;
+        kbdb = &world.kb_wingeom;
     }
     else if ('k' == c)
     {
-        kbd = &world.kb_winkeys;
+        kbdb = &world.kb_winkeys;
     }
     else if ('w' == c)
     {
         struct Win * w = get_win_by_id(world.winDB.active);
-        kbd = &w->kb;
+        kbdb = &w->kb;
     }
-    return kbd;
+    return kbdb;
 }
 
 
@@ -104,16 +65,16 @@ static uint8_t try_keycode(uint16_t keycode_given, char * keyname,
 
 
 
-extern struct Command * get_command_to_keycode(struct KeyBinding * kb_p,
+extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb,
                                                uint16_t keycode)
 {
-    while (0 != kb_p)
+    uint16_t n_kb;
+    for (n_kb = 0; n_kb < kbdb->n_of_kbs; n_kb++)
     {
-        if (keycode == kb_p->keycode)
+        if (keycode == kbdb->kbs[n_kb].keycode)
         {
-            return kb_p->command;
+            return kbdb->kbs[n_kb].command;
         }
-        kb_p = kb_p->next;
     }
     return NULL;
 }
@@ -164,23 +125,21 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd)
 {
     char * f_name = "write_keybindings_to_file()";
     uint16_t linemax = 0;
-    struct KeyBinding * kb_p = kbd->kbs;
-    while (0 != kb_p)
+    uint16_t n_kb;
+    for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++)
     {
-        if (strlen(kb_p->command->dsc_short) > linemax)
+        if (strlen(kbd->kbs[n_kb].command->dsc_short) > linemax)
         {
-            linemax = strlen(kb_p->command->dsc_short);
+            linemax = strlen(kbd->kbs[n_kb].command->dsc_short);
         }
-        kb_p = kb_p->next;
     }
     linemax = linemax + 6;            /* + 6 = + 3 digits + ' ' + '\n' + '\0' */
     char line[linemax];
-    kb_p = kbd->kbs;
-    while (0 != kb_p)
+    for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++)
     {
-        sprintf(line, "%d %s\n", kb_p->keycode, kb_p->command->dsc_short);
+        sprintf(line, "%d %s\n",
+                kbd->kbs[n_kb].keycode, kbd->kbs[n_kb].command->dsc_short);
         try_fwrite(line, sizeof(char), strlen(line), file, f_name);
-        kb_p = kb_p->next;
     }
     try_fwrite(world.delim, strlen(world.delim), 1, file, f_name);
 }
@@ -188,17 +147,15 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd)
 
 
 extern void read_keybindings_from_file(char * line, uint32_t linemax,
-                                       FILE * file, struct KeyBindingDB * kbd)
+                                       FILE * file, struct KeyBindingDB * kbdb)
 {
-    char * f_name = "read_keybindings_from_file()";
     char * context = "Failed reading keybindings from interface config file. ";
     char * err_space    = "Line illegally ends in whitespace.";
     char * err_nospace  = "No whitespace found in line.";
     char * err_int      = "Line starts not with a decimal number in digits.";
     char * err_toolarge = "Keycode number too large, must be below 1000.";
     char * err_cmd      = "No such command in command DB.";
-    struct KeyBinding ** loc_last_ptr = &kbd->kbs;
-    * loc_last_ptr = 0;
+    kbdb->n_of_kbs = 0;
     while (1)
     {
         err_try_fgets(line, linemax, file, context, "0nf");
@@ -216,62 +173,46 @@ extern void read_keybindings_from_file(char * line, uint32_t linemax,
             err_line(line[i] < '0' || '9' < line[i], line, context, err_int);
         }
         err_line(i > 3, line, context, err_toolarge);
-        * loc_last_ptr = try_malloc(sizeof(struct KeyBinding), f_name);
-        struct KeyBinding * kb_p = * loc_last_ptr;
-        line[strlen(line) - 1] = '\0';
-        kb_p->command = get_command(ptr_space + 1);
-        err_line(!(kb_p->command), line, context, err_cmd);
-        kb_p->next = 0;
-        kb_p->keycode = atoi(line);
-        loc_last_ptr = & kb_p->next;
-    }
-}
-
 
-
-extern void free_keybindings(struct KeyBinding * kb_start)
-{
-    if (0 == kb_start)
-    {
-        return;
-    }
-    struct KeyBinding * kb_p = kb_start->next;
-    if (0 != kb_p)
-    {
-        free_keybindings(kb_p);
+        struct KeyBinding kb;
+        line[strlen(line) - 1] = '\0';
+        kb.command = get_command(ptr_space + 1);
+        err_line(!(kb.command), line, context, err_cmd);
+        kb.keycode = atoi(line);
+        array_append(kbdb->n_of_kbs, sizeof(struct KeyBinding), (void *) &kb,
+                     (void **) kbdb);
+        kbdb->n_of_kbs++;
     }
-    free(kb_start);
 }
 
 
 
 extern void mod_selected_keyb(char kb_c)
 {
-    struct KeyBindingDB * kbd = char_selected_kb_db(kb_c);
-    kbd->edit = 1;
+    struct KeyBindingDB * kbdb = char_selected_kb_db(kb_c);
+    kbdb->edit = 1;
     draw_all_wins();
     cbreak();
     int keycode = getch();
     halfdelay(world.halfdelay);
     if (keycode < 1000)
     {
-        struct KeyBinding * kb_p = get_keyb_of_n(kbd->kbs, kbd->select);
-        kb_p->keycode = keycode;
+        kbdb->kbs[kbdb->select].keycode = keycode;
     }
-    kbd->edit = 0;
+    kbdb->edit = 0;
 }
 
 
 
 extern void move_keyb_selection(char kb_c, char dir)
 {
-    struct KeyBindingDB * kbd = char_selected_kb_db(kb_c);
-    if      ('u' == dir && kbd->select > 0)
+    struct KeyBindingDB * kbdb = char_selected_kb_db(kb_c);
+    if      ('u' == dir && kbdb->select > 0)
     {
-        kbd->select--;
+        kbdb->select--;
     }
-    else if ('d' == dir && kbd->select < get_n_of_keybs(kbd->kbs) - 1)
+    else if ('d' == dir && kbdb->select < kbdb->n_of_kbs - 1)
     {
-        kbd->select++;
+        kbdb->select++;
     }
 }
index 0d426e3e85602b144c6c120e6a75455a4a00219b..763ca56ca7bc27ee4f783dfa0f9461ab76abd4b5 100644 (file)
@@ -14,7 +14,6 @@ struct Command;
 
 struct KeyBinding
 {
-  struct KeyBinding * next;
   uint16_t keycode;
   struct Command * command; /* command in command DB to which key is bound */
 };
@@ -22,14 +21,15 @@ struct KeyBinding
 struct KeyBindingDB
 {
     struct KeyBinding * kbs;
+    uint16_t n_of_kbs; /* how many KeyBinding structs are stored below .kbs? */
     uint16_t select; /* linear list index of keybinding selected for editing */
     uint8_t edit;    /* 1 if currently editing a keybinding, else 0 */
 };
 
 
 
-/* Return command bound to keycode; NULL on failure. */
-extern struct Command * get_command_to_keycode(struct KeyBinding * kb_p,
+/* Return command bound to "keycode" in "kbdb"; NULL if none found. */
+extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb,
                                                uint16_t keycode);
 
 /* Return human-readable name (of maximum 9 chars) for "keycode" as matched by
@@ -42,9 +42,6 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd);
 extern void read_keybindings_from_file(char * line, uint32_t linemax,
                                        FILE * file, struct KeyBindingDB * kbd);
 
-/* Free keybinding chain starting at "kb_start". */
-extern void free_keybindings(struct KeyBinding * kb_start);
-
 /* Mark keybinding in KeybindingDB (char_selected_kb_db()-) selected by "kb_c"
  * as being edited, get user input to modify it, then unmark it again. Ensure
  * there are max. three digits in the ASCII string of the kecode read from user.
index fcb53ecf1e6f4423c89ebeeb64cbe6a74578c568..9d7539edec9c2f1a895cb2677685301d04d3fa28 100644 (file)
@@ -14,7 +14,7 @@
 #include "../common/rexit.h" /* exit_err() */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "cleanup.h" /* set_cleanup_flag() */
-#include "keybindings.h" /* free_keybindings(), read_keybindings_from_file(),
+#include "keybindings.h" /* read_keybindings_from_file(),
                           * write_keybindings_to_file()
                           */
 #include "map.h" /* map_center() */
@@ -79,7 +79,7 @@ extern void load_interface_conf()
     read_keybindings_from_file(line, linemax, file, &world.kb_winkeys);
     char active_tmp;
     char * order_tmp;
-    read_order_wins_visible_active(line, linemax, file, &order_tmp, &active_tmp);
+    read_order_wins_visible_active(line, linemax, file, &order_tmp,&active_tmp);
     while (read_winconf_from_file(line, linemax, file));
     try_fclose(file, f_name);
 
@@ -110,9 +110,12 @@ extern void load_interface_conf()
 
 extern void unload_interface_conf()
 {
-    free_keybindings(world.kb_global.kbs);
-    free_keybindings(world.kb_wingeom.kbs);
-    free_keybindings(world.kb_winkeys.kbs);
+    free(world.kb_global.kbs);
+    world.kb_global.kbs = NULL;
+    free(world.kb_wingeom.kbs);
+    world.kb_wingeom.kbs = NULL;
+    free(world.kb_winkeys.kbs);
+    world.kb_winkeys.kbs = NULL;
     while ('\0' != world.winDB.active)
     {
         toggle_window(world.winDB.active);
index 674e6ad67a00f149dfa06fa20c778ebb3f414697..763178bf596465660b1f2ea4fa084504e7a12092 100644 (file)
@@ -23,7 +23,7 @@
                         * draw_win_keybindings_winconf_geometry(),
                         * draw_win_keybindings_global()
                         */
-#include "keybindings.h" /* free_keybindings(), write_keybidings_to_file(),
+#include "keybindings.h" /* write_keybidings_to_file(),
                           * read_keybindings_from_file()
                           */
 #include "misc.h" /* array_append() */
@@ -739,7 +739,8 @@ extern void free_winDB()
     {
         struct Win * wc = get_win_by_id(id);
         free(wc->title);
-        free_keybindings(wc->kb.kbs);
+        free(wc->kb.kbs);
+        wc->kb.kbs = NULL;
     }
     free(world.winDB.ids);  /* NULL this too since add_win_to_winDB() checks  */
     world.winDB.ids = NULL; /* for it to detect its first post-DB-purge round.*/