diff --git a/libbdc/CMakeLists.txt b/libbdc/CMakeLists.txt index 3a0a1b2d8eceab000d421bb17aabdc60a278f7d5..0ecb214949674ba5f44d8fbb8ab7623700999306 100644 --- a/libbdc/CMakeLists.txt +++ b/libbdc/CMakeLists.txt @@ -32,7 +32,11 @@ endif () add_subdirectory(bdc_cross_platform) +add_subdirectory(bdc_hashtable) +add_subdirectory(bdc_io) +add_subdirectory(bdc_logging) add_subdirectory(bdc_memory) +add_subdirectory(bdc_strings) add_subdirectory(bdc_time) add_library(bdc STATIC "") @@ -40,6 +44,10 @@ add_library(bdc STATIC "") set_target_properties(bdc PROPERTIES LINKER_LANGUAGE C) set_property(TARGET bdc PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(bdc + bdc_hashtable + bdc_io + bdc_logging bdc_memory + bdc_strings bdc_time) diff --git a/libbdc/bdc_hashtable/CMakeLists.txt b/libbdc/bdc_hashtable/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5e11b831162c1c676de5c24a1a349ad2112d71aa --- /dev/null +++ b/libbdc/bdc_hashtable/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(bdc_hashtable STATIC bdc_hashtable.c bdc_hashtable.h) +set_property(TARGET bdc_hashtable PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(bdc_hashtable bdc_logging) + + + +add_executable(bdc_hashtable_test tests/test_bdc_hashtable.c) + + +target_link_libraries(bdc_hashtable_test bdc_strings) \ No newline at end of file diff --git a/libbdc/bdc_hashtable/bdc_hashtable.c b/libbdc/bdc_hashtable/bdc_hashtable.c new file mode 100644 index 0000000000000000000000000000000000000000..74975d3090ff32860e0bb7fa204364a6e5a7022d --- /dev/null +++ b/libbdc/bdc_hashtable/bdc_hashtable.c @@ -0,0 +1,476 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_hashtable.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "bdc_hashtable.h" +#include "bdc_logging/logging.h" +#include "bdc_memory/bdc_memory.h" + + +struct bdc_value { + union { + char *string; + int64_t int64; + double double_value; + void *pointer; + }; + enum bdc_value_type type; +}; +struct bdc_item { + char *key; + struct bdc_value *value; + struct bdc_item *next; +}; +struct bdc_hash_table { + size_t item_count; + size_t bucket_count; + size_t *items_per_bucket; + //size_t max_items_pro_bucket; + struct bdc_item **items; + +}; + + + +// FNV-1a hash, see https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash +#define OFFSET 14695981039346656037UL +#define PRIME 1099511628211UL + +#define DEBUG(...) + +// FIXME: add function to return keys + +uint64_t hash_function(const char *key) +{ + uint64_t hash = OFFSET; + while (*key != '\0') { + hash ^= (uint64_t) (unsigned char) *key; + hash *= PRIME; + key++; + } + return hash; +} + + +__attribute__((unused)) size_t hash_index(const char *key, size_t buckets) +{ + return (size_t) hash_function(key) & (buckets - 1); +} + + +size_t hash_idx_from_hash(uint64_t hash, size_t buckets) +{ + return hash & (buckets - 1); +} + + + +struct bdc_hash_table *bdc_intern_new_hash_table(size_t buckets) +{ + struct bdc_hash_table *table = calloc_or_die(1, sizeof(struct bdc_hash_table)); + table->bucket_count = buckets; + table->items = calloc_or_die(table->bucket_count, sizeof(struct bdc_item *)); + table->item_count = 0; + //table->max_items_pro_bucket = 0; + + table->items_per_bucket = calloc_or_die(table->bucket_count, sizeof(size_t)); + DEBUG("Creating hash table with %lu buckets\n", table->bucket_count) + + for (size_t i = 0; i < table->bucket_count; i++) { + table->items_per_bucket[i] = 0; + table->items[i] = NULL; + } + + return table; +} + + +__attribute__((unused)) struct bdc_hash_table *new_hash_table(void) +{ + return bdc_intern_new_hash_table(MIN_SIZE); +} + + +void destroy_value(struct bdc_value **value) +{ + if (value == NULL || *value == NULL) return; + struct bdc_value *this = *value; + if(this->type == BDC_STRING) { + log_message(LOG_DEBUG, "freeing string value '%s'", this->string); + free(this->string); + this->string = NULL; + } + log_message(LOG_DEBUG, "freeing value"); + free(this); + *value = NULL; + +} + +struct bdc_item *bdc_intern_get_entry(struct bdc_hash_table *table, const char *key, uint64_t hash) +{ + size_t hash_idx = hash_idx_from_hash(hash, table->bucket_count); + if (table->items[hash_idx] == NULL) return NULL; + + struct bdc_item *entry = table->items[hash_idx]; + + if (0 == strcmp(entry->key, key)) return entry; + + while (entry->next != NULL) { + entry = entry->next; + if (0 == strcmp(entry->key, key)) return entry; + } + + return NULL; +} + + +struct bdc_item *get_entry(struct bdc_hash_table *table, const char *key) +{ + uint64_t hash = hash_function(key); + + size_t hash_idx = hash & (table->bucket_count - 1); + if (table->items[hash_idx] == NULL) return NULL; + + struct bdc_item *entry = table->items[hash_idx]; + if (0 == strcmp(entry->key, key)) return entry; + while (entry->next != NULL) { + entry = entry->next; + if (0 == strcmp(entry->key, key)) return entry; + } + + return NULL; +} + +void destroy_item(struct bdc_item **item) +{ + if(item == NULL || *item == NULL) return; + struct bdc_item *this = *item; + destroy_value(&this->value); + free(this->key); + free(this); + *item = NULL; +} + +bool remove_key(struct bdc_hash_table *table, const char *key) +{ + if (!bdc_key_in_hash_table(table, key)) return false; + + uint64_t hash = hash_function(key); + size_t hash_idx = hash & (table->bucket_count - 1); + + struct bdc_item *target = NULL; + struct bdc_item *entry = table->items[hash_idx]; + if (0 == strcmp(entry->key, key)) { + target = entry; + table->items[hash_idx] = target->next; + table->items_per_bucket[hash_idx]--; + destroy_item(&target); + return true; + } + struct bdc_item *prev = NULL; + while (entry->next != NULL) { + prev = entry, + entry = entry->next; + if (0 == strcmp(entry->key, key)) { + target = entry; + prev->next = target->next; + table->items_per_bucket[hash_idx]--; + free(entry); + return true; + } + } + return false; +} + + +__attribute__((unused)) bool bdc_key_in_hash_table(struct bdc_hash_table *table, const char *key) +{ + return get_entry(table, key) != NULL; + +} + + +struct bdc_value *bdc_get_value_from_key(struct bdc_hash_table *table, const char *key) +{ + struct bdc_item *entry = get_entry(table, key); + if (entry) { + return entry->value; + } else { + return NULL; + } +} + + +struct bdc_item *new_entry(const char *key, struct bdc_value *value) +{ + struct bdc_item *entry = calloc_or_die(1, sizeof(struct bdc_item)); + + + entry->value = value; + log_message(LOG_DEBUG, "duplicating key '%s'", key); + entry->key = strdup(key); + entry->next = NULL; + + return entry; +} + + +void print_key_val(struct bdc_item *entry) +{ + struct bdc_value *value = entry->value; + switch (value->type) { + + case BDC_STRING: + printf("\t\t%s -> '%s'\n", entry->key, value->string); + break; + case BDC_INT64: + printf("\t\t%s -> %ld\n", entry->key, value->int64); + break; + case BDC_DOUBLE: + printf("\t\t%s -> %f\n", entry->key, value->double_value); + break; + case BDC_CUSTOM: + printf("\t\t%s -> %p\n", entry->key, value->pointer); + break; + } + +} + + +__attribute__((unused)) void print_hash_table(const struct bdc_hash_table *table) +{ + printf("\n"); + printf("Hash table: %lu buckets with %lu items\n", table->bucket_count, + table->item_count); + for (size_t i = 0; i < table->bucket_count; i++) { + if (table->items[i] == NULL) continue; + printf("\tentry %lu: %lu entries\n", i, table->items_per_bucket[i]); + size_t count = 1; + struct bdc_item *entry = table->items[i]; + print_key_val(entry); + while (entry->next != NULL) { + entry = entry->next; + count++; + print_key_val(entry); + } + + if (count != table->items_per_bucket[i]) { + printf("Error: mismatch between expected (%lu) and found entries (%lu)\n", + table->items_per_bucket[i], i); + } + } + printf("\n"); +} + + + + + +struct bdc_item *bdc_intern_add_entry(struct bdc_hash_table *table, struct bdc_item *entry, uint64_t hash) +{ + size_t hash_idx = hash_idx_from_hash(hash, table->bucket_count); + entry->next = table->items[hash_idx]; + table->items[hash_idx] = entry; + table->items_per_bucket[hash_idx] += 1; + table->item_count += 1; + + return entry; +} + + +void rehash_table(struct bdc_hash_table *table) +{ + log_message(LOG_INFO, "%s: rehashing!", __func__); + struct bdc_hash_table *tmp = bdc_intern_new_hash_table(table->bucket_count * 2); + + for (size_t i = 0; i < table->bucket_count; i++) { + if (table->items[i] == NULL) continue; + struct bdc_item *entry = table->items[i]; + struct bdc_item *next = entry->next; + uint64_t hash = hash_function(entry->key); + bdc_intern_add_entry(tmp, entry, hash); + + while (next) { + entry = next; + next = entry->next; + hash = hash_function(entry->key); + bdc_intern_add_entry(tmp, entry, hash); + } + + } + + free(table->items); + free(table->items_per_bucket); + table->items = tmp->items; + table->items_per_bucket = tmp->items_per_bucket; + table->bucket_count = tmp->bucket_count; + + free(tmp); + tmp = NULL; + +} + + +struct bdc_item *bdc_ht_add_string(struct bdc_hash_table *table, const char *key, const char *value) +{ + struct bdc_value *val = calloc(1, sizeof(struct bdc_value)); + log_message(LOG_DEBUG, "duplicating value '%s", value); + val->string = strdup(value); + val->type = BDC_STRING; + return intern_bdc_add_entry(table, key, val); +} + + +struct bdc_item *bdc_ht_add_custom(struct bdc_hash_table *table, const char *key, void *value) +{ + struct bdc_value *val = calloc(1, sizeof(struct bdc_value)); + val->pointer = value; + val->type = BDC_CUSTOM; + return intern_bdc_add_entry(table, key, val); +} + + +struct bdc_item *bdc_ht_add_int64(struct bdc_hash_table *table, const char *key, int64_t value) +{ + struct bdc_value *val = calloc(1, sizeof(struct bdc_value)); + val->int64 = value; + val->type = BDC_INT64; + return intern_bdc_add_entry(table, key, val); +} + + +struct bdc_item *bdc_ht_add_double(struct bdc_hash_table *table, const char *key, double value) +{ + struct bdc_value *val = calloc(1, sizeof(struct bdc_value)); + val->double_value = value; + val->type = BDC_DOUBLE; + return intern_bdc_add_entry(table, key, val); +} + + +struct bdc_item *intern_bdc_add_entry(struct bdc_hash_table *table, const char *key, struct bdc_value *value) +{ + uint64_t hash = hash_function(key); + size_t hash_idx = hash_idx_from_hash(hash, table->bucket_count); + switch (value->type) { + case BDC_STRING: + log_message(LOG_DEBUG, "adding entry %s %s with hash %lu to bucket %lu", key, value->string, + hash_function(key), hash_idx); + break; + case BDC_INT64: + log_message(LOG_DEBUG, "adding entry %s %ld with hash %lu to bucket %lu", key, value->int64, + hash_function(key), hash_idx); + break; + case BDC_DOUBLE: + log_message(LOG_DEBUG, "adding entry %s %f with hash %lu to bucket %lu", key, + value->double_value, + hash_function(key), hash_idx); + break; + case BDC_CUSTOM: + log_message(LOG_DEBUG, "adding entry %s %p with hash %lu to bucket %lu", key, value->pointer, + hash_function(key), hash_idx); + break; + } + + + struct bdc_item *entry = bdc_intern_get_entry(table, key, hash); + + if (entry != NULL) { + log_message(LOG_DEBUG, "replacing key '%s'", entry->key); + destroy_value(&entry->value); + entry->value = value; + + if (entry->value->type == BDC_STRING) { + log_message(LOG_DEBUG, "setting value of '%s' to '%s'", key, entry->value->string); + } + return entry; + } + assert(entry == NULL); + entry = new_entry(key, value); + bdc_intern_add_entry(table, entry, hash); + + if (table->items_per_bucket[hash_idx] > 2) { + rehash_table(table); + } + + log_message(LOG_DEBUG, "added key '%s'\n", key); + return entry; +} + + +bool bdc_ht_get_int64_from_key(struct bdc_hash_table *table, const char *key, int64_t *result) +{ + struct bdc_value *value = bdc_get_value_from_key(table, key); + if (!value) return false; + if (value->type != BDC_INT64) return false; + *result = value->int64; + return true; +} + + +__attribute__((unused)) bool bdc_ht_get_double_from_key(struct bdc_hash_table *table, const char *key, double *result) +{ + struct bdc_value *value = bdc_get_value_from_key(table, key); + if (!value) return false; + if (value->type != BDC_DOUBLE) return false; + *result = value->double_value; + return true; +} + + +bool bdc_ht_get_string_from_key(struct bdc_hash_table *table, const char *key, char **result) +{ + struct bdc_value *value = bdc_get_value_from_key(table, key); + if (!value) return false; + if (value->type != BDC_STRING) return false; + *result = strdup(value->string); + return true; +} + +void destroy_hash_table(struct bdc_hash_table **ht) +{ + if (ht == NULL || *ht == NULL) return; + struct bdc_hash_table *t = *ht; + size_t count = t->bucket_count; + for (size_t i = 0; i < count; i++){ + struct bdc_item *item = t->items[i]; + while(item){ + struct bdc_item *this = item; + item = item->next; + if (this->value->type == BDC_STRING) { + log_message(LOG_DEBUG, "freeing item '%s' -> '%s'", this->key, this->value->string); + free(this->value->string); + } + free(this->value); + free(this->key); + free(this); + this = NULL; + } + free(item); + } + free(t->items_per_bucket); + free(t->items); + free(t); + *ht = NULL; +} \ No newline at end of file diff --git a/libbdc/bdc_hashtable/bdc_hashtable.h b/libbdc/bdc_hashtable/bdc_hashtable.h new file mode 100644 index 0000000000000000000000000000000000000000..9b7f9ecbde64d3f96bf361b60e451690a210b0da --- /dev/null +++ b/libbdc/bdc_hashtable/bdc_hashtable.h @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_hashtable.h +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef BDC_HASHTABLE_H +#define BDC_HASHTABLE_H + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +#define MIN_SIZE 1024 + + +enum bdc_value_type { + BDC_STRING = 0, + BDC_INT64 = 1, + BDC_DOUBLE = 2, + BDC_CUSTOM +}; + + + + +struct bdc_hash_table; +struct bdc_value; + +bool remove_key(struct bdc_hash_table *table, const char *key); +struct bdc_item *intern_bdc_add_entry(struct bdc_hash_table *table, const char *key, struct bdc_value *value); + +struct bdc_item *bdc_ht_add_string(struct bdc_hash_table *table, const char *key, const char *value); + +struct bdc_item *bdc_ht_add_custom(struct bdc_hash_table *table, const char *key, void *custom); + +struct bdc_item *bdc_ht_add_int64(struct bdc_hash_table *table, const char *key, int64_t value); + +struct bdc_item *bdc_ht_add_double(struct bdc_hash_table *table, const char *key, double value); + +__attribute__((unused)) struct bdc_hash_table *new_hash_table(void); + +__attribute__((unused)) void print_hash_table(const struct bdc_hash_table *table); + +struct bdc_value *bdc_get_value_from_key(struct bdc_hash_table *table, const char *key); + +__attribute__((unused)) bool bdc_key_in_hash_table(struct bdc_hash_table *table, const char *key); + +bool bdc_ht_get_int64_from_key(struct bdc_hash_table *table, const char *key, int64_t *result); + +bool bdc_ht_get_string_from_key(struct bdc_hash_table *table, const char *key, char **result); + +__attribute__((unused)) bool bdc_ht_get_double_from_key(struct bdc_hash_table *table, const char *key, double *result); +void destroy_hash_table(struct bdc_hash_table **ht); + +#define bdc_ht_get_data_from_key(TABLE, KEY, RESULT) _GENERIC((RESULT), \ + int64_t *: bdc_ht_get_int64_from_key, \ + char **: bdc_ht_get_string_from_key, \ + double *: bdc_ht_get_value_from_key, \ +)(TABLE, KEY, (RESULT)) + +#define bdc_ht_add_entry(table, key, value) \ + _Generic((value),\ + int64_t: bdc_ht_add_int64, \ + int: bdc_ht_add_int64, \ + double: bdc_ht_add_double, \ + void *: bdc_ht_add_custom, \ + char *: bdc_ht_add_string)(table, key, value) + + +// move to private later // FIXME +void rehash_table(struct bdc_hash_table *table); +#endif //BDC_HASHTABLE_H diff --git a/libbdc/bdc_hashtable/tests/test_bdc_hashtable.c b/libbdc/bdc_hashtable/tests/test_bdc_hashtable.c new file mode 100644 index 0000000000000000000000000000000000000000..9ebc91628a8d9e6117c8a2013d9d90966e28fa76 --- /dev/null +++ b/libbdc/bdc_hashtable/tests/test_bdc_hashtable.c @@ -0,0 +1,52 @@ + +// SPDX-License-Identifier: GPL-3.0-or-later +// +// test_bdc_hashtable.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include <stdlib.h> +#include "bdc_hashtable/bdc_hashtable.h" +#include "bdc_strings/bdc_strings.h" + + +int main(int argc, char **argv) +{ + //logging_initialize(LOG_DEBUG, NULL, NULL, false); + struct bdc_hash_table *t = new_hash_table(); + bdc_ht_add_string(t, "a", "b12345"); + bdc_ht_add_string(t, "a", "c123123"); + bdc_ht_add_string(t, "b", "d21542"); + bdc_ht_add_string(t, "c", "d316315"); + bdc_ht_add_string(t, "d", "d1326536"); + bdc_ht_add_string(t, "a", "d316136"); + remove_key(t, "a"); + bdc_ht_add_string(t, "a", "e13616136136"); + destroy_hash_table(&t); + + struct string_substitution *s = new_substituter(); + add_substitution(s, "%a", "<was a>"); + add_substitution(s, "%b", "<was b>"); + add_substitution(s, "%c", "<was c>"); + const char *orig = "%c-%a-%b-%c-aa-%d"; + char *x = substitute_string(orig, s); + printf("%s -> %s\n", orig, x); + destroy_substituter(&s); + free(x); + return 0; +} \ No newline at end of file diff --git a/libbdc/bdc_io/CMakeLists.txt b/libbdc/bdc_io/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8436cfbab4603543f88f0eb6b673db7f9d84e809 --- /dev/null +++ b/libbdc/bdc_io/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(bdc_io STATIC "" ../bdc_cross_platform/bdc_cross_platform.h ) + +target_sources(bdc_io + PRIVATE + bdc_io.c + bdc_paths.c + PUBLIC + bdc_io.h +) + + +set_property(TARGET bdc_io PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(bdc_io bdc_strings) diff --git a/src/cats_strings/io_text.c b/libbdc/bdc_io/bdc_io.c similarity index 75% rename from src/cats_strings/io_text.c rename to libbdc/bdc_io/bdc_io.c index 19cac9ba58ad60e2a038d0c0089dc7f534cb79f4..1a0c9313c44f045183b9dddb64cfc12c66adeecf 100644 --- a/src/cats_strings/io_text.c +++ b/libbdc/bdc_io/bdc_io.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -// io_text.c +// bdc_io.c // // Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. // @@ -19,13 +19,12 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#include "cats_global.h" +#include <stdio.h> #include <assert.h> #include <string.h> -#include <stdlib.h> -#include <logging/logging.h> -#include "cats_strings.h" +#include "bdc_memory/bdc_memory.h" +#include "bdc_io.h" char *read_single_line(FILE *file) { @@ -33,9 +32,9 @@ char *read_single_line(FILE *file) char buffer[MAX_STRING_BUFF_LENGTH] = {0}; fgets(buffer, MAX_STRING_BUFF_LENGTH, file); fflush(stdout); - char *result = right_trim(buffer); - if (strlen(result)) return strdup(result); + + if (strlen(buffer)) return strdup(buffer); return NULL; } @@ -47,7 +46,7 @@ char *slurp_file(const char *filename) FILE *file = fopen(filename, "r"); if (!file) { - log_message(LOG_ERROR, "%s: File '%s' does not exist or could not be opened.", __func__, filename); + fprintf(stderr, "%s: File '%s' does not exist or could not be opened.\n", __func__, filename); return NULL; } @@ -56,15 +55,9 @@ char *slurp_file(const char *filename) long size = ftell(file); fseek(file, 0L, SEEK_SET); - char *buffer = malloc(size + 1); - - if (!buffer) { - log_message(LOG_ERROR, "%s: failed to allocate memory", __func__); - exit(EXIT_FAILURE); - } - + char *buffer = malloc_or_die(size + 1); fread(buffer, sizeof(char), size, file); fclose(file); buffer[size] = '\0'; return buffer; -} +} \ No newline at end of file diff --git a/libbdc/bdc_io/bdc_io.h b/libbdc/bdc_io/bdc_io.h new file mode 100644 index 0000000000000000000000000000000000000000..54ade855606b54c1c5b6e0c02f1fe0ea8d3eeee3 --- /dev/null +++ b/libbdc/bdc_io/bdc_io.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_io.h +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef BDC_IO_H +#define BDC_IO_H + +#define MAX_STRING_BUFF_LENGTH 4096 +#if defined(WIN32) || defined (_WIN32) +#define DIRECTORY_SEPARATOR "\\" +#else +#define DIRECTORY_SEPARATOR "/" +#endif + + +#include "bdc_strings/bdc_strings.h" + +char *slurp_file(const char *filename); +char *read_single_line(FILE *file); + +#define ENSURE_FILE_OPENED(FILE_HANDLE, FILENAME)\ +if (! (FILE_HANDLE))\ +{\ + fprintf(stderr, "ERROR: Couldn't open file %s in %s: %d (%s)\n", FILENAME, __FILE__, __LINE__, __func__);\ + exit(EXIT_FAILURE);\ +} + +char *assemble_path(const struct string_array *path); + +char *assemble_filename(struct string_array *path, struct string_array *filename, char *field_separator, char *extension); + +bool check_and_create_directory_if_needed(const struct string_array *directory_path); + +bool directory_exists(const char *path); + +bool directory_writable(const char *path); + +void make_directory(const char *path); +#endif //BDC_IO_H diff --git a/libbdc/bdc_io/bdc_paths.c b/libbdc/bdc_io/bdc_paths.c new file mode 100644 index 0000000000000000000000000000000000000000..586572d0bb15272d145522d3e30344f77843d605 --- /dev/null +++ b/libbdc/bdc_io/bdc_paths.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_paths.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include <string.h> +#include <sys/stat.h> +#include <stdio.h> +#include <errno.h> + +#include "bdc_io.h" +#include "bdc_cross_platform/bdc_cross_platform.h" + +#ifdef BDC_ON_WINDOWS +#include <direct.h> +#else +#include <unistd.h> +#endif + + + +bool directory_exists(const char *path) +{ + struct stat info; + int rc = stat(path, &info); + if (rc == 0 && info.st_mode & S_IFDIR) return true; + + if (rc == 0) { + fprintf(stderr, "Path '%s' is not a directory. Exiting.\n", path); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "Directory '%s' does not exist\n", path); + return false; +} + + +bool directory_writable(const char *path) +{ + int rc = access(path, F_OK); + + if (rc == 0) { + return true; + } + + fprintf(stderr, "directory %s exists but cannot be accessed or written to.\n", path); + return false; +} + + +void make_directory(const char *path) +{ +#ifndef BDC_ON_WINDOWS + int rc = mkdir(path, S_IRWXU); +#else + int rc = _mkdir(path); +#endif + if (rc == 0) return; + + int error = errno; + fprintf(stderr, "unable to create directory %s: %s\n", path, strerror(error)); + exit(EXIT_FAILURE); +} + + +char *assemble_path(const struct string_array *path) +{ + return string_array_paste(path, DIRECTORY_SEPARATOR); +} + + +char * +assemble_filename(struct string_array *path, struct string_array *filename, char *field_separator, char *extension) +{ + char *name_string = string_array_paste(filename, field_separator); + char *result = NULL; + + if (path && get_string_count(path) > 0) { + char *path_string = string_array_paste(path, DIRECTORY_SEPARATOR); + if (extension && strlen(extension)) { + char *fn = compound_string(name_string, extension, "."); + result = compound_string(path_string, fn, DIRECTORY_SEPARATOR); + free(fn); + } else { + result = compound_string(path_string, name_string, DIRECTORY_SEPARATOR); + } + free(path_string); + } else { + + if (extension && strlen(extension)) { + result = compound_string(name_string, extension, "."); + } else { + result = strdup(name_string); + } + } + + free(name_string); + return result; +} + + +bool check_and_create_directory_if_needed(const struct string_array *directory_path) +{ + if (directory_path == NULL || get_string_count(directory_path) == 0) { + fprintf(stderr, "Unable to check directory - no path specified\n"); + exit(EXIT_FAILURE); + } + + char *dir = assemble_path(directory_path); + + + if (!directory_exists(dir)) { + fprintf(stderr, "directory '%s' does not exist. Trying to create.\n", dir); + make_directory(dir); + } + + bool writeable = directory_writable(dir); + free(dir); + return writeable; +} \ No newline at end of file diff --git a/libbdc/bdc_logging/CMakeLists.txt b/libbdc/bdc_logging/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3391d9862697e0cd9c94b604e9546daecbbfdb0e --- /dev/null +++ b/libbdc/bdc_logging/CMakeLists.txt @@ -0,0 +1,12 @@ +add_library(bdc_logging STATIC "") + +target_sources(bdc_logging + PRIVATE + logging.c + PUBLIC + logging.h + ) + +target_include_directories(bdc_logging PUBLIC ".") +target_link_libraries(bdc_logging bdc_memory bdc_time bdc_cross_platform) +set_property(TARGET bdc_logging PROPERTY POSITION_INDEPENDENT_CODE ON) \ No newline at end of file diff --git a/libbdc/bdc_logging/README.md b/libbdc/bdc_logging/README.md new file mode 100644 index 0000000000000000000000000000000000000000..32e219e21dfd07c71180c652f6d5d2dac42b617b --- /dev/null +++ b/libbdc/bdc_logging/README.md @@ -0,0 +1,10 @@ +# bdc_logging + +This is a library to handle logging. + +## Dependencies +* bdc_memory +* bdc_time +* bdc_cross_platform (header only) + + diff --git a/src/logging/logging.c b/libbdc/bdc_logging/logging.c similarity index 58% rename from src/logging/logging.c rename to libbdc/bdc_logging/logging.c index a7c0ed515b4fce7d30b8e52093d057f932008926..73e5f822cbdc4302732d1a129280aa2bd665e70c 100644 --- a/src/logging/logging.c +++ b/libbdc/bdc_logging/logging.c @@ -21,27 +21,26 @@ #include <stdbool.h> #include <stdio.h> -#include <stdint.h> #include <string.h> #include <stdarg.h> #include <stdlib.h> -#include "logging.h" + #include "bdc_memory/bdc_memory.h" #include "bdc_time/bdc_time.h" -#include "misc/misc.h" - +#include "bdc_io/bdc_io.h" +#include "bdc_logging/logging.h" -enum cats_log_level internal_current_log_level = LOG_INFO; +enum bdc_log_level internal_current_log_level = LOG_INFO; int32_t logging_mpi_rank = -1; -struct bdc_time cats_logging_start_time; -FILE *cats_log_file = NULL; -char *cats_log_file_name = NULL; +struct bdc_time bdc_logging_start_time; +FILE *bdc_log_file = NULL; +char *bdc_log_file_name = NULL; const char *logging_module_name = NULL; bool time_initialized = false; bool logging_quiet = false; -const char *get_log_level_name(enum cats_log_level level) +const char *get_log_level_name(enum bdc_log_level level) { switch (level) { case LOG_DEBUG: @@ -50,7 +49,6 @@ const char *get_log_level_name(enum cats_log_level level) return "INFO"; case LOG_RAW: case LOG_EMPTY: - return ""; case LOG_MARK: return ""; case LOG_IMPORTANT: @@ -70,58 +68,52 @@ const char *get_log_level_name(enum cats_log_level level) } -const char *get_log_level_color(enum cats_log_level level) +const char *get_log_level_color(enum bdc_log_level level) { switch (level) { case LOG_RAW: case LOG_DEBUG: - return C_RESET; case LOG_INFO: - return C_RESET; case LOG_EMPTY: - return C_RESET; case LOG_MARK: return C_RESET; case LOG_IMPORTANT: - return C_YELLOW; case LOG_WARNING: return C_YELLOW; case LOG_ERROR: - return C_RED; case LOG_MPI: - return C_RED; case LOG_UNIMPLEMENTED: - return C_RED; case LOG_UNKNOWN: return C_RED; + } return C_RESET; } -void set_log_level(enum cats_log_level new_level) +void set_log_level(enum bdc_log_level new_level) { internal_current_log_level = new_level; } - // - mpi world rank can be added later // FIXME: if start_time is NULL, generate -void logging_initialize(enum cats_log_level level, const struct bdc_time *start_time, const char *log_file_name, bool quiet) +void +logging_initialize(enum bdc_log_level level, const struct bdc_time *start_time, const char *log_file_name, bool quiet) { set_log_level(level); logging_quiet = quiet; if (start_time != NULL) { - cats_logging_start_time = *start_time; + bdc_logging_start_time = *start_time; time_initialized = true; } if (log_file_name != NULL) { - cats_log_file_name = strdup(log_file_name); - cats_log_file = fopen(log_file_name, "w"); - ENSURE_FILE_OPENED(cats_log_file, cats_log_file_name) + bdc_log_file_name = strdup(log_file_name); + bdc_log_file = fopen(log_file_name, "w"); + ENSURE_FILE_OPENED(bdc_log_file, bdc_log_file_name) } } @@ -138,13 +130,16 @@ void logging_set_mpi_rank(int mpi_world_rank) logging_mpi_rank = mpi_world_rank; } + // actual logging function(s), only to be called from log_message -void log_msg(const char *msg, enum cats_log_level loglevel); -void log_msg_simple(const char *msg, enum cats_log_level loglevel); +void log_msg(const char *msg, enum bdc_log_level loglevel); + +void log_msg_simple(const char *msg, enum bdc_log_level loglevel); + // logging wrapper function __attribute__ ((__format__ (__printf__, 2, 3))) -void log_message(enum cats_log_level level, const char *fmt, ...) +void log_message(enum bdc_log_level level, const char *fmt, ...) { if (level < internal_current_log_level) return; @@ -165,13 +160,13 @@ void log_message(enum cats_log_level level, const char *fmt, ...) } -enum cats_log_level get_log_level(void) +enum bdc_log_level get_log_level(void) { return internal_current_log_level; } -void log_message_simple(enum cats_log_level level, const char *fmt, ...) +__attribute__((unused)) void log_message_simple(enum bdc_log_level level, const char *fmt, ...) { if (level < internal_current_log_level) return; char *message = NULL; @@ -190,26 +185,26 @@ void log_message_simple(enum cats_log_level level, const char *fmt, ...) } -void log_msg(const char *msg, enum cats_log_level loglevel) +void log_msg(const char *msg, enum bdc_log_level loglevel) { if (loglevel < internal_current_log_level) return; if (loglevel == LOG_RAW) { - if (! logging_quiet) fprintf(stdout, "%s", msg); - if (cats_log_file != NULL) fprintf(cats_log_file, "%s", msg); + if (!logging_quiet) fprintf(stdout, "%s", msg); + if (bdc_log_file != NULL) fprintf(bdc_log_file, "%s", msg); return; } if (loglevel == LOG_EMPTY) { - if (! logging_quiet) fprintf(stdout, "\n"); - if (cats_log_file != NULL) fprintf(cats_log_file, "\n"); + if (!logging_quiet) fprintf(stdout, "\n"); + if (bdc_log_file != NULL) fprintf(bdc_log_file, "\n"); return; } const char *color = get_log_level_color(loglevel); if (loglevel == LOG_MARK) { - if (! logging_quiet) fprintf(stdout, "%s%s%s\n", color, msg, C_RESET); - if (cats_log_file != NULL) fprintf(cats_log_file, "%s%s%s\n", color, msg, C_RESET); + if (!logging_quiet) fprintf(stdout, "%s%s%s\n", color, msg, C_RESET); + if (bdc_log_file != NULL) fprintf(bdc_log_file, "%s%s%s\n", color, msg, C_RESET); return; } const char *log_default = "unknown"; @@ -222,55 +217,60 @@ void log_msg(const char *msg, enum cats_log_level loglevel) if (logging_mpi_rank >= 0) { - if (! logging_quiet) fprintf(stdout, "(%02d)::", logging_mpi_rank); - if (cats_log_file != NULL) fprintf(cats_log_file, "(%02d)::", logging_mpi_rank); + if (!logging_quiet) fprintf(stdout, "(%02d)::", logging_mpi_rank); + if (bdc_log_file != NULL) fprintf(bdc_log_file, "(%02d)::", logging_mpi_rank); } if (time_initialized) { - double secs = seconds_monotonic_since(&cats_logging_start_time); - if (cats_log_file != NULL) { - fprintf(cats_log_file, "% 16.4f::", secs); + double secs = seconds_monotonic_since(&bdc_logging_start_time); + if (bdc_log_file != NULL) { + fprintf(bdc_log_file, "% 16.4f::", secs); } - if (! logging_quiet) fprintf(stdout, "% 16.4f::", secs); + if (!logging_quiet) fprintf(stdout, "% 16.4f::", secs); } else { - if (cats_log_file != NULL) { - fprintf(cats_log_file, " ::"); + if (bdc_log_file != NULL) { + fprintf(bdc_log_file, " ::"); } - if (! logging_quiet) fprintf(stdout, " ::"); + if (!logging_quiet) fprintf(stdout, " ::"); } if (logging_module_name != NULL) { - if (! logging_quiet) fprintf(stdout, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET); - if (cats_log_file) fprintf(cats_log_file, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET); + if (!logging_quiet) + fprintf(stdout, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET); + if (bdc_log_file) + fprintf(bdc_log_file, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, + C_RESET); } else { - if (! logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); - if (cats_log_file) fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); + if (!logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); + if (bdc_log_file) fprintf(bdc_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); } } -void log_msg_simple(const char *msg, enum cats_log_level loglevel) +void log_msg_simple(const char *msg, enum bdc_log_level loglevel) { if (loglevel < internal_current_log_level) return; const char *log_default = "unknown"; const char *loglevel_name = log_default; - if (loglevel <= LOG_UNKNOWN && loglevel >= LOG_DEBUG) { + if (loglevel <= LOG_UNKNOWN) { loglevel_name = get_log_level_name(loglevel); } const char *color = get_log_level_color(loglevel); if (logging_mpi_rank >= 0) { - if (! logging_quiet) fprintf(stdout, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET); - if (cats_log_file != NULL) fprintf(cats_log_file, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET); + if (!logging_quiet) + fprintf(stdout, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET); + if (bdc_log_file != NULL) + fprintf(bdc_log_file, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, + C_RESET); } else { - if (! logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); - if (cats_log_file != NULL) fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); + if (!logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); + if (bdc_log_file != NULL) fprintf(bdc_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); } - } diff --git a/src/logging/logging.h b/libbdc/bdc_logging/logging.h similarity index 66% rename from src/logging/logging.h rename to libbdc/bdc_logging/logging.h index 52eefe767e846a4ffef06e4853a7241b5c901e65..2a5ac642429a296017353904a527205c606c936f 100644 --- a/src/logging/logging.h +++ b/libbdc/bdc_logging/logging.h @@ -19,14 +19,15 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#ifndef CATS_LOGGING_H_ -#define CATS_LOGGING_H_ +#ifndef BDC_LOGGING_H_ +#define BDC_LOGGING_H_ + #include <stdbool.h> -#include "cats_defs.h" #include <time.h> + #include "bdc_time/bdc_time.h" -#if defined(__MINGW32__) || defined(CATS_ON_WINDOWS) +#if defined(__MINGW32__) || defined(WIN32) // no color codes #define C_RED "" #define C_GREEN "" @@ -41,7 +42,7 @@ #define C_WHITE "\x1B[37m" #endif -enum cats_log_level { +enum bdc_log_level { LOG_DEBUG, LOG_INFO, LOG_EMPTY, @@ -55,19 +56,25 @@ enum cats_log_level { LOG_UNKNOWN }; -void logging_initialize(enum cats_log_level level, const struct bdc_time *start_time, const char *log_file_name, bool quiet); +void +logging_initialize(enum bdc_log_level level, const struct bdc_time *start_time, const char *log_file_name, bool quiet); void logging_set_mpi_rank(int mpi_world_rank); void logging_set_module_name(const char *name); __attribute__ ((__format__ (__printf__, 2, 3))) -void log_message(enum cats_log_level level, const char *fmt, ...); +void log_message(enum bdc_log_level level, const char *fmt, ...); + +enum bdc_log_level get_log_level(void); + +__attribute__((unused)) void log_message_simple(enum bdc_log_level level, const char *fmt, ...); -enum cats_log_level get_log_level(void); +void set_log_level(enum bdc_log_level new_level); -void log_message_simple(enum cats_log_level level, const char *fmt, ...); +#define INCOMPLETE_IMPLEMENTATION() log_message(LOG_ERROR, "%s: not yet implemented", __func__) +#define MISSING_IMPLEMENTATION(X) log_message(LOG_ERROR, "%s: missing functionality %s", __func__, (X)) +#define ABORT_IMPLEMENTATION() log_message(LOG_ERROR, "%s:%s:%d: not yet implemented", __FILE__, __func__, __LINE__); exit(EXIT_FAILURE) -void set_log_level(enum cats_log_level new_level); #endif \ No newline at end of file diff --git a/libbdc/bdc_strings/CMakeLists.txt b/libbdc/bdc_strings/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..78d25f74c5bf3c3f9b29ae31125e98b2646eadf4 --- /dev/null +++ b/libbdc/bdc_strings/CMakeLists.txt @@ -0,0 +1,18 @@ +add_library(bdc_strings STATIC "" ../bdc_cross_platform/bdc_cross_platform.h + +) + +target_sources(bdc_strings + PRIVATE + bdc_strings.c + pretty_print.c + string_helpers.c + string_substitution.c + string_converters.c + PUBLIC + bdc_strings.h + + ) + +set_property(TARGET bdc_strings PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(bdc_strings bdc_logging bdc_hashtable) \ No newline at end of file diff --git a/libbdc/bdc_strings/README.md b/libbdc/bdc_strings/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a86721af7f78b5a20dfe18c4e18a8254a00e6b0 --- /dev/null +++ b/libbdc/bdc_strings/README.md @@ -0,0 +1,9 @@ +# bdc_strings + + +This is a library to handle strings. + +## Dependencies +* bdc_logging +* bdc_hashtable + diff --git a/src/cats_strings/cats_strings.c b/libbdc/bdc_strings/bdc_strings.c similarity index 80% rename from src/cats_strings/cats_strings.c rename to libbdc/bdc_strings/bdc_strings.c index 4843f1b104b68ebf2937b421383ce1208db3d059..64a67339550d6b5b83ed4cfc53a1847c5e6f2a29 100644 --- a/src/cats_strings/cats_strings.c +++ b/libbdc/bdc_strings/bdc_strings.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -// cats_strings.c +// bdc_strings.c // // Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. // @@ -19,24 +19,57 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#include "cats_global.h" +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "cats_strings.h" -#include <logging/logging.h> +#include "bdc_strings.h" +#include "bdc_logging/logging.h" #include "bdc_memory/bdc_memory.h" -#include <assert.h> + +struct string_array { + int count; + char **string; + enum JSON_HINT *typehint; +}; void asprintf_check(int rc) { if (rc >= 0) return; - log_message(LOG_ERROR, "error in asprintf_ could not allocate memory or other error. rc: %d", rc); + log_message(LOG_ERROR, "error in asprintf - could not allocate memory or other error. rc: %d", rc); exit(EXIT_FAILURE); } +void snprintf_check(int rc, size_t expected) +{ + if (rc >= 0 && (rc == expected || rc + 1 == expected)) return; + if (rc < 0) { + log_message(LOG_ERROR, "error in snprintf - error : %d", rc); + exit(EXIT_FAILURE); + } + if (rc < expected - 1) { + log_message(LOG_DEBUG, "error in snprintf - output truncated: %d of %ld bytes written", rc, expected); + } +} + +int get_string_count(const struct string_array *array) +{ + assert(array != NULL); + return array->count; +} + + +const char *get_string(const struct string_array *array, int count) +{ + assert(array != NULL); + assert(count >= 0); + assert(count < array->count); + return array->string[count]; + +} + void string_array_add(struct string_array *array, const char *string) { if (!array) { @@ -51,6 +84,8 @@ void string_array_add(struct string_array *array, const char *string) DBG_STRING(log_message(LOG_RAW, "%s: address: %p\n", __func__, array);) DBG_STRING(log_message(LOG_RAW, "%s: count: %d\n", __func__, array->count);) DBG_STRING(log_message(LOG_RAW, "%s: trying to add: %s\n", __func__, string);) + DBG_STRING(log_message(LOG_RAW, "%p: string address: %p\n", __func__, array->string);) + DBG_STRING(log_message(LOG_RAW, "%s: new size: %zu\n", __func__, new_size);) array->string = realloc_or_die(array->string, new_size); array->typehint = realloc_or_die(array->typehint, sizeof(enum JSON_HINT) * (array->count + 1)); @@ -66,7 +101,7 @@ void string_array_add(struct string_array *array, const char *string) } -void string_array_add_conditional(struct string_array *array, char *string, bool condition) +__attribute__((unused)) void string_array_add_conditional(struct string_array *array, char *string, bool condition) { if (!condition) return; string_array_add(array, string); @@ -79,8 +114,10 @@ void string_array_add_int(struct string_array *array, int32_t number, const char if (!format_string || !strlen(format_string)) f = "%d"; int count = snprintf(NULL, 0, f, number) + 1; + snprintf_check(count, -1); char *tmp = malloc_or_die(count); - snprintf(tmp, count, f, number); + int rc = snprintf(tmp, count, f, number); + snprintf_check(rc, count); string_array_add(array, tmp); array->typehint[array->count - 1] = JSON_NUMERIC; @@ -94,6 +131,7 @@ void string_array_add_int64(struct string_array *array, int64_t number, char *fo if (!format_string || !strlen(format_string)) f = "%ld"; int count = snprintf(NULL, 0, f, number) + 1; + snprintf_check(count, -1); char *tmp = malloc_or_die(count); snprintf(tmp, count, f, number); @@ -103,20 +141,22 @@ void string_array_add_int64(struct string_array *array, int64_t number, char *fo } -void string_array_add_double(struct string_array *array, double number, const char *format_string) +__attribute__((unused)) void string_array_add_double(struct string_array *array, double number, const char *format_string) { const char *f = format_string; if (!format_string || !strlen(format_string)) f = "%f"; int count = snprintf(NULL, 0, f, number) + 1; + snprintf_check(count, -1); char *tmp = malloc_or_die(count); - snprintf(tmp, count, f, number); + int rc = snprintf(tmp, count, f, number); + snprintf_check(rc, count); string_array_add(array, tmp); array->typehint[array->count - 1] = JSON_NUMERIC; free(tmp); } -void +__attribute__((unused)) void string_array_add_int_conditional(struct string_array *array, int32_t number, const char *format_string, bool condition) { if (!condition) return; @@ -134,11 +174,18 @@ struct string_array *new_string_array() return result; } -const char *get_nth_string_from_array(const struct string_array *array, int n) + +__attribute__((unused)) const char *string_array_get_string(const struct string_array *array, int n) { + + if (array == NULL || array->string == NULL) { + log_message(LOG_ERROR, "%s: string array or contents are NULL", __func__); + exit(EXIT_FAILURE); + } assert(array != NULL); + if (n < 0 && n >= array->count) { - log_message(LOG_ERROR, "%s: requested string index %d out of range [0, %d]", __func__ , n, array->count); + log_message(LOG_ERROR, "%s: requested string index %d out of range [0, %d]", __func__, n, array->count); exit(EXIT_FAILURE); } @@ -146,6 +193,7 @@ const char *get_nth_string_from_array(const struct string_array *array, int n) } + struct string_array *new_string_array_init(const char *entry) { struct string_array *result = new_string_array(); @@ -207,16 +255,16 @@ int32_t count_fields(const char *line, const char *sep) // untested trivial -void abort_on_null_token(const char *token, char *orig, int count) +void abort_on_null_token(const char *token, const char *orig, int count) { if (token != NULL) return; log_message(LOG_WARNING, "%s: string '%s' has not enough (%d) tokens", __func__, orig, count); abort(); - exit(EXIT_FAILURE); + //exit(EXIT_FAILURE); } -struct string_array *get_all_tokens(char *line, const char *sep) +struct string_array *get_all_tokens(const char *line, const char *sep) { const int32_t max_count = count_fields(line, sep); @@ -229,6 +277,7 @@ struct string_array *get_all_tokens(char *line, const char *sep) char *token = strtok_r(copy, sep, &saveptr); abort_on_null_token(token, line, max_count); + char *to_add = strdup(token); to_add = left_trim(right_trim(to_add)); string_array_add(result, to_add); @@ -253,7 +302,7 @@ struct string_array *get_all_tokens(char *line, const char *sep) } -char *get_nth_token(char *line, const char *sep, int32_t n) +__attribute__((unused)) char *get_nth_token(char *line, const char *sep, int32_t n) { char *result = NULL; struct string_array *tokens = get_all_tokens(line, sep); @@ -265,7 +314,7 @@ char *get_nth_token(char *line, const char *sep, int32_t n) } -char *remove_0th_token(char *line, const char *sep) +char *remove_0th_token(const char *line, const char *sep) { char *result = NULL; struct string_array *tokens = get_all_tokens(line, sep); @@ -302,7 +351,7 @@ char *json_dict(const struct string_array *header, const struct string_array *da char *result = calloc_or_die(1, len); - size_t written = 0; + size_t written; // = 0; result[0] = '{'; // written: 1 written = 1; @@ -361,7 +410,7 @@ char *string_array_paste(const struct string_array *array, const char *sep) if (length == 0) { log_message(LOG_ERROR, "%s: empty string, exiting", __func__); abort(); - exit(EXIT_FAILURE); + // exit(EXIT_FAILURE); } length += (array->count - 1) * strlen(sep); // space for separator @@ -382,7 +431,7 @@ char *string_array_paste(const struct string_array *array, const char *sep) } -void print_string_array(const struct string_array *array) +__attribute__((unused)) void print_string_array(const struct string_array *array) { log_message(LOG_RAW, "string array with %d entries:\n", array->count); for (int32_t i = 0; i < array->count; i++) { @@ -392,7 +441,7 @@ void print_string_array(const struct string_array *array) } -int32_t string_array_index(const struct string_array *array, const char *needle) +__attribute__((unused)) int32_t string_array_string_index(const struct string_array *array, const char *needle) { if (array == NULL) { log_message(LOG_ERROR, "%s: called with empty parameter array", __func__); @@ -407,7 +456,7 @@ int32_t string_array_index(const struct string_array *array, const char *needle) } -bool in_string_array(const struct string_array *array, const char *needle) +__attribute__((unused)) bool string_array_contains_string(const struct string_array *array, const char *needle) { for (int32_t i = 0; i < array->count; i++) { if (strcmp(needle, array->string[i]) == 0) return true; @@ -442,6 +491,20 @@ char *compound_string(const char *s1, const char *s2, const char *sep) size_t len = strlen(s1) + strlen(s2) + strlen(sep) + 1; result = malloc_or_die(len); - snprintf(result, len, "%s%s%s", s1, sep, s2); + //printf("s1: %s (%ld)\n", s1, strlen(s1)); + //printf("sep: %s (%ld)\n", sep, strlen(sep)); + //printf("s2: %s (%ld)\n", s2, strlen(s2)); + //printf("len: %ld\n", len); + int rc = snprintf(result, len, "%s%s%s", s1, sep, s2); + //printf("res: %s (%ld)\n", result, strlen(result)); + snprintf_check(rc, len); return result; -} \ No newline at end of file +} + + +bool string_is_empty_or_null(const char *name) +{ + if (name == NULL) return true; + if (strlen(name) == 0) return true; // FIXME CHECK ONLY FIRST X BYTES + return false; +} diff --git a/src/cats_strings/cats_strings.h b/libbdc/bdc_strings/bdc_strings.h similarity index 52% rename from src/cats_strings/cats_strings.h rename to libbdc/bdc_strings/bdc_strings.h index d0031c202ea42da7c25c62db078eecee8d852754..7e64d1790fadb9bf2fb7458cf8dd08b3a4bbff00 100644 --- a/src/cats_strings/cats_strings.h +++ b/libbdc/bdc_strings/bdc_strings.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -// cats_strings.h +// bdc_strings.h // // Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. // @@ -21,51 +21,44 @@ #ifndef CATS_STRING_H_ #define CATS_STRING_H_ + #include <stdlib.h> #include <stdbool.h> #include <stdint.h> -#include "data/error.h" +#include <stdio.h> + +struct string_array; +struct string_substitution; enum JSON_HINT { JSON_STRING = 0, JSON_QUOTED = 0, JSON_UNQUOTED = 1, JSON_NUMERIC = 1 }; +// constants +#define TEXT_DIVIDER "==================================================================================================" +#define PAD_NAME 55 +#define PAD_VALUE 35 -struct string_array { - int count; - char **string; - enum JSON_HINT *typehint; -}; - - - - -#include <stdio.h> - -#define MAX_STRING_BUFF_LENGTH 2048 - -char *read_single_line(FILE *file); - -char *slurp_file(const char *filename); +//#define DEBUG_STRING +#ifdef DEBUG_STRING +#define DBG_STRING(X) {X;}while(0); +#else +#define DBG_STRING(X) +#endif -#define ENSURE_FILE_OPENED(FILE_HANDLE, FILENAME)\ -if (! (FILE_HANDLE))\ -{\ - fprintf(stderr, "ERROR: Couldn't open file %s in %s: %d (%s)\n", FILENAME, __FILE__, __LINE__, __func__);\ - exit(E_UNREADABLE_FILE);\ -} +// string array functions +struct string_array *new_string_array(void); -void asprintf_check(int rc); +const char *get_string(const struct string_array *array, int count); -struct string_array *new_string_array(void); +int get_string_count(const struct string_array *array); void free_string_array(struct string_array **array); -int32_t count_fields(const char *line, const char *sep); +struct string_array *get_all_tokens(const char *line, const char *sep); -struct string_array *get_all_tokens(char *line, const char *seperator); void string_array_add(struct string_array *array, const char *string); @@ -73,33 +66,42 @@ void string_array_add_int64(struct string_array *array, int64_t number, char *fo char *string_array_paste(const struct string_array *array, const char *sep); -char *assemble_filename(struct string_array *path, struct string_array *filename, char *filesep, char *extension); void string_array_add_int(struct string_array *array, int32_t number, const char *format_string); struct string_array *new_string_array_init(const char *entry); -void string_array_add_conditional(struct string_array *array, char *string, bool conditon); +__attribute__((unused)) void string_array_add_conditional(struct string_array *array, char *string, bool conditon); -void string_array_add_double(struct string_array *array, double number, const char *format_string); +__attribute__((unused)) void string_array_add_double(struct string_array *array, double number, const char *format_string); -void +__attribute__((unused)) void string_array_add_int_conditional(struct string_array *array, int32_t number, const char *format_string, bool condition); -const char *get_nth_string_from_array(const struct string_array *array, int n); -void print_string_array(const struct string_array *array); -char *remove_0th_token(char *line, const char *sep); +__attribute__((unused)) const char *string_array_get_string(const struct string_array *array, int n); + +__attribute__((unused)) void print_string_array(const struct string_array *array); -char *get_nth_token(char *line, const char *sep, int32_t n); struct string_array *copy_string_array(const struct string_array *src); char *json_dict(const struct string_array *header, const struct string_array *data); -int32_t string_array_index(const struct string_array *array, const char *needle); +int32_t string_array_string_index(const struct string_array *array, const char *needle); + +__attribute__((unused)) bool string_array_contains_string(const struct string_array *array, const char *needle); + + +// string functions +char *trim_both(char *line); + +int32_t count_fields(const char *line, const char *sep); + -bool in_string_array(const struct string_array *array, const char *needle); +char *remove_0th_token(const char *line, const char *sep); + +__attribute__((unused)) char *get_nth_token(char *line, const char *sep, int32_t n); size_t substring_count(const char *haystack, const char *needle); @@ -115,14 +117,20 @@ char *right_trim(char *line); char *left_trim(char *line); -void abort_on_null_token(const char *token, char *orig, int count); +bool string_is_empty_or_null(const char *name); -#define PAD_NAME 55 -#define PAD_VALUE 35 +void abort_on_null_token(const char *token, const char *orig, int count); +// helper functions + +void asprintf_check(int rc); +void snprintf_check(int rc, size_t expected); + + +// pretty print functions void print_string(int indent, const char *name, const char *value); -void print_subcategory(int indent, const char *category_name, int64_t category_number, char *name); +void print_subcategory(int indent, const char *category_name, int64_t category_number, const char *name); void print_category(int indent, const char *category, const char *name); @@ -130,15 +138,38 @@ void print_integer(int indent, const char *name, int64_t value); void print_rate(int indent, const char *name, long double value); + + +// string substitution + +void add_substitution(struct string_substitution *substituter, const char *key, const char *initial_value); + +void update_substitution(struct string_substitution *substituter, const char *key, const char *initial_value); + +struct string_substitution *new_substituter(void); + +char *substitute_string(const char *string, const struct string_substitution *substituter); + +void destroy_substituter(struct string_substitution **substituter); + +struct string_substitution *copy_substituter(const struct string_substitution *from); + +void add_substitution_integer(struct string_substitution *substituter, const char *key, int32_t initial_value); + +void set_integer_pattern(struct string_substitution *substituter, const char *key, const char *pattern); + + +// conversion function const char *bool_to_string(bool b); -#ifdef DEBUG_STRING -#define DBG_STRING(X) {X;}while(0); -#else -#define DBG_STRING(X) -#endif +bool string_to_float(char *string, float *value); + +bool string_to_bool(char *string, bool *value); + +bool string_to_double(const char *string, double *value); -// implemented in string_helpers.h +bool string_to_integer(const char *string, int32_t *value); +bool string_to_long_double(const char *string, long double *value); #endif diff --git a/src/cats_strings/pretty_print.c b/libbdc/bdc_strings/pretty_print.c similarity index 95% rename from src/cats_strings/pretty_print.c rename to libbdc/bdc_strings/pretty_print.c index fb94e70e609bae74089f2ce9c4f6242b5ea68e3a..a3797c3aa733638c488de17c2aafa3728d209e60 100644 --- a/src/cats_strings/pretty_print.c +++ b/libbdc/bdc_strings/pretty_print.c @@ -19,10 +19,11 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#include "cats_global.h" + #include <inttypes.h> -#include "cats_strings.h" -#include "logging/logging.h" +#include "bdc_strings.h" +#include "bdc_logging/logging.h" + void print_string(int indent, const char *name, const char *value) { @@ -32,7 +33,7 @@ void print_string(int indent, const char *name, const char *value) } -void print_subcategory(int indent, const char *category_name, int64_t category_number, char *name) +void print_subcategory(int indent, const char *category_name, int64_t category_number, const char *name) { indent *= 2; if (indent > 0) log_message(LOG_RAW, "%*s", indent, ""); diff --git a/src/cats_strings/string_converters.c b/libbdc/bdc_strings/string_converters.c similarity index 94% rename from src/cats_strings/string_converters.c rename to libbdc/bdc_strings/string_converters.c index 5578c1ecc2e2e69ccc64aad52035ea6bb56a2bf5..c7b8b74926cebc4eb5870316b49c16d2e3b863ba 100644 --- a/src/cats_strings/string_converters.c +++ b/libbdc/bdc_strings/string_converters.c @@ -25,8 +25,10 @@ #include <string.h> #include <errno.h> #include <stdlib.h> -#include "string_converters.h" -#include "logging/logging.h" + + +#include "bdc_logging/logging.h" + const char *true_values[] = {"1", "y", "t"}; const char *false_values[] = {"0", "n", "f"}; @@ -34,7 +36,7 @@ const int true_counts = (int) (sizeof(true_values) / sizeof(char *)); const int false_counts = (int) (sizeof(false_values) / sizeof(char *)); -bool string_to_double(char *string, double *value) +bool string_to_double(const char *string, double *value) { if (string == NULL || strlen(string) == 0) return false; @@ -82,7 +84,7 @@ bool string_to_float(char *string, float *value) } -bool string_to_long_double(char *string, long double *value) +bool string_to_long_double(const char *string, long double *value) { if (string == NULL || strlen(string) == 0) return false; @@ -127,7 +129,7 @@ bool string_to_bool(char *string, bool *value) } -bool string_to_integer(char *string, int32_t *value) +bool string_to_integer(const char *string, int32_t *value) { if (string == NULL || strlen(string) == 0) return false; @@ -148,3 +150,7 @@ bool string_to_integer(char *string, int32_t *value) return false; } + + + + diff --git a/src/cats_strings/string_helpers.c b/libbdc/bdc_strings/string_helpers.c similarity index 90% rename from src/cats_strings/string_helpers.c rename to libbdc/bdc_strings/string_helpers.c index eb6553fa7543bd54b55214b74d4e7504debddf74..9c46586d411f2519804df9b364a37a00e23b6196 100644 --- a/src/cats_strings/string_helpers.c +++ b/libbdc/bdc_strings/string_helpers.c @@ -19,12 +19,11 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#include "cats_global.h" #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <ctype.h> -#include <logging/logging.h> +#include "bdc_logging/logging.h" #include "bdc_memory/bdc_memory.h" @@ -78,6 +77,13 @@ char *left_trim(char *line) } +char *trim_both(char *line) +{ + return left_trim(right_trim(line)); + +} + + size_t substring_count(const char *haystack, const char *needle) { size_t count = 0; @@ -134,8 +140,8 @@ char *replace_substring(const char *original, const char *search, const char *re exit(EXIT_FAILURE); } - size_t occurrences = substring_count(original, search); - size_t result_len = strlen(original) + strlen(replacement) * occurrences - strlen(search) * occurrences + 1; + size_t n_occurrences = substring_count(original, search); + size_t result_len = strlen(original) + strlen(replacement) * n_occurrences - strlen(search) * n_occurrences + 1; char *result = calloc_or_die(1, result_len); @@ -144,20 +150,24 @@ char *replace_substring(const char *original, const char *search, const char *re size_t bytes_copied = 0; - for (size_t i = 0; i < occurrences; i++) { + for (size_t i = 0; i < n_occurrences; i++) { char *next_occurrence = strstr(orig_loc, search); - if (next_occurrence == NULL) { break; } + if (next_occurrence == NULL || strlen(next_occurrence) == 0) { break; } + + // how many bytes are before our first hit? size_t bytes_to_copy = strlen(orig_loc) - strlen(next_occurrence); + + if (bytes_to_copy) { bytes_copied += bytes_to_copy; strncpy(result_loc, orig_loc, bytes_to_copy); result_loc += bytes_to_copy; - orig_loc += bytes_to_copy + search_len; + orig_loc += bytes_to_copy; } - - strncpy(result_loc, replacement, replacement_len); result_loc += replacement_len; + orig_loc += search_len; + } if (bytes_copied < original_len) { diff --git a/libbdc/bdc_strings/string_substitution.c b/libbdc/bdc_strings/string_substitution.c new file mode 100644 index 0000000000000000000000000000000000000000..2ee87c138c2c97a7de2df7e3ae82bfbdf709b83a --- /dev/null +++ b/libbdc/bdc_strings/string_substitution.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// string_substitution.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include <string.h> + +#include "bdc_memory/bdc_memory.h" +#include "bdc_logging/logging.h" +#include "bdc_hashtable/bdc_hashtable.h" +#include "bdc_strings.h" + +struct string_substitution { + struct bdc_hash_table *substitution_strings; + struct bdc_hash_table *integer_patterns; + struct string_array *keys; +}; + +struct string_substitution *new_substituter() +{ + struct string_substitution *new = calloc_or_die(1, sizeof(struct string_substitution)); + new->substitution_strings = new_hash_table(); + new->integer_patterns = new_hash_table(); + new->keys = new_string_array(); + return new; +} + + +void set_integer_pattern(struct string_substitution *substituter, const char *key, const char *pattern) +{ + if (substituter == NULL) { + log_message(LOG_ERROR, "%s: substituter == NULL", __func__); + exit(EXIT_FAILURE); + } + bdc_ht_add_string(substituter->integer_patterns, key, pattern); +} + +void add_substitution_integer(struct string_substitution *substituter, const char *key, int32_t initial_value) +{ + if (substituter == NULL) { + log_message(LOG_ERROR, "%s: substituter == NULL", __func__); + exit(EXIT_FAILURE); + } + + char *default_pattern = "%d"; + char *pattern = NULL; + char *loaded_pattern = NULL; + bdc_ht_get_string_from_key(substituter->integer_patterns, key, &loaded_pattern); + if (!loaded_pattern) { + pattern = default_pattern; + + } else { + pattern = loaded_pattern; + } + + char *value = NULL; + int rc = asprintf(&value, pattern, initial_value); + asprintf_check(rc); + add_substitution(substituter, key, value); + free(value); + free(loaded_pattern); +} + + + + + +void add_substitution(struct string_substitution *substituter, const char *key, const char *initial_value) +{ + if (!bdc_key_in_hash_table(substituter->substitution_strings, key)) { + string_array_add(substituter->keys, key); + } + + bdc_ht_add_string(substituter->substitution_strings, key, initial_value); +} + +char *substitute_string(const char *string, const struct string_substitution *substituter) +{ + if (substituter == NULL) { + log_message(LOG_ERROR, "%s: substituter == NULL", __func__); + exit(EXIT_FAILURE); + } + if (substituter->keys == NULL) { + log_message(LOG_ERROR, "%s: substituter invalid, keys = NULL", __func__); + exit(EXIT_FAILURE); + } + log_message(LOG_INFO, "substituting string '%s' with %d potential substitutions", string, get_string_count(substituter->keys)); + const int count = get_string_count(substituter->keys); + char *copy = strdup(string); + char *result = strdup(string); + for (int i = 0; i < count; i++) { + const char *key = get_string(substituter->keys, i); + char *value = NULL; + bool found = bdc_ht_get_string_from_key(substituter->substitution_strings, key, &value); + if (! found) { + continue; + } + free(result); + result = replace_substring(copy, key, value); + free(copy); + copy = strdup(result); + + + } + free(copy); + return result; +} + +void destroy_substituter(struct string_substitution **substituter) +{ + if (substituter == NULL || *substituter == NULL) return; + struct string_substitution *s = *substituter; + free_string_array(&s->keys); + destroy_hash_table(&s->substitution_strings); + destroy_hash_table(&s->integer_patterns); + free(s); + *substituter = NULL; + +} + +struct string_substitution *copy_substituter(const struct string_substitution *from) +{ + if (from == NULL) return NULL; + struct string_substitution *to = new_substituter(); + const struct string_array *keys = from->keys; + const int32_t count = get_string_count(keys); + for (int32_t i = 0; i< count; i++) { + const char *key = get_string(keys, i); + char *value = NULL; + bdc_ht_get_string_from_key(from->substitution_strings, key, &value); + if (value) { + add_substitution(to, key, value); + } + bdc_ht_get_string_from_key(from->integer_patterns, key, &value); + if (value) { + set_integer_pattern(to, key, value); + } + + } + + return to; +} \ No newline at end of file diff --git a/libbdc/bdc_time/bdc_time.c b/libbdc/bdc_time/bdc_time.c index 41bc4a6da3f07010050648f2a3d1563b80a99b31..2d7908c6dc53cef1a10ab80f0350dbcc0faa5862 100644 --- a/libbdc/bdc_time/bdc_time.c +++ b/libbdc/bdc_time/bdc_time.c @@ -1,25 +1,23 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * - * bdc_time.c - * - * Copyright (C) 2011-2022, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_time.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// #include <time.h> #include <stdio.h> diff --git a/libbdc/bdc_time/bdc_time.h b/libbdc/bdc_time/bdc_time.h index 68ff82626a726d3e74142093c81ecad47158de97..d8f822726f0224b3f3a1c2ccb828ee4c67d8f60a 100644 --- a/libbdc/bdc_time/bdc_time.h +++ b/libbdc/bdc_time/bdc_time.h @@ -1,25 +1,23 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * - * bdc_time.h - * - * Copyright (C) 2011-2022, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_time.h +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// #ifndef BDC_TIME_H #define BDC_TIME_H diff --git a/libbdc/bdc_time/bdc_timer.c b/libbdc/bdc_time/bdc_timer.c index 321951d39041ea12dcb20500357f0fa5261b037c..2a147c211b09f2e11fbc794ed1ecb6d4851adc8c 100644 --- a/libbdc/bdc_time/bdc_timer.c +++ b/libbdc/bdc_time/bdc_timer.c @@ -1,3 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// bdc_timer.c +// +// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + #include <assert.h> #include <stdlib.h> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee838a3dbcd34a8adf2d1919a0445bdf80e93a0e..423f4c71f61cc0965ab519536d3f2b765ba76ed5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,5 @@ -add_subdirectory(logging) + add_subdirectory(cats) -add_subdirectory(cats_strings) add_subdirectory(cats_ini) add_subdirectory(cats_csv) add_subdirectory(modules/cats_test_module) diff --git a/src/cats/CMakeLists.txt b/src/cats/CMakeLists.txt index 66572ef47e0c98811b0a72b89bc8b53880826e49..ff9fab8605001c6f6591178ab168dc1a5b98d451 100644 --- a/src/cats/CMakeLists.txt +++ b/src/cats/CMakeLists.txt @@ -318,15 +318,15 @@ set(CATS_SOURCES_MPI ) add_executable(cats cats.c) -target_link_libraries(libcats cats_logging bdc cats_strings cats_ini cats_csv) -target_link_libraries(cats libcats cats_logging bdc cats_strings cats_ini cats_csv) +target_link_libraries(libcats bdc_logging bdc bdc_strings cats_ini cats_csv) +target_link_libraries(cats libcats bdc_logging bdc bdc_strings cats_ini cats_csv) if (MSVC) # target_include_directories(cats PRIVATE ${GDAL_INCLUDE_DIRS}) - # target_link_libraries(cats cats_logging cats_memory cats_strings cats_ini cats_csv ${GDAL_LIBRARIES}) + # target_link_libraries(cats bdc_logging bdc_memory bdc_strings cats_ini cats_csv ${GDAL_LIBRARIES}) else () - target_link_libraries(cats cats_logging bdc cats_strings cats_ini cats_csv) + target_link_libraries(cats bdc_logging bdc bdc_strings cats_ini cats_csv) endif () @@ -334,7 +334,7 @@ if (MPI_FOUND) add_executable(cats-mpi cats.c ${CATS_SOURCES_MPI}) - target_link_libraries(cats-mpi ${MPI_C_LIBRARIES} cats_logging bdc_memory cats_strings cats_ini cats_csv libcats) + target_link_libraries(cats-mpi ${MPI_C_LIBRARIES} bdc_logging bdc_memory bdc_strings cats_ini cats_csv libcats) target_compile_options(cats-mpi PRIVATE -DUSEMPI) diff --git a/src/cats/actions/setup_actions.c b/src/cats/actions/setup_actions.c index e3a1539c9cd1e45246f03c3c12a57cdc5b0e260e..274d8a68c078bf0619680be0d09b1afa97fea9d8 100644 --- a/src/cats/actions/setup_actions.c +++ b/src/cats/actions/setup_actions.c @@ -28,7 +28,7 @@ #include "actions/setup_actions.h" #include "actions/cats_actions.h" #include "actions/process_inter_period_survival.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "dispersal/dispersal.h" #include "bdc_memory/bdc_memory.h" diff --git a/src/cats/cats.c b/src/cats/cats.c index a0d5a4fbacaf4079b1d73695362a0363356697ee..d2c14b367a7d5115dc935fba55af221cef26622b 100644 --- a/src/cats/cats.c +++ b/src/cats/cats.c @@ -31,7 +31,7 @@ #include "cats_global.h" #include <cats_ini/cats_ini.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "cats/command_line/command_line_info.h" #include "cats/command_line/command_line_options.h" diff --git a/src/cats/command_line/command_line_info.c b/src/cats/command_line/command_line_info.c index 779d32ea3c3ef7067eae1e9263b902cb4df88c7b..fb3b6995b5e2f70f84f270e7b4217e03f209a646 100644 --- a/src/cats/command_line/command_line_info.c +++ b/src/cats/command_line/command_line_info.c @@ -24,7 +24,7 @@ #include "vital_rates/vital_rates_helper.h" #include "command_line_options.h" #include "command_line_info.h" -#include "logging/logging.h" +#include "bdc_logging/logging.h" #include "cats_ini/cats_ini.h" #include "defaults.h" #include "cats_global.h" diff --git a/src/cats/command_line/command_line_options.h b/src/cats/command_line/command_line_options.h index df6924e7e08482f941b3135f174bc7f0406caf17..35f4287da9304452f03f24b72b53e79f473712c3 100644 --- a/src/cats/command_line/command_line_options.h +++ b/src/cats/command_line/command_line_options.h @@ -25,7 +25,7 @@ #include <getopt.h> #include <stdlib.h> #include <stdbool.h> -#include "logging/logging.h" +#include "bdc_logging/logging.h" #include "cats_global.h" @@ -114,7 +114,7 @@ struct program_options { bool lambda_test; enum cats_debug_flags debug_flags; - enum cats_log_level default_log_level; + enum bdc_log_level default_log_level; bool show_unused_config_values; bool show_unspecified_config_values; bool have_poisson_dampening_factor; diff --git a/src/cats/configuration/load_config_spatial.c b/src/cats/configuration/load_config_spatial.c index 6fed7296b5057f9b9b1ae0ccffa249a0c5fc2277..fa9ae72e37a55c2df8ebd3c415bf59500b4cac6b 100644 --- a/src/cats/configuration/load_config_spatial.c +++ b/src/cats/configuration/load_config_spatial.c @@ -25,7 +25,7 @@ #include "misc/misc.h" #include "logging.h" #include "cats_ini/cats_ini.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "load_configuration_temporal.h" #include "paths/paths.h" #include "grids/gdal_helper.h" @@ -34,7 +34,7 @@ void load_simulation_geometry_from_initial_population(struct cats_configuration *conf, struct cats_ini *ini) { struct string_array *species_sections = get_sections_with_prefix(ini, "species"); - if (species_sections->count == 0) { + if (get_string_count(species_sections) == 0) { log_message(LOG_ERROR, "%s: could not load any species information", __func__); exit_cats(EXIT_FAILURE); } @@ -53,9 +53,9 @@ void load_simulation_geometry_from_initial_population(struct cats_configuration } char *file_name = NULL; bool load_ini_pop = ! conf->command_line_options.no_input_rasters_required; - for (int32_t i = 0; i < species_sections->count; i++) { - char *species_section = species_sections->string[i]; - + size_t count = get_string_count(species_sections); + for (int32_t i = 0; i < count; i++) { + const char *species_section = get_string(species_sections, i); load_conf_value(load_ini_pop, ini, species_section, "initial population filename", &file_name); // VR::ignored:: break; } diff --git a/src/cats/configuration/load_configuration.c b/src/cats/configuration/load_configuration.c index e312c92b70dfe218f895318fc46ce6d950ca75c0..7b768adc9af1a909ae37ce70c73d465a8b4c236f 100644 --- a/src/cats/configuration/load_configuration.c +++ b/src/cats/configuration/load_configuration.c @@ -25,7 +25,7 @@ #include <assert.h> #include <cats_ini/cats_ini.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #ifdef USEMPI #include "mpi/mpi_cats.h" @@ -48,6 +48,7 @@ #include "load_configuration_modules.h" #include "test/test_ini.h" #include "debug/debug_vital_rates.h" +#include "bdc_io/bdc_io.h" void load_configuration_elements(struct cats_configuration *conf, struct cats_ini *ini); diff --git a/src/cats/configuration/load_configuration_dispersal.c b/src/cats/configuration/load_configuration_dispersal.c index 045df971bb8ea10e2017ed6801136c05d2bdc80b..d1808817077f889ac2dde754454e7f66b061a0ee 100644 --- a/src/cats/configuration/load_configuration_dispersal.c +++ b/src/cats/configuration/load_configuration_dispersal.c @@ -26,8 +26,8 @@ #include <string.h> #include <stdbool.h> -#include <logging/logging.h> -#include <cats_strings/cats_strings.h> +#include <bdc_logging/logging.h> +#include <bdc_strings/bdc_strings.h> #include "data/species_parameters.h" #include "load_configuration_helper.h" @@ -42,10 +42,13 @@ bool load_dispersal_info(struct cats_configuration *conf, struct cats_ini *ini, struct string_array *prob_min = get_char_array_from_conf2(ini, dispersal_section, "minimum weights"); struct string_array *prob_max = get_char_array_from_conf2(ini, dispersal_section, "maximum weights"); - if (!((file_names->count == prob_min->count) && (file_names->count == prob_max->count))) { + if (!((get_string_count(file_names) == get_string_count(prob_min)) && + (get_string_count(file_names) == get_string_count(prob_max)))) { log_message(LOG_ERROR, "CONF: count mismatch: %d file names, %d minimum weights, " - "%d maximum weights. Expected all counts to be equal.", file_names->count, - prob_min->count, prob_max->count); + "%d maximum weights. Expected all counts to be equal.", + get_string_count(file_names), + get_string_count(prob_min), + get_string_count(prob_max)); exit(EXIT_FAILURE); } @@ -64,20 +67,20 @@ bool load_dispersal_info(struct cats_configuration *conf, struct cats_ini *ini, dispersal->long_range_enabled = true; } - for (int32_t i = 0; i < file_names->count; i++) { + for (int32_t i = 0; i <get_string_count(file_names); i++) { dispersal->types[i] = DISPERSAL_KERNEL; - bool pmin_succ = string_to_long_double(prob_min->string[i], &pmin); - bool pmax_succ = string_to_long_double(prob_max->string[i], &pmax); + bool pmin_succ = string_to_long_double(get_string(prob_min, i), &pmin); + bool pmax_succ = string_to_long_double(get_string(prob_min, i), &pmax); if (pmin_succ == false || pmax_succ == false) { log_message(LOG_ERROR, "CONF: error reading minimum and maximum probability: " "'%s' and '%s'", - prob_min->string[i], prob_max->string[i]); + get_string(prob_min, i), get_string(prob_min, i)); exit(EXIT_FAILURE); } - if (file_names->count > i && file_names->string[i]) { - dispersal->filenames[i] = strdup(file_names->string[i]); + if (get_string_count(file_names) > i && get_string(file_names, i)) { + dispersal->filenames[i] = strdup(get_string(file_names, i)); } if ((pmax >= 0 && pmax <= 1.0 && pmin >= 0 && pmin <= 1.0 && pmax >= pmin) || diff --git a/src/cats/configuration/load_configuration_environments.c b/src/cats/configuration/load_configuration_environments.c index 08f0f70ff73125cee770102111959888435992ca..94cc25eb4a5c89e4dd9d7ff11f81f73199eac759 100644 --- a/src/cats/configuration/load_configuration_environments.c +++ b/src/cats/configuration/load_configuration_environments.c @@ -42,7 +42,7 @@ enum environment_variable_type get_environment_variable_type_from_string(const c } -void add_environment_variable_from_conf(struct cats_configuration *conf, struct cats_ini *ini, char *environment_section) +void add_environment_variable_from_conf(struct cats_configuration *conf, struct cats_ini *ini, const char *environment_section) { struct array_dimension *dimension = &conf->geometry.dimension; char *name = remove_0th_token(environment_section, ":"); @@ -126,14 +126,16 @@ void load_environments_configuration(struct cats_configuration *conf, struct cat //struct string_array *suitability_variables = get_sections_with_prefix(ini, "suitability"); struct string_array *glms = get_sections_with_prefix(ini, "glm"); + size_t count = get_string_count(env_variables); + for (int32_t i = 0; i < count; i++) { - for (int32_t i = 0; i < env_variables->count; i++) { - add_environment_variable_from_conf(conf, ini, env_variables->string[i]); + add_environment_variable_from_conf(conf, ini, get_string(env_variables, i)); } - - for (int32_t i = 0; i < glms->count; i++) { - add_glm_from_conf(conf, ini, glms->string[i]); + count = get_string_count(glms); + for (int32_t i = 0; i < count; i++) { + char *name = strdup(get_string(glms, i)); // FIXME, make add_glm_from_conf argument const + add_glm_from_conf(conf, ini, name); } diff --git a/src/cats/configuration/load_configuration_glm.c b/src/cats/configuration/load_configuration_glm.c index d5d1745ab743f81fc19ec3901e548c046915af03..3c234a32a83e6c2ddcc0ae3604d63b182829eb7a 100644 --- a/src/cats/configuration/load_configuration_glm.c +++ b/src/cats/configuration/load_configuration_glm.c @@ -115,14 +115,14 @@ void add_glm_from_conf(struct cats_configuration *conf, struct cats_ini *ini, ch } struct glm_params glm = {0}; struct string_array *predictors = get_char_array_from_conf2(ini, environment_section, "predictors"); - if (predictors->count == 0) { + if (get_string_count(predictors) == 0) { log_message(LOG_ERROR, "%s: section [%s] does not contain any predictor names", __func__, environment_section); exit_cats(EXIT_FAILURE); } - if (predictors->count > MAX_ENVIRONMENTS) { + if (get_string_count(predictors) > MAX_ENVIRONMENTS) { log_message(LOG_ERROR, "%s: section [%s]: more predictors (%d) found than the allowed maximum %d", __func__, environment_section, - predictors->count, MAX_ENVIRONMENTS); + get_string_count(predictors), MAX_ENVIRONMENTS); exit_cats(EXIT_FAILURE); } enum environment_type type = get_environment_glm_type(type_name); @@ -142,15 +142,15 @@ void add_glm_from_conf(struct cats_configuration *conf, struct cats_ini *ini, ch free(family_name); - for (int32_t i = 0; i < predictors->count; i++) { - get_environment_from_registry(&conf->environment_registry, predictors->string[i]); - char *predictor_linear = compound_string(predictors->string[i], "linear", " "); + for (int32_t i = 0; i < get_string_count(predictors); i++) { + get_environment_from_registry(&conf->environment_registry, get_string(predictors,i)); + char *predictor_linear = compound_string(get_string(predictors, i), "linear", " "); load_conf_value(true, ini, environment_section, predictor_linear, &glm.linear[i]); free(predictor_linear); glm.count += 1; if (glm.type == GLM_QUADRATIC) { - char *predictor_quadratic = compound_string(predictors->string[i], "quadratic", " "); + char *predictor_quadratic = compound_string(get_string(predictors, i), "quadratic", " "); load_conf_value(true, ini, environment_section, predictor_quadratic, &glm.quadratic[i]); free(predictor_quadratic); } @@ -160,9 +160,9 @@ void add_glm_from_conf(struct cats_configuration *conf, struct cats_ini *ini, ch struct cats_environment *set = add_environment(conf, name, type, &glm); load_conf_value(false, ini, environment_section, "save environment", &set->save_environment); - for (int32_t i = 0; i < predictors->count; i++) { + for (int32_t i = 0; i < get_string_count(predictors); i++) { struct cats_environment_variable *env = get_environment_from_registry(&conf->environment_registry, - predictors->string[i]); + get_string(predictors, i)); add_to_environment(set, env); } diff --git a/src/cats/configuration/load_configuration_helper.c b/src/cats/configuration/load_configuration_helper.c index 2e9375712b0aae95a2e40057c6f957a48ec965ff..ee3c4527710f651f9377dbfa03fe1a95bf616544 100644 --- a/src/cats/configuration/load_configuration_helper.c +++ b/src/cats/configuration/load_configuration_helper.c @@ -60,7 +60,7 @@ void reset_same_dispersals(bool all_same, struct cats_configuration_counts *coun } -int32_t count_kernel_dispersal_for_species(struct cats_ini *ini, char *species_section) +int32_t count_kernel_dispersal_for_species(struct cats_ini *ini, const char *species_section) { int32_t dispersal_count = 0; char *dispersal_name = NULL; @@ -77,14 +77,14 @@ int32_t count_kernel_dispersal_for_species(struct cats_ini *ini, char *species_s struct string_array *dispersal_kernel_filenames = get_char_array_from_conf2(ini, dispersal_section_name, "kernel filenames"); - if (!dispersal_kernel_filenames->count) { + if (!get_string_count(dispersal_kernel_filenames)) { log_message(LOG_ERROR, "Error creating configuration structures: could not load dispersal information for species '%s': '%s' [%s]", species_section, dispersal_name, dispersal_section_name); exit_cats(EXIT_FAILURE); } - dispersal_count = dispersal_kernel_filenames->count; + dispersal_count = get_string_count(dispersal_kernel_filenames); free(dispersal_section_name); free_string_array(&dispersal_kernel_filenames); @@ -100,13 +100,13 @@ struct cats_configuration_counts get_counts_from_config(struct cats_ini *ini) // required struct string_array *species = get_sections_with_prefix(ini, "species"); - counts.species = species->count; + counts.species = get_string_count(species); counts.dispersals = new_raw_1d_array(counts.species, sizeof(int)); for (int i = 0; i < counts.species; i++) { - counts.dispersals[i] = count_kernel_dispersal_for_species(ini, species->string[i]); + counts.dispersals[i] = count_kernel_dispersal_for_species(ini, get_string(species, i)); } free_string_array(&species); diff --git a/src/cats/configuration/load_configuration_modules.c b/src/cats/configuration/load_configuration_modules.c index 281d1ebe2d5951d187c2b8c16fcaa159bdeb2f50..bd3c3d7b0291968f2cda02ca97aaedc25d23ceaf 100644 --- a/src/cats/configuration/load_configuration_modules.c +++ b/src/cats/configuration/load_configuration_modules.c @@ -29,9 +29,9 @@ void load_configuration_modules(struct cats_configuration *conf, struct cats_ini *ini) { struct string_array *modules = get_sections_with_prefix(ini, "module"); - for (int32_t i = 0; i < modules->count; i++) { + for (int32_t i = 0; i < get_string_count(modules); i++) { - char *module_section = modules->string[i]; + const char *module_section = get_string(modules, i); char *name = remove_0th_token(module_section, ":"); if (i >= MAX_MODULES) { log_message(LOG_ERROR, "too many modules, limit is %d", MAX_MODULES); diff --git a/src/cats/configuration/load_configuration_overlays.c b/src/cats/configuration/load_configuration_overlays.c index 31fe1d7e9878273c70ccd1f6e1645dba8f2b26e6..f48163d2bbf498b9f81884343205b84a7f9655fd 100644 --- a/src/cats/configuration/load_configuration_overlays.c +++ b/src/cats/configuration/load_configuration_overlays.c @@ -24,8 +24,8 @@ #include <string.h> #include <math.h> -#include <logging/logging.h> -#include <cats_strings/cats_strings.h> +#include <bdc_logging/logging.h> +#include <bdc_strings/bdc_strings.h> #include "load_configuration_overlays.h" #include "overlays/overlay_habitat_type_cc.h" #include "grids/grid_setup.h" @@ -36,15 +36,15 @@ void load_overlay_configuration(struct cats_configuration *conf, struct cats_ini if (conf->command_line_options.no_input_rasters_required) return; struct string_array *overlay_names = get_sections_with_prefix(ini, "overlay"); - for (int32_t i = 0; i < overlay_names->count; i++) { - char *overlay_section = overlay_names->string[i]; + for (int32_t i = 0; i < get_string_count(overlay_names); i++) { + const char *overlay_section = get_string(overlay_names, i); bool enabled = true; load_conf_value(false, ini, overlay_section, "enabled", &enabled); if (enabled == false) { continue; } - char *overlay_name = remove_0th_token(overlay_names->string[i], ":"); + char *overlay_name = remove_0th_token(get_string(overlay_names, i), ":"); char *type_name = NULL; diff --git a/src/cats/configuration/load_configuration_species_params.c b/src/cats/configuration/load_configuration_species_params.c index a7418dde57b2746150b0e7dbf16f2dd21bbe6807..ec3ce4edb5cf392e76ed3fd109d3fd9d0c584d7d 100644 --- a/src/cats/configuration/load_configuration_species_params.c +++ b/src/cats/configuration/load_configuration_species_params.c @@ -30,7 +30,7 @@ #include "bdc_memory/bdc_memory.h" #include <cats_ini/cats_ini.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "configuration/configuration.h" #include "load_configuration_dispersal.h" @@ -46,7 +46,7 @@ enum sexuality_type get_sexuality_from_string(const char *string) } -void preload_default_vital_rates_for_presets(struct cats_configuration *conf, struct cats_ini *ini, char *species_section, +void preload_default_vital_rates_for_presets(struct cats_configuration *conf, struct cats_ini *ini, const char *species_section, struct cats_species_param *p) { // load values that could be used for presets -- e.g. some presets could depend on these values @@ -62,7 +62,7 @@ void preload_default_vital_rates_for_presets(struct cats_configuration *conf, st } -void preload_default_vital_ages_for_presets(struct cats_configuration *conf, struct cats_ini *ini, char *species_section, +void preload_default_vital_ages_for_presets(struct cats_configuration *conf, struct cats_ini *ini, const char *species_section, struct cats_species_param *p) { for (enum cats_vital_age_id age_id = VA_MIN + 1; age_id < VA_MAX; age_id++) { @@ -73,7 +73,7 @@ void preload_default_vital_ages_for_presets(struct cats_configuration *conf, str } -void load_conf_vital_ages(struct cats_configuration *conf, struct cats_ini *ini, char *species_section, +void load_conf_vital_ages(struct cats_configuration *conf, struct cats_ini *ini, const char *species_section, struct cats_species_param *p) { for (enum cats_vital_age_id age_id = VA_MIN + 1; age_id < VA_MAX; age_id++) { @@ -125,7 +125,7 @@ void load_conf_vital_rate(struct cats_vital_rate *vr, struct cats_configuration void load_plant_species_parameter(struct cats_configuration *conf, struct cats_ini *ini, - char *species_name, struct cats_species_param *p) + const char *species_name, struct cats_species_param *p) { char *preset_string = NULL; @@ -182,7 +182,7 @@ void load_plant_species_parameter(struct cats_configuration *conf, struct cats_i void load_config_species_parameter(struct cats_configuration *conf, struct cats_ini *ini, int species_idx, - char *species_section) + const char *species_section) { struct cats_species_param *p = &conf->param[species_idx]; @@ -290,7 +290,7 @@ void load_config_species_parameter(struct cats_configuration *conf, struct cats_ } -void load_parameter_sets_all_same(struct cats_configuration *conf, struct cats_ini *ini, int species_idx, char *name) +void load_parameter_sets_all_same(struct cats_configuration *conf, struct cats_ini *ini, int species_idx, const char *name) { assert(species_idx >= 0); char *species_name = strdup(conf->param[0].species_name); @@ -313,8 +313,8 @@ void load_all_species(struct cats_configuration *conf, struct cats_ini *ini) { struct string_array *species = get_sections_with_prefix(ini, "species"); - for (int32_t i = 0; i < species->count; i++) { - char *species_section = species->string[i]; + for (int32_t i = 0; i < get_string_count(species); i++) { + const char *species_section = get_string(species, i); load_config_species_parameter(conf, ini, i, species_section); if (conf->all_species_same && i == 0) { diff --git a/src/cats/data/cats_datatypes.c b/src/cats/data/cats_datatypes.c index c311e402cf4b5f2158e07de5fb190bcb2c7fb0ad..06624c3f9415516e8ead6192a02a471f4b72a335 100644 --- a/src/cats/data/cats_datatypes.c +++ b/src/cats/data/cats_datatypes.c @@ -35,7 +35,7 @@ const char *false_values[] = {"0", "n", "f"}; const int true_counts = (int) (sizeof(true_values) / sizeof(char *)); const int false_counts = (int) (sizeof(false_values) / sizeof(char *)); - +/* bool string_to_double(char *string, double *value) { if (string == NULL || strlen(string) == 0) return false; @@ -149,5 +149,5 @@ bool string_to_integer(char *string, int32_t *value) } return false; } - +*/ diff --git a/src/cats/data/cats_datatypes.h b/src/cats/data/cats_datatypes.h index d2bba5466e47223b70793c29c3c30a8da695e390..eea745469db26eb2c80f128ffd223b5811db2c23 100644 --- a/src/cats/data/cats_datatypes.h +++ b/src/cats/data/cats_datatypes.h @@ -58,6 +58,6 @@ struct cats_coordinates { // conversion functions -#include <cats_strings/string_converters.h> +#include <bdc_strings/bdc_strings.h> #endif \ No newline at end of file diff --git a/src/cats/data/cats_global.c b/src/cats/data/cats_global.c index d3a574978bda439c226640c80d2ed34b690a8f0b..977f3e3296a1209e7e20a1e5041e701f458dabb1 100644 --- a/src/cats/data/cats_global.c +++ b/src/cats/data/cats_global.c @@ -24,7 +24,7 @@ #include "misc/misc.h" #include "defaults.h" #include "bdc_memory/bdc_memory.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include <stdlib.h> diff --git a/src/cats/data/simulation_geometry.c b/src/cats/data/simulation_geometry.c index ed9e0b14fe8659c2876789622156f3cdd0ef6555..9959d15cadfbd2679c41ee2475caced2740b611c 100644 --- a/src/cats/data/simulation_geometry.c +++ b/src/cats/data/simulation_geometry.c @@ -23,7 +23,7 @@ #include "cats_global.h" #include <math.h> #include "simulation_geometry.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> void init_simulation_geometry(struct simulation_geometry *geo) { diff --git a/src/cats/debug/debug.c b/src/cats/debug/debug.c index ebe381a57c45c402db821cb9d3a75fa58db646f9..b924064d8307e46b61885504b95e7849eadf5bbb 100644 --- a/src/cats/debug/debug.c +++ b/src/cats/debug/debug.c @@ -24,8 +24,9 @@ #include "bdc_memory/bdc_memory.h" #include "debug/debug.h" #include "threading/threading-helpers.h" -#include <cats_strings/cats_strings.h> +#include <bdc_strings/bdc_strings.h> #include "misc/misc.h" +#include "bdc_io/bdc_io.h" #define DEBUG_DIR "debug" diff --git a/src/cats/debug/debug_vital_rates.c b/src/cats/debug/debug_vital_rates.c index ca9da40274bbe54f90f692b0b6daea0a60d91f7e..996e31e8b6ddf2509b067f924446760599a56651 100644 --- a/src/cats/debug/debug_vital_rates.c +++ b/src/cats/debug/debug_vital_rates.c @@ -26,6 +26,7 @@ #include "inline_carrying_capacity.h" #include "grids/grid_setup.h" #include "paths/directory_helper.h" +#include "bdc_io/bdc_io.h" struct cats_environment *minimal_suitability_environment(void) diff --git a/src/cats/environment/environment.c b/src/cats/environment/environment.c index 353a79783c1cd82b153359f0680f06f7ff19be5e..04d0ae375dfdd8e5299a07bd387baecd6a209649 100644 --- a/src/cats/environment/environment.c +++ b/src/cats/environment/environment.c @@ -26,7 +26,7 @@ #endif #include <assert.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "configuration/configuration.h" #include "memory.h" diff --git a/src/cats/environment/environment_registry.c b/src/cats/environment/environment_registry.c index fa1f606830009413903de358d4d29dedf73d1a14..d2208b75dca4ba6e9dc09ebd4259ac0de6e0c09e 100644 --- a/src/cats/environment/environment_registry.c +++ b/src/cats/environment/environment_registry.c @@ -25,7 +25,7 @@ #include <limits.h> #include "environment/environment_structures.h" #include "bdc_memory/bdc_memory.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> void reset_environment_registry(struct cats_environment_registry *reg) { @@ -125,10 +125,10 @@ add_environment_to_registry(struct cats_environment_registry *registry, const ch } -struct cats_environment_variable *get_environment_from_registry(struct cats_environment_registry *reg, char *name) +struct cats_environment_variable *get_environment_from_registry(struct cats_environment_registry *reg, const char *name) { - int32_t idx = string_array_index(reg->name, name); + int32_t idx = string_array_string_index(reg->name, name); if (idx < 0) { log_message(LOG_ERROR, "%s: could not find environment '%s' in registry.", __func__, name); exit(EXIT_FAILURE); @@ -148,7 +148,7 @@ void cleanup_environment_registry(struct cats_environment_registry *reg) { for (int32_t i = 0; i < reg->count; i++) { - log_message(LOG_INFO, "%s: cleaning up %s", __func__, reg->name->string[i]); + log_message(LOG_INFO, "%s: cleaning up %s", __func__, get_string(reg->name, i)); cleanup_cats_environment_variable(®->environment[i]); } diff --git a/src/cats/environment/environment_registry.h b/src/cats/environment/environment_registry.h index 1d4680f2160cc46b354b6d2dd67ebf41671ad086..e5a810dc25cf48dc24bfdd6da175df5e4050d87b 100644 --- a/src/cats/environment/environment_registry.h +++ b/src/cats/environment/environment_registry.h @@ -38,7 +38,7 @@ add_environment_to_registry(struct cats_environment_registry *registry, const ch enum environment_variable_type type, const char *file_name_pattern, int32_t reload_interval, int32_t interpolation, const struct array_dimension *dimension); -struct cats_environment_variable *get_environment_from_registry(struct cats_environment_registry *reg, char *name); +struct cats_environment_variable *get_environment_from_registry(struct cats_environment_registry *reg, const char *name); void cleanup_environment_registry(struct cats_environment_registry *reg); diff --git a/src/cats/environment/environment_set.c b/src/cats/environment/environment_set.c index 7e5f6b0662ebd9f4e8fb14169b6220304fc7ca51..c0d34ea4f12ea5e20cc1afbd76cc7f87f7c5e172 100644 --- a/src/cats/environment/environment_set.c +++ b/src/cats/environment/environment_set.c @@ -177,12 +177,12 @@ void add_to_environment(struct cats_environment *environment, struct cats_enviro void failed_to_find_environment(const struct cats_configuration *conf, const char *name) { log_message(LOG_ERROR, "%s: could not find environment set '%s' in registry", __func__, name); - if (conf->environment.names == NULL || conf->environment.names->count == 0) { + if (conf->environment.names == NULL || get_string_count(conf->environment.names) == 0) { log_message(LOG_ERROR, "%s: registry empty ('%s')", __func__, name); } else { - for (int32_t i = 0; i < conf->environment.names->count; i++) { + for (int32_t i = 0; i < get_string_count(conf->environment.names); i++) { log_message(LOG_INFO, "%s: have registry entry: '%s'", __func__, - conf->environment.names->string[i]); + get_string(conf->environment.names, i)); } } @@ -193,10 +193,10 @@ void failed_to_find_environment(const struct cats_configuration *conf, const cha struct cats_environment *get_environment(const struct cats_configuration *conf, const char *name) { - if (conf->environment.names == NULL || conf->environment.names->count == 0) { + if (conf->environment.names == NULL || get_string_count(conf->environment.names) == 0) { failed_to_find_environment(conf, name); } - int32_t idx = string_array_index(conf->environment.names, name); + int32_t idx = string_array_string_index(conf->environment.names, name); if (idx < 0) failed_to_find_environment(conf, name); diff --git a/src/cats/environment/load_environment.c b/src/cats/environment/load_environment.c index c1324c5583a68fa3d4859be34a9db7bab54c862b..f9119cfd94ec26852f0fcf1e26aae176435cb32b 100644 --- a/src/cats/environment/load_environment.c +++ b/src/cats/environment/load_environment.c @@ -76,7 +76,7 @@ enum action_status update_environment_warmup(struct cats_configuration *conf, in time); } else if (time == start) { log_message(LOG_INFO, " ENV: loading environment %s for year %d as static predictor", - conf->environment_registry.name->string[i], + get_string(conf->environment_registry.name, i), time); load_environment_raster(conf, &conf->environment_registry.environment[i], INTERPOLATION_CURRENT, time); diff --git a/src/cats/grids/cats_grid.c b/src/cats/grids/cats_grid.c index 9665728c33dee67cfa59c6909ff9b2d944d3d439..882fe5f855fb7c108c7f9fbe2db2bcdc96571041 100644 --- a/src/cats/grids/cats_grid.c +++ b/src/cats/grids/cats_grid.c @@ -55,6 +55,7 @@ #include "paths/output_paths.h" #include "stats/global_stats.h" #include "actions/setup.h" +#include "bdc_io/bdc_io.h" struct cats_grid **create_and_initialize_grids(struct cats_configuration *conf, const int32_t count) diff --git a/src/cats/grids/gdal_helper.c b/src/cats/grids/gdal_helper.c index 403df5601e4fe85ec1911094ce27f14dc515e69d..3ac72218a910e1ce56d5429ac8acbff79f55af4f 100644 --- a/src/cats/grids/gdal_helper.c +++ b/src/cats/grids/gdal_helper.c @@ -26,7 +26,7 @@ #include <cpl_string.h> #include <assert.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "gdal_load.h" #include "configuration/configuration.h" #include "misc/misc.h" @@ -167,7 +167,7 @@ void verify_raster_geometry(GDALDatasetH dataset, struct simulation_geometry *ge log_message(LOG_INFO, "GEOM: global projection string not set, ignoring projection '%s'", projection); } else { if (strcmp(projection, geometry->projection_string) != 0) { - enum cats_log_level ll; + enum bdc_log_level ll; if (geometry->ignore_raster_projection) { ll = LOG_INFO; } else { diff --git a/src/cats/hybrid/scalefactor.c b/src/cats/hybrid/scalefactor.c index 040be9f7dbd824be3c3c3fafad4801e064e177fc..f1c8563617f8e1973c06366b3aa8daeb8a4a1098 100644 --- a/src/cats/hybrid/scalefactor.c +++ b/src/cats/hybrid/scalefactor.c @@ -29,7 +29,7 @@ #endif #include <cats_ini/cats_ini.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "cats/command_line/command_line_options.h" #include "configuration/load_vital_rates.h" diff --git a/src/cats/inline_population.h b/src/cats/inline_population.h index 20937d8d3b768e025fd73c42f91a824d3b5ba9ab..d52ced908656ef1804655e811a71d2b09cecfad8 100644 --- a/src/cats/inline_population.h +++ b/src/cats/inline_population.h @@ -26,7 +26,7 @@ #include "cats_global.h" #include <math.h> #include "data/cats_datatypes.h" -#include "logging/logging.h" +#include "bdc_logging/logging.h" #include "assert.h" #include "configuration/configuration.h" #include "inline_overlays.h" diff --git a/src/cats/lambda/eigen.c b/src/cats/lambda/eigen.c index 5933034471c6befbd7ff66ba0bb039804957b185..360d20865dd9efbe3cffe22d19cd82e8ab6cb954 100644 --- a/src/cats/lambda/eigen.c +++ b/src/cats/lambda/eigen.c @@ -25,7 +25,7 @@ #include <stdbool.h> #include <math.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "eigen.h" #include "matrix_helpers.h" #include "inline.h" diff --git a/src/cats/lambda/leslie_matrix.c b/src/cats/lambda/leslie_matrix.c index e1a858201b7a2c4c927c5d514f6cf04775b04911..491e7ede62044e9d89b5455e1b8bdba299ed38af 100644 --- a/src/cats/lambda/leslie_matrix.c +++ b/src/cats/lambda/leslie_matrix.c @@ -24,7 +24,7 @@ #include "dispersal/dispersal.h" #include "leslie_matrix.h" #include "bdc_memory/bdc_memory.h" -#include "logging/logging.h" +#include "bdc_logging/logging.h" #include "configuration/configuration.h" #include "inline.h" #include "matrix_helpers.h" diff --git a/src/cats/lambda/matrix_helpers.c b/src/cats/lambda/matrix_helpers.c index c054e992f0a9c06fb3b675d4f1f0ce60360e22d1..e5694b85d4eb0d3caf56f724969000f7a1c200a3 100644 --- a/src/cats/lambda/matrix_helpers.c +++ b/src/cats/lambda/matrix_helpers.c @@ -21,7 +21,7 @@ // #include <assert.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "bdc_memory/bdc_memory.h" #include "cats_global.h" diff --git a/src/cats/misc/debug.c b/src/cats/misc/debug.c index f86e57bcf73aae439cb3d99d0265bdff5a830d02..5a92ff63ea3f73df41bd448e359f3cacf2c98672 100644 --- a/src/cats/misc/debug.c +++ b/src/cats/misc/debug.c @@ -24,6 +24,7 @@ #include "misc.h" #include "inline.h" #include "bdc_memory/bdc_memory.h" +#include "bdc_io/bdc_io.h" void diff --git a/src/cats/misc/filesystem.c b/src/cats/misc/filesystem.c index 88de2fcba682fb2c06ca392398d495fdc30d4897..94b63130d3ee68626ec32246080eb4839c85ce96 100644 --- a/src/cats/misc/filesystem.c +++ b/src/cats/misc/filesystem.c @@ -25,7 +25,7 @@ #include <errno.h> #include <string.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "filesystem.h" #include "data/error.h" #ifndef CATS_ON_WINDOWS diff --git a/src/cats/misc/misc.h b/src/cats/misc/misc.h index 2d377fd57a67fc6534b6925fa67b9cb25f81fa8a..6194c37b356a7d9804b6c58078e859b11ff45f35 100644 --- a/src/cats/misc/misc.h +++ b/src/cats/misc/misc.h @@ -24,20 +24,12 @@ #include <string.h> #include "data/error.h" + #define TEXT_DIVIDER "==================================================================================================" const char *cats_version(void); -// this is kept as a macro, so we can print calling function -#define ENSURE_FILE_OPENED(FILE_HANDLE, FILENAME)\ -if (! (FILE_HANDLE))\ -{\ - fprintf(stderr, "ERROR: Couldn't open file %s in %s: %d (%s)\n", FILENAME, __FILE__, __LINE__, __func__);\ - exit(E_UNREADABLE_FILE);\ -} - - void set_program_name(const char *name); #endif \ No newline at end of file diff --git a/src/cats/modules/load_module.c b/src/cats/modules/load_module.c index 6e6d9bf421e15ff1b371d8ff599b715ae5dad27b..7859124baa4749dded0bb5189c33ce33667cf60f 100644 --- a/src/cats/modules/load_module.c +++ b/src/cats/modules/load_module.c @@ -20,7 +20,7 @@ // #include <dlfcn.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include <string.h> #include "configuration/configuration.h" #include "load_module.h" diff --git a/src/cats/modules/modules.c b/src/cats/modules/modules.c index b18d538ea6453f595a0799a9d1bc9a3141b5565d..92ee7f9bb2b3f8e477d2ec20f76665956da8a147 100644 --- a/src/cats/modules/modules.c +++ b/src/cats/modules/modules.c @@ -24,7 +24,7 @@ #include <string.h> #include <stdlib.h> #include "modules.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" void init_cats_module(struct cats_module *module, int32_t id) { diff --git a/src/cats/mpi/mpi_debug.c b/src/cats/mpi/mpi_debug.c index 1570c2c220b55aaf1aeb217d04b3a96c51279dea..b6b423a13921c928173896aad45c81029042ccdc 100644 --- a/src/cats/mpi/mpi_debug.c +++ b/src/cats/mpi/mpi_debug.c @@ -26,6 +26,7 @@ #include "mpi_debug.h" #include "mpi_grid_helpers.h" #include "paths/output_paths.h" +#include "bdc_io/bdc_io.h" char *get_node_name(const struct cats_configuration *conf) diff --git a/src/cats/overlays/overlays.c b/src/cats/overlays/overlays.c index a89b27aa75a005edb3ebb38d9f766912aeddb6cb..c08d061cf482626a35a744b921ba6e0c9e7d322a 100644 --- a/src/cats/overlays/overlays.c +++ b/src/cats/overlays/overlays.c @@ -93,8 +93,8 @@ enum overlay_type get_overlay_type_from_name(const char *name, const struct stri if (!strcmp(name, "resources")) return OL_RESOURCE; if (registered_names != NULL) { - for (int32_t i = 0; i < registered_names->count; i++) { - if (!strcmp(name, registered_names->string[i])) { + for (int32_t i = 0; i < get_string_count(registered_names); i++) { + if (!strcmp(name, get_string(registered_names,i))) { return OL_CUSTOM; } } diff --git a/src/cats/paths/directory_helper.c b/src/cats/paths/directory_helper.c index 80d8c5b4e0aed4626d2dcf5013600fb423860555..6c338405828760d874a60a04127b586bf10c233a 100644 --- a/src/cats/paths/directory_helper.c +++ b/src/cats/paths/directory_helper.c @@ -22,7 +22,7 @@ #include "cats_global.h" #include <string.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "misc/filesystem.h" #include "paths/paths.h" #include "paths/output_paths.h" @@ -32,7 +32,7 @@ bool check_and_create_directory_if_needed(const struct string_array *path) { - if (path == NULL || path->count == 0) { + if (path == NULL || get_string_count(path) == 0) { fprintf(stderr, "Unable to check directory - no path specified\n"); log_message(LOG_ERROR, "\tunable to check directory - no path specified"); exit_cats(E_SYSTEM_ERROR); @@ -94,8 +94,8 @@ void ensure_needed_directories_exist(const struct cats_configuration *conf, cons struct string_array *output = new_string_array_init(conf->output.output_directory); check_and_create_directory_if_needed(output); free_string_array(&output); - for (int32_t i = 0; i < output_dirs->count; i++) { - struct string_array *path = get_output_directory(conf, output_dirs->string[i]); + for (int32_t i = 0; i < get_string_count(output_dirs); i++) { + struct string_array *path = get_output_directory(conf, get_string(output_dirs,i)); check_and_create_directory_if_needed(path); free_string_array(&path); diff --git a/src/cats/paths/output_paths.c b/src/cats/paths/output_paths.c index 08e0fc9c398959da4661ad25a63997fb77736944..47ad4df0936015681e2449f552c5de85d3bb44b2 100644 --- a/src/cats/paths/output_paths.c +++ b/src/cats/paths/output_paths.c @@ -22,7 +22,7 @@ #include <string.h> #include <assert.h> -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "data/cats_grid.h" #include "temporal/phase_names.h" @@ -30,6 +30,7 @@ #include "output_paths.h" #include "paths.h" +#include "bdc_io/bdc_io.h" const char *get_base_output_directory(const struct cats_configuration *conf) diff --git a/src/cats/paths/paths.c b/src/cats/paths/paths.c index 53310ab453a5e7b765296ef5f080108ea660e9a8..56b95deb5e2a2f32c74fc766cbb2994d822fb4d1 100644 --- a/src/cats/paths/paths.c +++ b/src/cats/paths/paths.c @@ -28,7 +28,7 @@ #include "cats_global.h" #include "data/cats_grid.h" #include "configuration/configuration.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "temporal/phase_names.h" @@ -60,7 +60,7 @@ char *assemble_filename(struct string_array *path, struct string_array *filename char *name_string = string_array_paste(filename, filesep); char *result = NULL; - if (path && path->count > 0) { + if (path && get_string_count(path) > 0) { char *path_string = string_array_paste(path, "/"); if (extension && strlen(extension)) { char *fn = compound_string(name_string, extension, "."); diff --git a/src/cats/paths/paths.h b/src/cats/paths/paths.h index b2cfdbc40f1ed4ccfa07a05b6b9ec4c9507ac39e..583ada17fc000a72ea4c8e3ab6598b7b846728b2 100644 --- a/src/cats/paths/paths.h +++ b/src/cats/paths/paths.h @@ -22,7 +22,7 @@ #pragma once #include <stdint.h> -#include <cats_strings/cats_strings.h> +#include <bdc_strings/bdc_strings.h> struct cats_configuration; struct cats_environment_variable; diff --git a/src/cats/paths/paths_suitability.c b/src/cats/paths/paths_suitability.c index d3360fa00fd5f2cecdbf0b81596f43ac0f678b53..37739e6cf13982486dd385b8e1c9e89f911f7a1e 100644 --- a/src/cats/paths/paths_suitability.c +++ b/src/cats/paths/paths_suitability.c @@ -26,6 +26,7 @@ #include "temporal/timeformat.h" #include "data/species_parameters.h" #include "path_patterns.h" +#include "bdc_io/bdc_io.h" char * diff --git a/src/cats/stats/global_stats.c b/src/cats/stats/global_stats.c index a412a8250249b7e44b8a0f4dd089875b85669f04..c7aee12914706c807cb5dfeb2453de498f33369e 100644 --- a/src/cats/stats/global_stats.c +++ b/src/cats/stats/global_stats.c @@ -30,6 +30,7 @@ #include "stats/grid_stats.h" #include "paths/output_paths.h" #include "bdc_memory/bdc_memory.h" +#include "bdc_io/bdc_io.h" #ifdef USEMPI #include "mpi/mpi_stats.h" diff --git a/src/cats/stats/lambda_stats.c b/src/cats/stats/lambda_stats.c index 7f02b8b7a229db96732cec6d3e4c411577f317c6..ee5f5a34368a8086bacaaf29749885ac2fea709d 100644 --- a/src/cats/stats/lambda_stats.c +++ b/src/cats/stats/lambda_stats.c @@ -25,6 +25,7 @@ #include "inline.h" #include "metadata.h" #include "inline_vital_rates.h" +#include "bdc_io/bdc_io.h" FILE * diff --git a/src/cats/stats/statistics.c b/src/cats/stats/statistics.c index c1ed496cbcd5deeafe2bfc58b0744db5231f40d5..1834bfdaa54da16b4155c214d9b8ac6828fb6536 100644 --- a/src/cats/stats/statistics.c +++ b/src/cats/stats/statistics.c @@ -23,7 +23,7 @@ #include <assert.h> #include <stdlib.h> #include "statistics.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "bdc_memory/bdc_memory.h" #include "configuration/configuration.h" diff --git a/src/cats/threading/threading-helpers.c b/src/cats/threading/threading-helpers.c index 0877f6b54d05e7716d0752321462248a68be6850..cdf3e7ad20bd17675a129be72cb49aa77cf4fc68 100644 --- a/src/cats/threading/threading-helpers.c +++ b/src/cats/threading/threading-helpers.c @@ -27,6 +27,8 @@ #include "misc/cats_random.h" #include "stats/grid_stats.h" #include "bdc_memory/bdc_memory.h" +#include "data/error.h" + void create_custom_stats_for_thread(struct statistics *thread_stats, struct statistics *grid_stats) { diff --git a/src/cats/vital_ages/default_vital_ages.c b/src/cats/vital_ages/default_vital_ages.c index bbff02ce684f6ca29ecd2d4e1de0d3849b6fc0c7..f9ce195723cdcc2abed8a8503591ad493a465af6 100644 --- a/src/cats/vital_ages/default_vital_ages.c +++ b/src/cats/vital_ages/default_vital_ages.c @@ -20,7 +20,7 @@ // #include "default_vital_ages.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> const char *get_vital_age_name(enum cats_vital_age_id idx) { diff --git a/src/cats/vital_rates/setup_rates.c b/src/cats/vital_rates/setup_rates.c index 7b738d9ffc6fdfb485bbea8d84e7572c001a52ad..02883ad28173c2d87b8c964f33ec599a0cdf3dfe 100644 --- a/src/cats/vital_rates/setup_rates.c +++ b/src/cats/vital_rates/setup_rates.c @@ -21,7 +21,7 @@ #include <math.h> #include <assert.h> -#include <cats_strings/cats_strings.h> +#include <bdc_strings/bdc_strings.h> #include "logging.h" #include "setup_rates.h" #include "string.h" diff --git a/src/cats/vital_rates/vital_rate_ranges.c b/src/cats/vital_rates/vital_rate_ranges.c index 44451ee91776abd948937deeec0d47a9fb7a6afc..82635a88d03740ec63b7b1865335f6e5293d7bb5 100644 --- a/src/cats/vital_rates/vital_rate_ranges.c +++ b/src/cats/vital_rates/vital_rate_ranges.c @@ -21,7 +21,7 @@ #include <math.h> #include "vital_rate_ranges.h" -#include "logging/logging.h" +#include "bdc_logging/logging.h" int check_vital_rate_hybrid(struct cats_vital_rate *vr) diff --git a/src/cats_csv/CMakeLists.txt b/src/cats_csv/CMakeLists.txt index d3afbbe76e17a53b45f8fd9363045c61138fb5d6..5f055d7c04cd350d447de75f9ce17480ad5a1600 100644 --- a/src/cats_csv/CMakeLists.txt +++ b/src/cats_csv/CMakeLists.txt @@ -13,4 +13,4 @@ target_sources(cats_csv set_property(TARGET cats_csv PROPERTY POSITION_INDEPENDENT_CODE ON) -target_link_libraries(cats_logging bdc cats_strings) \ No newline at end of file +target_link_libraries(bdc_logging bdc bdc_strings) \ No newline at end of file diff --git a/src/cats_csv/cats_csv.c b/src/cats_csv/cats_csv.c index db8cf5940b54461a97ad6fe45a81bbeec08925db..c3d4c2eeb3025b912688ae29b9097bb7a1381e05 100644 --- a/src/cats_csv/cats_csv.c +++ b/src/cats_csv/cats_csv.c @@ -26,8 +26,9 @@ #include <string.h> #include "cats_csv.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> #include "bdc_memory/bdc_memory.h" +#include "bdc_io/bdc_io.h" struct cats_csv *csv_new(char *header_line, int32_t expected_fields) @@ -42,21 +43,21 @@ struct cats_csv *csv_new(char *header_line, int32_t expected_fields) struct string_array *headers = get_all_tokens(header_line, ","); - if (headers->count != expected_fields) { - log_message(LOG_ERROR, "%s: disparity in field count: got %d expected %d\n", __func__, headers->count, + if (get_string_count(headers) != expected_fields) { + log_message(LOG_ERROR, "%s: disparity in field count: got %d expected %d\n", __func__, get_string_count(headers), expected_fields); exit(EXIT_FAILURE); } struct cats_csv *result = malloc_or_die_trace(sizeof(struct cats_csv), __func__); - result->column_count = headers->count; + result->column_count = get_string_count(headers); result->data_row_count = 0; result->data = NULL; result->headers = malloc_or_die_trace(result->column_count * sizeof(char *), __func__); - for (int32_t i = 0; i < headers->count; i++) { - result->headers[i] = strdup(headers->string[i]); + for (int32_t i = 0; i < get_string_count(headers); i++) { + result->headers[i] = strdup(get_string(headers, i)); } free_string_array(&headers); @@ -224,8 +225,8 @@ void csv_add_row(struct cats_csv *csv, char *line) struct string_array *data = get_all_tokens(line, ","); - if (csv->column_count != data->count) { - log_message(LOG_ERROR, "%s: disparity in field count: got %d expected %d\n", __func__, data->count, + if (csv->column_count != get_string_count(data)) { + log_message(LOG_ERROR, "%s: disparity in field count: got %d expected %d\n", __func__, get_string_count(data), csv->column_count); exit(EXIT_FAILURE); } @@ -233,14 +234,14 @@ void csv_add_row(struct cats_csv *csv, char *line) csv->data_row_count = csv->data_row_count + 1; - csv->data = realloc(csv->data, csv->data_row_count * sizeof(char **)); + csv->data = realloc_or_die(csv->data, csv->data_row_count * sizeof(char **)); int32_t row = csv->data_row_count - 1; csv->data[row] = malloc_or_die_trace(fields * sizeof(char *), __func__); for (int32_t i = 0; i < csv->column_count; i++) { - csv->data[row][i] = strdup(data->string[i]); + csv->data[row][i] = strdup(get_string(data,i)); } diff --git a/src/cats_csv/cats_csv.h b/src/cats_csv/cats_csv.h index 08e79fc66fef2023c3e6852124274ebe229085d7..774183fc93c47fbeb03266a8d9e7d66fbb94764a 100644 --- a/src/cats_csv/cats_csv.h +++ b/src/cats_csv/cats_csv.h @@ -24,7 +24,7 @@ #include <stdint.h> #include <stdio.h> -#include <cats_strings/cats_strings.h> +#include <bdc_strings/bdc_strings.h> ///@brief Data structure for simple csv files struct cats_csv { diff --git a/src/cats_ini/CMakeLists.txt b/src/cats_ini/CMakeLists.txt index 8b03aec39edbde74a99e212b9b403c7e09033d1e..3aa7adc109faf55147e34375e43b33f88dd9d7c4 100644 --- a/src/cats_ini/CMakeLists.txt +++ b/src/cats_ini/CMakeLists.txt @@ -18,4 +18,4 @@ target_sources(cats_ini set_property(TARGET cats_ini PROPERTY POSITION_INDEPENDENT_CODE ON) -target_link_libraries(cats_logging cats_strings bdc) +target_link_libraries(bdc_strings bdc_logging bdc) diff --git a/src/cats_ini/cats_ini.c b/src/cats_ini/cats_ini.c index 96f1de8de6735176ad6fc52b36c1b55819561a81..abc937a636a9e26cfd8b1f6adc053c7459031151 100644 --- a/src/cats_ini/cats_ini.c +++ b/src/cats_ini/cats_ini.c @@ -28,8 +28,8 @@ #include <string.h> #include <stddef.h> -#include <cats_strings/cats_strings.h> -#include <logging/logging.h> +#include <bdc_strings/bdc_strings.h> +#include <bdc_logging/logging.h> #include "cats_ini.h" diff --git a/src/cats_ini/cats_ini_helpers.c b/src/cats_ini/cats_ini_helpers.c index 89c1643d46c9c5800ddec28cac50ced189fc4757..4a14df026b77edc04b8603905db6d34b200baa72 100644 --- a/src/cats_ini/cats_ini_helpers.c +++ b/src/cats_ini/cats_ini_helpers.c @@ -25,7 +25,7 @@ #include "cats_ini_helpers.h" #include "cats_ini_write_values.h" #include "misc/misc.h" -#include <logging/logging.h> +#include <bdc_logging/logging.h> void add_complement_value_read(struct cats_ini *ini, char *section, char *key) { diff --git a/src/cats_ini/cats_ini_read_values.c b/src/cats_ini/cats_ini_read_values.c index b12be6878cac1471a74da089492cfadb7a9e1b56..fcc777ad65473a97798b7b77903296052847bea2 100644 --- a/src/cats_ini/cats_ini_read_values.c +++ b/src/cats_ini/cats_ini_read_values.c @@ -22,12 +22,10 @@ #include <assert.h> #include <stdlib.h> #include <string.h> -#include "../logging/logging.h" +#include "bdc_logging/logging.h" #include "cats_ini.h" -#include "../cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "cats_ini_read_values.h" - -#include "../cats_strings/string_helpers.h" #include "cats_ini_helpers.h" #include <stdio.h> diff --git a/src/cats_ini/cats_ini_write_values.c b/src/cats_ini/cats_ini_write_values.c index b99d1be269d89ac4e500e4ece6bbac1fad0d9db2..aa461bb51e6b9bd7043050072ac6baedb11f133f 100644 --- a/src/cats_ini/cats_ini_write_values.c +++ b/src/cats_ini/cats_ini_write_values.c @@ -20,10 +20,9 @@ // #include "cats_ini_helpers.h" -#include "../cats_strings/string_helpers.h" #include "cats_ini.h" -#include "../logging/logging.h" -#include "../cats_strings/cats_strings.h" +#include "bdc_logging/logging.h" +#include "bdc_strings/bdc_strings.h" #include <stddef.h> #include <string.h> #include <stdlib.h> diff --git a/src/cats_strings/CMakeLists.txt b/src/cats_strings/CMakeLists.txt deleted file mode 100644 index 1414340bcf846d1fb3daec3b9570fc1b58f5df98..0000000000000000000000000000000000000000 --- a/src/cats_strings/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_library(cats_strings STATIC "" ../cats_defs.h ../cats_windows.h string_converters.c string_converters.h) - -target_sources(cats_strings - PRIVATE - cats_strings.c - io_text.c - string_helpers.c - pretty_print.c - PUBLIC - cats_strings.h - io_text.h - pretty_print.h - string_helpers.h - ) - -set_property(TARGET cats_strings PROPERTY POSITION_INDEPENDENT_CODE ON) -target_link_libraries(cats_logging bdc_time) \ No newline at end of file diff --git a/src/cats_strings/io_text.h b/src/cats_strings/io_text.h deleted file mode 100644 index 224a71ae574159b2274fae8d0f04a7d671235d15..0000000000000000000000000000000000000000 --- a/src/cats_strings/io_text.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// -// io_text.h -// -// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// - -#ifndef CATS_IO_TEXT_H -#define CATS_IO_TEXT_H - - -#endif diff --git a/src/cats_strings/pretty_print.h b/src/cats_strings/pretty_print.h deleted file mode 100644 index be12b63a789ab371dcd60ff9971b7504b2bad7cf..0000000000000000000000000000000000000000 --- a/src/cats_strings/pretty_print.h +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// -// pretty_print.h -// -// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// - -#ifndef CATS_PRETTY_PRINT_H -#define CATS_PRETTY_PRINT_H - -#endif //CATS_PRETTY_PRINT_H diff --git a/src/cats_strings/string_converters.h b/src/cats_strings/string_converters.h deleted file mode 100644 index b2a8082bfe4693d0656c7a35c9552d9417daee60..0000000000000000000000000000000000000000 --- a/src/cats_strings/string_converters.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// -// string_converters.h -// -// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// - - -#include <stdint.h> - - - - -#ifndef CATS_STRING_CONVERTERS_H -#define CATS_STRING_CONVERTERS_H -bool string_to_float(char *string, float *value); - -bool string_to_bool(char *string, bool *value); - -bool string_to_double(char *string, double *value); - -bool string_to_integer(char *string, int32_t *value); - -bool string_to_long_double(char *string, long double *value); -#endif //CATS_STRING_CONVERTERS_H diff --git a/src/cats_strings/string_helpers.h b/src/cats_strings/string_helpers.h deleted file mode 100644 index 10671ce4bddd214ca68a777d3d835a4f57d4a9c9..0000000000000000000000000000000000000000 --- a/src/cats_strings/string_helpers.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// -// string_helpers.h -// -// Copyright (C) 2011-2024, University of Vienna and Vienna Institute for Nature Conservation & Analyses, Andreas Gattringer. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// - -#ifndef CATS_STRING_HELPERS_H -#define CATS_STRING_HELPERS_H - - -#endif //CATS_STRING_HELPERS_H diff --git a/src/logging/CMakeLists.txt b/src/logging/CMakeLists.txt deleted file mode 100644 index 872a70e10aab6cd48ce39fe8e43d472669e4dcce..0000000000000000000000000000000000000000 --- a/src/logging/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -add_library(cats_logging STATIC "" ../cats_windows.h) - -target_sources(cats_logging - PRIVATE - ../cats_defs.h - logging.c - PUBLIC - logging.h - ) - -target_include_directories(cats_logging PUBLIC ".") -set_property(TARGET cats_logging PROPERTY POSITION_INDEPENDENT_CODE ON) \ No newline at end of file diff --git a/src/modules/butterflies/CMakeLists.txt b/src/modules/butterflies/CMakeLists.txt index c20a250845e6cfd490a47a0312602fc2f7ded1c1..538918b46ccf4b4136a7b81ff1d117be37439c33 100644 --- a/src/modules/butterflies/CMakeLists.txt +++ b/src/modules/butterflies/CMakeLists.txt @@ -24,4 +24,4 @@ target_sources(cats-butterflies set_property(TARGET cats-butterflies PROPERTY POSITION_INDEPENDENT_CODE ON) -target_link_libraries(cats-butterflies cats_logging libcats) +target_link_libraries(cats-butterflies bdc_logging libcats) diff --git a/src/modules/butterflies/butterflies_main.c b/src/modules/butterflies/butterflies_main.c index e8e0b29088f4b9c5d9c516ef879ec9a6eca33e91..28b3fb18a4bb54deba517ea775f1360c57d3a031 100644 --- a/src/modules/butterflies/butterflies_main.c +++ b/src/modules/butterflies/butterflies_main.c @@ -39,6 +39,7 @@ struct cats_debug_options cats_debug; #include "lambda/leslie_matrix.h" #include "actions/setup_actions.h" #include "butterflies_scale.h" +#include "bdc_io/bdc_io.h" cats_dt_rates bf_expected_local_eggs_per_female(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col) diff --git a/src/modules/butterflies/butterflies_paths.c b/src/modules/butterflies/butterflies_paths.c index ba749c26edc9f085135fc2cffcc0faedadae4b73..7cc158d23c1e746830e46473048d0be74792f8db 100644 --- a/src/modules/butterflies/butterflies_paths.c +++ b/src/modules/butterflies/butterflies_paths.c @@ -30,6 +30,8 @@ #include "actions/cats_actions.h" #include "butterflies_paths.h" #include "module.h" +#include "bdc_io/bdc_io.h" + void bf_add_directories(struct cats_configuration *conf) { diff --git a/src/modules/butterflies/butterflies_stats.c b/src/modules/butterflies/butterflies_stats.c index 567a20fcd77b48951736851d621058630633321b..d711dcc8ea85fca4723ceac62665c2dddeaba2e8 100644 --- a/src/modules/butterflies/butterflies_stats.c +++ b/src/modules/butterflies/butterflies_stats.c @@ -32,6 +32,7 @@ #include "butterflies_paths.h" #include "temporal/phase_names.h" #include "temporal/years.h" +#include "bdc_io/bdc_io.h" const char *bf_get_stats_field_name(enum butterfly_stats which) diff --git a/src/modules/cats_test_module/CMakeLists.txt b/src/modules/cats_test_module/CMakeLists.txt index 6ebb9e80daed1eb2b058350a690dea82a2b1d098..68caf04a210f05943e7d41801d3554431e717209 100644 --- a/src/modules/cats_test_module/CMakeLists.txt +++ b/src/modules/cats_test_module/CMakeLists.txt @@ -8,4 +8,4 @@ target_sources(cats-test-module PRIVATE target_include_directories(cats-test-module PUBLIC ".") set_property(TARGET cats-test-module PROPERTY POSITION_INDEPENDENT_CODE ON) -target_link_libraries(cats-test-module cats_logging libcats) +target_link_libraries(cats-test-module bdc_logging libcats) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 237b15de3e760cd8c2182d7e35745afd44b8f878..b205a80d7b7822ff3f876118c20538575a06e5db 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -9,5 +9,5 @@ add_executable(vital_rate_test vital_rate_test.c) add_executable(csv_test csv_test.c ) configure_file("test.csv" "test.csv") -target_link_libraries(vital_rate_test cmocka cats_logging bdc cats_strings cats_ini cats_csv libcats) -target_link_libraries(csv_test cmocka cats_strings cats_csv cats_strings cats_logging bdc) +target_link_libraries(vital_rate_test cmocka bdc_logging bdc bdc_strings cats_ini cats_csv libcats) +target_link_libraries(csv_test cmocka bdc_strings cats_csv bdc_strings bdc_logging bdc) diff --git a/src/tests/csv_test.c b/src/tests/csv_test.c index 1375ec10c656e6a942ef1817fd61ebe621e0469f..467a7a488288729afe9161f93083d7aab7d72ce1 100644 --- a/src/tests/csv_test.c +++ b/src/tests/csv_test.c @@ -24,8 +24,9 @@ #include <cmocka.h> #include <stdio.h> #include "bdc_memory/bdc_memory.h" -#include "cats_strings/cats_strings.h" +#include "bdc_strings/bdc_strings.h" #include "cats_csv/cats_csv.h" +#include "bdc_io/bdc_io.h" struct csv_test {