]> granicus.if.org Git - neomutt/commitdiff
Import typed vector implementation [1], convert alias menu
authorPietro Cerutti <gahr@gahr.ch>
Tue, 6 Aug 2019 15:28:01 +0000 (15:28 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 21 Oct 2019 18:58:45 +0000 (19:58 +0100)
[1] https://github.com/rxi/vec

Makefile.autosetup
addrbook.c
rxi-vec/README [new file with mode: 0644]
rxi-vec/vec.c [new file with mode: 0644]
rxi-vec/vec.h [new file with mode: 0644]

index 4b866b374df074899ed2bb48a2d213d75dec7ce4..057e6b0bfb5879eddfedf9314a823eb91eb5a6a8 100644 (file)
@@ -282,7 +282,7 @@ LIBMUTTOBJS=        mutt/base64.o mutt/buffer.o mutt/charset.o mutt/date.o \
                mutt/envlist.o mutt/exit.o mutt/file.o mutt/hash.o mutt/history.o \
                mutt/list.o mutt/logging.o mutt/mapping.o mutt/mbyte.o mutt/md5.o \
                mutt/memory.o mutt/notify.o mutt/path.o mutt/pool.o mutt/regex.o \
-               mutt/signal.o mutt/slist.o mutt/string.o
+               mutt/signal.o mutt/slist.o mutt/string.o rxi-vec/vec.o
 CLEANFILES+=   $(LIBMUTT) $(LIBMUTTOBJS)
 MUTTLIBS+=     $(LIBMUTT)
 ALLOBJS+=      $(LIBMUTTOBJS)
index 2a69edba41b41885ce6ff3290ef0e8b12887c64e..aca4152ececeecd8145d8243f23d393f0a4ef969 100644 (file)
@@ -44,6 +44,9 @@
 #include "mutt_window.h"
 #include "muttlib.h"
 #include "opcodes.h"
+#include "rxi-vec/vec.h"
+
+typedef vec_t(struct Alias*) AliasVector;
 
 /* These Config Variables are only used in addrbook.c */
 char *C_AliasFormat; ///< Config: printf-like format string for the alias menu
@@ -111,7 +114,7 @@ static void alias_make_entry(char *buf, size_t buflen, struct Menu *menu, int li
 {
   mutt_expando_format(buf, buflen, 0, menu->indexwin->cols,
                       NONULL(C_AliasFormat), alias_format_str,
-                      (unsigned long) ((struct Alias **) menu->data)[line],
+                      (unsigned long) (((AliasVector *) menu->data)->data[line]),
                       MUTT_FORMAT_ARROWCURSOR);
 }
 
@@ -194,7 +197,7 @@ void mutt_alias_menu(char *buf, size_t buflen, struct AliasList *aliases)
 {
   struct Alias *a = NULL, *last = NULL;
   struct Menu *menu = NULL;
-  struct Alias **alias_table = NULL;
+  AliasVector alias_table;
   int t = -1;
   int i;
   bool done = false;
@@ -215,6 +218,8 @@ void mutt_alias_menu(char *buf, size_t buflen, struct AliasList *aliases)
   menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ALIAS, AliasHelp);
   mutt_menu_push_current(menu);
 
+  vec_init(&alias_table);
+
 new_aliases:
   omax = menu->max;
 
@@ -226,29 +231,29 @@ new_aliases:
     menu->max++;
   }
 
-  mutt_mem_realloc(&alias_table, menu->max * sizeof(struct Alias *));
-  menu->data = alias_table;
-  if (!alias_table)
+  if (vec_reserve(&alias_table, menu->max) == -1)
     return;
 
+  menu->data = &alias_table;
+
   if (last)
     a = TAILQ_NEXT(last, entries);
 
   i = omax;
   TAILQ_FOREACH_FROM(a, aliases, entries)
   {
-    alias_table[i] = a;
+    vec_insert(&alias_table, i, a);
     i++;
   }
 
   if ((C_SortAlias & SORT_MASK) != SORT_ORDER)
   {
-    qsort(alias_table, menu->max, sizeof(struct Alias *),
+    vec_sort(&alias_table, 
           ((C_SortAlias & SORT_MASK) == SORT_ADDRESS) ? alias_sort_address : alias_sort_alias);
   }
 
   for (i = 0; i < menu->max; i++)
-    alias_table[i]->num = i;
+    alias_table.data[i]->num = i;
 
   last = TAILQ_LAST(aliases, AliasList);
 
@@ -268,13 +273,13 @@ new_aliases:
         if (menu->tagprefix)
         {
           for (i = 0; i < menu->max; i++)
-            if (alias_table[i]->tagged)
-              alias_table[i]->del = (op == OP_DELETE);
+            if (alias_table.data[i]->tagged)
+              alias_table.data[i]->del = (op == OP_DELETE);
           menu->redraw |= REDRAW_INDEX;
         }
         else
         {
-          alias_table[menu->current]->del = (op == OP_DELETE);
+          alias_table.data[menu->current]->del = (op == OP_DELETE);
           menu->redraw |= REDRAW_CURRENT;
           if (C_Resolve && (menu->current < menu->max - 1))
           {
@@ -295,19 +300,19 @@ new_aliases:
 
   for (i = 0; i < menu->max; i++)
   {
-    if (alias_table[i]->tagged)
+    if (alias_table.data[i]->tagged)
     {
-      mutt_addrlist_write(buf, buflen, &alias_table[i]->addr, true);
+      mutt_addrlist_write(buf, buflen, &alias_table.data[i]->addr, true);
       t = -1;
     }
   }
 
   if (t != -1)
   {
-    mutt_addrlist_write(buf, buflen, &alias_table[t]->addr, true);
+    mutt_addrlist_write(buf, buflen, &alias_table.data[t]->addr, true);
   }
 
   mutt_menu_pop_current(menu);
   mutt_menu_free(&menu);
-  FREE(&alias_table);
+  vec_deinit(&alias_table);
 }
diff --git a/rxi-vec/README b/rxi-vec/README
new file mode 100644 (file)
index 0000000..500d997
--- /dev/null
@@ -0,0 +1 @@
+From https://github.com/rxi/vec
diff --git a/rxi-vec/vec.c b/rxi-vec/vec.c
new file mode 100644 (file)
index 0000000..399104e
--- /dev/null
@@ -0,0 +1,114 @@
+/** 
+ * Copyright (c) 2014 rxi
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include "vec.h"
+
+
+int vec_expand_(char **data, int *length, int *capacity, int memsz) {
+  if (*length + 1 > *capacity) {
+    void *ptr;
+    int n = (*capacity == 0) ? 1 : *capacity << 1;
+    ptr = realloc(*data, n * memsz);
+    if (ptr == NULL) return -1;
+    *data = ptr;
+    *capacity = n;
+  }
+  return 0;
+}
+
+
+int vec_reserve_(char **data, int *length, int *capacity, int memsz, int n) {
+  (void) length;
+  if (n > *capacity) {
+    void *ptr = realloc(*data, n * memsz);
+    if (ptr == NULL) return -1;
+    *data = ptr;
+    *capacity = n;
+  }
+  return 0;
+}
+
+
+int vec_reserve_po2_(
+  char **data, int *length, int *capacity, int memsz, int n
+) {
+  int n2 = 1;
+  if (n == 0) return 0;
+  while (n2 < n) n2 <<= 1;
+  return vec_reserve_(data, length, capacity, memsz, n2);
+}
+
+
+int vec_compact_(char **data, int *length, int *capacity, int memsz) {
+  if (*length == 0) {
+    free(*data);
+    *data = NULL;
+    *capacity = 0;
+    return 0;
+  } else {
+    void *ptr;
+    int n = *length;
+    ptr = realloc(*data, n * memsz);
+    if (ptr == NULL) return -1;
+    *capacity = n;
+    *data = ptr;
+  }
+  return 0;
+}
+
+
+int vec_insert_(char **data, int *length, int *capacity, int memsz,
+                 int idx
+) {
+  int err = vec_expand_(data, length, capacity, memsz);
+  if (err) return err;
+  memmove(*data + (idx + 1) * memsz,
+          *data + idx * memsz,
+          (*length - idx) * memsz);
+  return 0;
+}
+
+
+void vec_splice_(char **data, int *length, int *capacity, int memsz,
+                 int start, int count
+) {
+  (void) capacity;
+  memmove(*data + start * memsz,
+          *data + (start + count) * memsz,
+          (*length - start - count) * memsz);
+}
+
+
+void vec_swapsplice_(char **data, int *length, int *capacity, int memsz,
+                     int start, int count
+) {
+  (void) capacity;
+  memmove(*data + start * memsz,
+          *data + (*length - count) * memsz,
+          count * memsz);
+}
+
+
+void vec_swap_(char **data, int *length, int *capacity, int memsz,
+               int idx1, int idx2 
+) {
+  unsigned char *a, *b, tmp;
+  int count;
+  (void) length;
+  (void) capacity;
+  if (idx1 == idx2) return;
+  a = (unsigned char*) *data + idx1 * memsz;
+  b = (unsigned char*) *data + idx2 * memsz;
+  count = memsz;
+  while (count--) {
+    tmp = *a;
+    *a = *b;
+    *b = tmp;
+    a++, b++;
+  }
+}
+
diff --git a/rxi-vec/vec.h b/rxi-vec/vec.h
new file mode 100644 (file)
index 0000000..2430611
--- /dev/null
@@ -0,0 +1,181 @@
+/** 
+ * Copyright (c) 2014 rxi
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MIT license. See LICENSE for details.
+ */
+
+#ifndef VEC_H
+#define VEC_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#define VEC_VERSION "0.2.1"
+
+
+#define vec_unpack_(v)\
+  (char**)&(v)->data, &(v)->length, &(v)->capacity, sizeof(*(v)->data)
+
+
+#define vec_t(T)\
+  struct { T *data; int length, capacity; }
+
+
+#define vec_init(v)\
+  memset((v), 0, sizeof(*(v)))
+
+
+#define vec_deinit(v)\
+  ( free((v)->data),\
+    vec_init(v) ) 
+
+
+#define vec_push(v, val)\
+  ( vec_expand_(vec_unpack_(v)) ? -1 :\
+    ((v)->data[(v)->length++] = (val), 0), 0 )
+
+
+#define vec_pop(v)\
+  (v)->data[--(v)->length]
+
+
+#define vec_splice(v, start, count)\
+  ( vec_splice_(vec_unpack_(v), start, count),\
+    (v)->length -= (count) )
+
+
+#define vec_swapsplice(v, start, count)\
+  ( vec_swapsplice_(vec_unpack_(v), start, count),\
+    (v)->length -= (count) )
+
+
+#define vec_insert(v, idx, val)\
+  ( vec_insert_(vec_unpack_(v), idx) ? -1 :\
+    ((v)->data[idx] = (val), 0), (v)->length++, 0 )
+    
+
+#define vec_sort(v, fn)\
+  qsort((v)->data, (v)->length, sizeof(*(v)->data), fn)
+
+
+#define vec_swap(v, idx1, idx2)\
+  vec_swap_(vec_unpack_(v), idx1, idx2)
+
+
+#define vec_truncate(v, len)\
+  ((v)->length = (len) < (v)->length ? (len) : (v)->length)
+
+
+#define vec_clear(v)\
+  ((v)->length = 0)
+
+
+#define vec_first(v)\
+  (v)->data[0]
+
+
+#define vec_last(v)\
+  (v)->data[(v)->length - 1]
+
+
+#define vec_reserve(v, n)\
+  vec_reserve_(vec_unpack_(v), n)
+
+#define vec_compact(v)\
+  vec_compact_(vec_unpack_(v))
+
+
+#define vec_pusharr(v, arr, count)\
+  do {\
+    int i__, n__ = (count);\
+    if (vec_reserve_po2_(vec_unpack_(v), (v)->length + n__) != 0) break;\
+    for (i__ = 0; i__ < n__; i__++) {\
+      (v)->data[(v)->length++] = (arr)[i__];\
+    }\
+  } while (0)
+
+
+#define vec_extend(v, v2)\
+  vec_pusharr((v), (v2)->data, (v2)->length)
+
+
+#define vec_find(v, val, idx)\
+  do {\
+    for ((idx) = 0; (idx) < (v)->length; (idx)++) {\
+      if ((v)->data[(idx)] == (val)) break;\
+    }\
+    if ((idx) == (v)->length) (idx) = -1;\
+  } while (0)
+
+
+#define vec_remove(v, val)\
+  do {\
+    int idx__;\
+    vec_find(v, val, idx__);\
+    if (idx__ != -1) vec_splice(v, idx__, 1);\
+  } while (0)
+
+
+#define vec_reverse(v)\
+  do {\
+    int i__ = (v)->length / 2;\
+    while (i__--) {\
+      vec_swap((v), i__, (v)->length - (i__ + 1));\
+    }\
+  } while (0)
+
+
+#define vec_foreach(v, var, iter)\
+  if  ( (v)->length > 0 )\
+  for ( (iter) = 0;\
+        (iter) < (v)->length && (((var) = (v)->data[(iter)]), 1);\
+        ++(iter))
+
+
+#define vec_foreach_rev(v, var, iter)\
+  if  ( (v)->length > 0 )\
+  for ( (iter) = (v)->length - 1;\
+        (iter) >= 0 && (((var) = (v)->data[(iter)]), 1);\
+        --(iter))
+
+
+#define vec_foreach_ptr(v, var, iter)\
+  if  ( (v)->length > 0 )\
+  for ( (iter) = 0;\
+        (iter) < (v)->length && (((var) = &(v)->data[(iter)]), 1);\
+        ++(iter))
+
+
+#define vec_foreach_ptr_rev(v, var, iter)\
+  if  ( (v)->length > 0 )\
+  for ( (iter) = (v)->length - 1;\
+        (iter) >= 0 && (((var) = &(v)->data[(iter)]), 1);\
+        --(iter))
+
+
+
+int vec_expand_(char **data, int *length, int *capacity, int memsz);
+int vec_reserve_(char **data, int *length, int *capacity, int memsz, int n);
+int vec_reserve_po2_(char **data, int *length, int *capacity, int memsz,
+                     int n);
+int vec_compact_(char **data, int *length, int *capacity, int memsz);
+int vec_insert_(char **data, int *length, int *capacity, int memsz,
+                int idx);
+void vec_splice_(char **data, int *length, int *capacity, int memsz,
+                 int start, int count);
+void vec_swapsplice_(char **data, int *length, int *capacity, int memsz,
+                     int start, int count);
+void vec_swap_(char **data, int *length, int *capacity, int memsz,
+               int idx1, int idx2);
+
+
+typedef vec_t(void*) vec_void_t;
+typedef vec_t(char*) vec_str_t;
+typedef vec_t(int) vec_int_t;
+typedef vec_t(char) vec_char_t;
+typedef vec_t(float) vec_float_t;
+typedef vec_t(double) vec_double_t;
+
+#endif