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)
#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
{
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);
}
{
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;
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;
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);
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))
{
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);
}
--- /dev/null
+From https://github.com/rxi/vec
--- /dev/null
+/**
+ * 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++;
+ }
+}
+
--- /dev/null
+/**
+ * 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