From: Pietro Cerutti Date: Tue, 6 Aug 2019 15:28:01 +0000 (+0000) Subject: Import typed vector implementation [1], convert alias menu X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bdaac1037c9f0853cfa68454bdc4f7b0ae674e8;p=neomutt Import typed vector implementation [1], convert alias menu [1] https://github.com/rxi/vec --- diff --git a/Makefile.autosetup b/Makefile.autosetup index 4b866b374..057e6b0bf 100644 --- a/Makefile.autosetup +++ b/Makefile.autosetup @@ -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) diff --git a/addrbook.c b/addrbook.c index 2a69edba4..aca4152ec 100644 --- a/addrbook.c +++ b/addrbook.c @@ -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 index 000000000..500d997cf --- /dev/null +++ b/rxi-vec/README @@ -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 index 000000000..399104e90 --- /dev/null +++ b/rxi-vec/vec.c @@ -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 index 000000000..2430611e3 --- /dev/null +++ b/rxi-vec/vec.h @@ -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 +#include + +#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