summaryrefslogtreecommitdiffstats
path: root/core/table.h
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-03-10 21:37:05 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-04-12 18:19:07 +0300
commita6f65d744f4fd0952df49f5cba0693fc4a73d167 (patch)
tree73ea03442355556aa8dd05d0686000ba41b02430 /core/table.h
parentefb770c979a5367a6f9616cc15ed5575eb7cd51f (diff)
downloadsubsurface-a6f65d744f4fd0952df49f5cba0693fc4a73d167.tar.gz
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 <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/table.h')
-rw-r--r--core/table.h93
1 files changed, 93 insertions, 0 deletions
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