diff options
| author | frosty <gabriel@bwaaa.monster> | 2026-08-08 13:25:16 -0400 |
|---|---|---|
| committer | frosty <gabriel@bwaaa.monster> | 2026-08-08 13:25:16 -0400 |
| commit | f20d8f711588a1918a6d75b99b0e11d745ca8395 (patch) | |
| tree | 45a2bf0db4ff0afd577425929fe1ee9e06891d51 /src/Utility | |
| parent | d93fead0aeaed1b7860fe132476c81c1845ce756 (diff) | |
| download | omnisearch-f20d8f711588a1918a6d75b99b0e11d745ca8395.tar.gz | |
refactor: add capacity-aware template string matrices
Diffstat (limited to 'src/Utility')
| -rw-r--r-- | src/Utility/Utility.c | 136 | ||||
| -rw-r--r-- | src/Utility/Utility.h | 15 |
2 files changed, 126 insertions, 25 deletions
diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c index 9c05434..97a8d15 100644 --- a/src/Utility/Utility.c +++ b/src/Utility/Utility.c @@ -263,6 +263,67 @@ void free_string_matrix(char ***matrix, int *inner_counts, int row_count) { free(inner_counts); } +void string_matrix_init(StringMatrix *matrix) { + if (matrix) + *matrix = (StringMatrix){0}; +} + +int string_matrix_append(StringMatrix *matrix, const char *const *values, + int field_count) { + if (!matrix || !values || field_count <= 0) + return -1; + + char **row = calloc((size_t)field_count, sizeof(*row)); + if (!row) + return -1; + + for (int i = 0; i < field_count; i++) { + row[i] = strdup(values[i] ? values[i] : ""); + if (!row[i]) { + for (int j = 0; j < i; j++) + free(row[j]); + free(row); + return -1; + } + } + + if (matrix->count == matrix->capacity) { + int new_capacity = matrix->capacity ? matrix->capacity * 2 : 8; + char ***new_rows = malloc(sizeof(*new_rows) * (size_t)new_capacity); + int *new_counts = malloc(sizeof(*new_counts) * (size_t)new_capacity); + if (!new_rows || !new_counts) { + free(new_rows); + free(new_counts); + for (int i = 0; i < field_count; i++) + free(row[i]); + free(row); + return -1; + } + if (matrix->count > 0) { + memcpy(new_rows, matrix->rows, sizeof(*new_rows) * matrix->count); + memcpy(new_counts, matrix->field_counts, + sizeof(*new_counts) * matrix->count); + } + free(matrix->rows); + free(matrix->field_counts); + matrix->rows = new_rows; + matrix->field_counts = new_counts; + matrix->capacity = new_capacity; + } + + matrix->rows[matrix->count] = row; + matrix->field_counts[matrix->count] = field_count; + matrix->count++; + return 0; +} + +void string_matrix_free(StringMatrix *matrix) { + if (!matrix) + return; + free_string_matrix(matrix->rows, matrix->field_counts, matrix->count); + *matrix = (StringMatrix){0}; +} + int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count) { @@ -273,37 +334,62 @@ int add_link_to_collection(const char *href, const char *label, int build_pagination(int page, char *(*href_builder)(int page, void *data), void *data, char ****out_matrix, int **out_inner_counts) { - enum { PAGER_WINDOW_SIZE = 5 }; + if (!out_matrix || !out_inner_counts) + return 0; - *out_matrix = NULL; - *out_inner_counts = NULL; - int count = 0; + StringMatrix matrix; + if (string_matrix_build_pagination(page, href_builder, data, &matrix) != 0) { + *out_matrix = NULL; + *out_inner_counts = NULL; + return 0; + } + + *out_matrix = matrix.rows; + *out_inner_counts = matrix.field_counts; + return matrix.count; +} +int string_matrix_build_pagination(int page, + char *(*href_builder)(int page, void *data), + void *data, StringMatrix *out_matrix) { + enum { PAGER_WINDOW_SIZE = 5 }; + if (!out_matrix || !href_builder) + return -1; + + string_matrix_init(out_matrix); int pager_start = page <= 3 ? 1 : page - 2; int pager_end = pager_start + PAGER_WINDOW_SIZE - 1; - if (page > 1) { - char *href = href_builder(page - 1, data); - count = add_link_to_collection(href, "←", "pagination-btn prev", out_matrix, - out_inner_counts, count); - free(href); - } + for (int i = page > 1 ? pager_start - 1 : pager_start; i <= pager_end + 1; + i++) { + const char *label = NULL; + const char *class_name = "pagination-btn"; + char page_label[16]; + int target_page = i; - for (int i = pager_start; i <= pager_end; i++) { - char label[16]; - snprintf(label, sizeof(label), "%d", i); - char *href = href_builder(i, data); - count = add_link_to_collection( - href, label, - i == page ? "pagination-btn pagination-current" : "pagination-btn", - out_matrix, out_inner_counts, count); + if (page > 1 && i == pager_start - 1) { + label = "←"; + class_name = "pagination-btn prev"; + target_page = page - 1; + } else if (i == pager_end + 1) { + label = "→"; + class_name = "pagination-btn next"; + target_page = page + 1; + } else { + snprintf(page_label, sizeof(page_label), "%d", i); + label = page_label; + if (i == page) + class_name = "pagination-btn pagination-current"; + } + + char *href = href_builder(target_page, data); + const char *values[LINK_FIELD_COUNT] = {href, label, class_name}; + int result = string_matrix_append(out_matrix, values, LINK_FIELD_COUNT); free(href); + if (result != 0) { + string_matrix_free(out_matrix); + return -1; + } } - - char *href = href_builder(page + 1, data); - count = add_link_to_collection(href, "→", "pagination-btn next", out_matrix, - out_inner_counts, count); - free(href); - - return count; + return 0; } diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h index 9fca8b6..663f2c4 100644 --- a/src/Utility/Utility.h +++ b/src/Utility/Utility.h @@ -13,6 +13,13 @@ #define LINK_FIELD_COUNT 3 +typedef struct { + char ***rows; + int *field_counts; + int count; + int capacity; +} StringMatrix; + int hex_to_int(char c); char *get_theme(const char *default_theme); void init_themes(const char *static_path); @@ -28,11 +35,19 @@ int append_string_row(char ****matrix, int **inner_counts, int row_count, const char *const *values, int field_count); void free_string_matrix(char ***matrix, int *inner_counts, int row_count); +void string_matrix_init(StringMatrix *matrix); +int string_matrix_append(StringMatrix *matrix, const char *const *values, + int field_count); +void string_matrix_free(StringMatrix *matrix); + int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count); int build_pagination(int page, char *(*href_builder)(int page, void *data), void *data, char ****out_matrix, int **out_inner_counts); +int string_matrix_build_pagination(int page, + char *(*href_builder)(int page, void *data), + void *data, StringMatrix *out_matrix); #endif |
