From a6f65d744f4fd0952df49f5cba0693fc4a73d167 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 10 Mar 2019 21:37:05 +0100 Subject: [PATCH] Cleanup: move table-macros into own header dive- and trip-table functions are generated in dive.c by macros. Move this macros to a new "core/table.h" header file. Thus, these functions can be used for other tables (e.g. dive site) and the trip function can be moved to a separate translation unit (divelist.c being quite large already). Signed-off-by: Berthold Stoeger --- core/divelist.c | 86 +-------------------------------------------- core/table.h | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 85 deletions(-) create mode 100644 core/table.h diff --git a/core/divelist.c b/core/divelist.c index 37433536a..635fa0b6e 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -18,6 +18,7 @@ #include "planner.h" #include "qthelper.h" #include "git-access.h" +#include "table.h" static bool dive_list_changed = false; @@ -820,109 +821,24 @@ static int comp_trips(const struct dive_trip *a, const struct dive_trip *b) return comp_dives(a->dives.dives[0], b->dives.dives[0]); } -#define MAKE_GROW_TABLE(table_type, item_type, array_name) \ - item_type *grow_##table_type(struct table_type *table) \ - { \ - int nr = table->nr, allocated = table->allocated; \ - item_type *items = table->array_name; \ - \ - if (nr >= allocated) { \ - allocated = (nr + 32) * 3 / 2; \ - items = realloc(items, allocated * sizeof(item_type)); \ - if (!items) \ - exit(1); \ - table->array_name = items; \ - table->allocated = allocated; \ - } \ - return items; \ - } - MAKE_GROW_TABLE(dive_table, struct dive *, dives) static MAKE_GROW_TABLE(trip_table, struct dive_trip *, trips) -/* get the index where we want to insert an object so that everything stays - * ordered according to a comparison function() */ -#define MAKE_GET_INSERTION_INDEX(table_type, item_type, array_name, fun) \ - int table_type##_get_insertion_index(struct table_type *table, item_type item) \ - { \ - /* we might want to use binary search here */ \ - for (int i = 0; i < table->nr; i++) { \ - if (fun(item, table->array_name[i])) \ - return i; \ - } \ - return table->nr; \ - } - MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than) static MAKE_GET_INSERTION_INDEX(trip_table, struct dive_trip *, trips, trip_less_than) -/* add object at the given index to a table. */ -#define MAKE_ADD_TO(table_type, item_type, array_name) \ - void add_to_##table_type(struct table_type *table, int idx, item_type item) \ - { \ - int i; \ - grow_##table_type(table); \ - table->nr++; \ - \ - for (i = idx; i < table->nr; i++) { \ - item_type tmp = table->array_name[i]; \ - table->array_name[i] = item; \ - item = tmp; \ - } \ - } - MAKE_ADD_TO(dive_table, struct dive *, dives) static MAKE_ADD_TO(trip_table, struct dive_trip *, trips) -#define MAKE_REMOVE_FROM(table_type, array_name) \ - void remove_from_##table_type(struct table_type *table, int idx) \ - { \ - int i; \ - for (i = idx; i < table->nr - 1; i++) \ - table->array_name[i] = table->array_name[i + 1]; \ - table->array_name[--table->nr] = NULL; \ - } - static MAKE_REMOVE_FROM(dive_table, dives) static MAKE_REMOVE_FROM(trip_table, trips) -#define MAKE_GET_IDX(table_type, item_type, array_name) \ - int get_idx_in_##table_type(const struct table_type *table, const item_type item) \ - { \ - for (int i = 0; i < table->nr; ++i) { \ - if (table->array_name[i] == item) \ - return i; \ - } \ - return -1; \ - } - static MAKE_GET_IDX(dive_table, struct dive *, dives) static MAKE_GET_IDX(trip_table, struct dive_trip *, trips) -#define MAKE_SORT(table_type, item_type, array_name, fun) \ - static int sortfn_##table_type(const void *_a, const void *_b) \ - { \ - const item_type a = (const item_type)*(const void **)_a; \ - const item_type b = (const item_type)*(const void **)_b; \ - return fun(a, b); \ - } \ - \ - void sort_##table_type(struct table_type *table) \ - { \ - qsort(table->array_name, table->nr, sizeof(item_type), sortfn_##table_type); \ - } - MAKE_SORT(dive_table, struct dive *, dives, comp_dives) MAKE_SORT(trip_table, struct dive_trip *, trips, comp_trips) -#define MAKE_REMOVE(table_type, item_type, item_name) \ - void remove_##item_name(const item_type item, struct table_type *table) \ - { \ - int idx = get_idx_in_##table_type(table, item); \ - if (idx >= 0) \ - remove_from_##table_type(table, idx); \ - } - MAKE_REMOVE(dive_table, struct dive *, dive) MAKE_REMOVE(trip_table, struct dive_trip *, trip) diff --git a/core/table.h b/core/table.h new file mode 100644 index 000000000..76074fe47 --- /dev/null +++ b/core/table.h @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* This header defines a number of macros that generate table-manipulation functions. + * There is no design behind these macros - the functions were take as-is and transformed + * into macros. Thus, this whole header could do with some redesign. */ +#ifndef CORE_TABLE_H +#define CORE_TABLE_H + +#define MAKE_GROW_TABLE(table_type, item_type, array_name) \ + item_type *grow_##table_type(struct table_type *table) \ + { \ + int nr = table->nr, allocated = table->allocated; \ + item_type *items = table->array_name; \ + \ + if (nr >= allocated) { \ + allocated = (nr + 32) * 3 / 2; \ + items = realloc(items, allocated * sizeof(item_type)); \ + if (!items) \ + exit(1); \ + table->array_name = items; \ + table->allocated = allocated; \ + } \ + return items; \ + } + +/* get the index where we want to insert an object so that everything stays + * ordered according to a comparison function() */ +#define MAKE_GET_INSERTION_INDEX(table_type, item_type, array_name, fun) \ + int table_type##_get_insertion_index(struct table_type *table, item_type item) \ + { \ + /* we might want to use binary search here */ \ + for (int i = 0; i < table->nr; i++) { \ + if (fun(item, table->array_name[i])) \ + return i; \ + } \ + return table->nr; \ + } + +/* add object at the given index to a table. */ +#define MAKE_ADD_TO(table_type, item_type, array_name) \ + void add_to_##table_type(struct table_type *table, int idx, item_type item) \ + { \ + int i; \ + grow_##table_type(table); \ + table->nr++; \ + \ + for (i = idx; i < table->nr; i++) { \ + item_type tmp = table->array_name[i]; \ + table->array_name[i] = item; \ + item = tmp; \ + } \ + } + +#define MAKE_REMOVE_FROM(table_type, array_name) \ + void remove_from_##table_type(struct table_type *table, int idx) \ + { \ + int i; \ + for (i = idx; i < table->nr - 1; i++) \ + table->array_name[i] = table->array_name[i + 1]; \ + table->array_name[--table->nr] = NULL; \ + } + +#define MAKE_GET_IDX(table_type, item_type, array_name) \ + int get_idx_in_##table_type(const struct table_type *table, const item_type item) \ + { \ + for (int i = 0; i < table->nr; ++i) { \ + if (table->array_name[i] == item) \ + return i; \ + } \ + return -1; \ + } + +#define MAKE_SORT(table_type, item_type, array_name, fun) \ + static int sortfn_##table_type(const void *_a, const void *_b) \ + { \ + const item_type a = (const item_type)*(const void **)_a; \ + const item_type b = (const item_type)*(const void **)_b; \ + return fun(a, b); \ + } \ + \ + void sort_##table_type(struct table_type *table) \ + { \ + qsort(table->array_name, table->nr, sizeof(item_type), sortfn_##table_type); \ + } + +#define MAKE_REMOVE(table_type, item_type, item_name) \ + void remove_##item_name(const item_type item, struct table_type *table) \ + { \ + int idx = get_idx_in_##table_type(table, item); \ + if (idx >= 0) \ + remove_from_##table_type(table, idx); \ + } + +#endif