diff options
author | sanine <sanine.not@pm.me> | 2022-12-10 21:26:05 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-12-10 21:26:05 -0600 |
commit | e68e6d4e433fe42a0c6df18b2f2d7990b91b7cd6 (patch) | |
tree | 823ba0a5f0f062692d04f32dfb2b26240fd71a7b | |
parent | 7c47f23ee92afa07c748700f1de22fd8b8ccf967 (diff) |
add basic float_array parsing
-rw-r--r-- | include/kalmia.h | 16 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/geometry/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/geometry/geometry.c | 71 | ||||
-rw-r--r-- | src/geometry/geometry.h | 20 | ||||
-rw-r--r-- | src/geometry/geometry.test.c | 49 | ||||
-rw-r--r-- | src/test/test.h | 2 |
7 files changed, 164 insertions, 2 deletions
diff --git a/include/kalmia.h b/include/kalmia.h index 31aff1e..48a608f 100644 --- a/include/kalmia.h +++ b/include/kalmia.h @@ -45,7 +45,7 @@ #ifndef KALMIA_H #define KALMIA_H -#include <stddef.h> +#include <stdlib.h> /* kalmia uses semantic versioning (semver.org) */ #define KALMIA_VERSION_MAJOR 0 @@ -53,6 +53,16 @@ #define KALMIA_VERSION_PATCH 0 +/* determine precision */ +#ifdef KALMIA_USE_DOUBLE +typedef double ka_real_t; +#define KA_STR_TO_REAL(nptr, end) strtod(nptr, end) +#else +typedef float ka_real_t; +#define KA_STR_TO_REAL(nptr, end) strtof(nptr, end) +#endif + + /* internal buffer size for strings/sids */ #ifndef KA_BUF_SIZE #define KA_BUF_SIZE 128 @@ -61,6 +71,8 @@ /* format data structures */ -typedef double ka_matrix_t[16]; +typedef ka_real_t ka_matrix_t[16]; + + #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f5055b1..78cf520 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,3 +12,4 @@ if (KALMIA_BUILD_TESTS) endif() add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/transform) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/geometry) diff --git a/src/geometry/CMakeLists.txt b/src/geometry/CMakeLists.txt new file mode 100644 index 0000000..e1a0995 --- /dev/null +++ b/src/geometry/CMakeLists.txt @@ -0,0 +1,7 @@ +project(kalmia) + +target_sources(kalmia PUBLIC geometry.c) + +if (KALMIA_BUILD_TESTS) + target_sources(kalmia-tests PUBLIC geometry.test.c) +endif() diff --git a/src/geometry/geometry.c b/src/geometry/geometry.c new file mode 100644 index 0000000..be9ce25 --- /dev/null +++ b/src/geometry/geometry.c @@ -0,0 +1,71 @@ +#include <string.h> +#include <stdlib.h> + +#include <kalmia.h> +#include <ezxml.h> +#include "geometry.h" + + +static int copy_str(char **dest, const char *src) +{ + if (src == NULL) { + *dest = NULL; + return 0; + } + + size_t len = strlen(src)+1; + *dest = malloc(len * sizeof(char)); + if (*dest == NULL) + return -1; + strncpy(*dest, src, len); + return 0; +} + + +ka_float_array_t * kai_parse_float_array(ezxml_t tag) +{ + if (strcmp(ezxml_name(tag), "float_array") != 0) { + /* wrong tag type */ + return NULL; + } + + /* allocate struct */ + ka_float_array_t *a = malloc(sizeof(ka_float_array_t)); + if (a == NULL) return NULL; + + /* inspect attributes */ + const char *count_str = ezxml_attr(tag, "count"); + a->count = strtol(count_str, NULL, 10); + + const char *id_str = ezxml_attr(tag, "id"); + if (copy_str(&(a->id), id_str) < 0) { + free(a); + return NULL; + } + + /* parse data */ + a->array = malloc(a->count * sizeof(ka_real_t)); + if (a->array == NULL) { + free(a->id); + free(a); + return NULL; + } + + char *data = ezxml_txt(tag); + char *end; + int i; + for (i=0; i<a->count; i++) { + a->array[i] = KA_STR_TO_REAL(data, &end); + data = end; + } + + return a; +} + + +void kai_free_float_array(ka_float_array_t *a) +{ + free(a->array); + free(a->id); + free(a); +} diff --git a/src/geometry/geometry.h b/src/geometry/geometry.h new file mode 100644 index 0000000..971bd1b --- /dev/null +++ b/src/geometry/geometry.h @@ -0,0 +1,20 @@ +#ifndef KALMIA_GEOMETRY_H +#define KALMIA_GEOMETRY_H + +#include <kalmia.h> +#include <ezxml.h> + +typedef struct { + char *id; + size_t count; + ka_real_t *array; +} ka_float_array_t; + + +/* allocate a new float array and parse an xml tag into it */ +ka_float_array_t * kai_parse_float_array(ezxml_t tag); + +/* free a loaded float array */ +void kai_free_float_array(ka_float_array_t *array); + +#endif diff --git a/src/geometry/geometry.test.c b/src/geometry/geometry.test.c new file mode 100644 index 0000000..f400540 --- /dev/null +++ b/src/geometry/geometry.test.c @@ -0,0 +1,49 @@ +#include <string.h> +#include <math.h> +#include <kalmia.h> +#include "test/test.h" +#include "geometry.h" + + +void parse_float_array(); + + +void suite_geometry() +{ + lily_run_test(parse_float_array); +} + + +void parse_float_array() +{ + char str[1024]; + strncpy( + str, + "<float_array id=\"box-Pos-array\" count=\"24\">\n" + " -0.5 0.5 0.5\n" + " 0.5 0.5 0.5\n" + " -0.5 -0.5 0.5\n" + " 0.5 -0.5 0.5\n" + " -0.5 0.5 -0.5\n" + " 0.5 0.5 -0.5\n" + " -0.5 -0.5 -0.5\n" + " 0.5 -0.5 -0.5\n" + "</float_array>\n", + 1024 + ); + ezxml_t tag = ezxml_parse_str(str, strlen(str)); + + ka_float_array_t *a = kai_parse_float_array(tag); + ezxml_free(tag); + + lily_assert_not_null(a); + lily_assert_string_equal(a->id, "box-Pos-array"); + lily_assert_int_equal(a->count, 24); + + int i; + for (i=0; i<24; i++) { + lily_assert_float_equal(fabs(a->array[i]), 0.5, 1e-3); + } + + kai_free_float_array(a); +} diff --git a/src/test/test.h b/src/test/test.h index 17731b9..b50fda5 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -5,11 +5,13 @@ void suite_transform(); +void suite_geometry(); #define RUN_TESTS() \ do { \ lily_run_suite(suite_transform); \ + lily_run_suite(suite_geometry); \ } while (0) #endif |