summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-12-10 21:26:05 -0600
committersanine <sanine.not@pm.me>2022-12-10 21:26:05 -0600
commite68e6d4e433fe42a0c6df18b2f2d7990b91b7cd6 (patch)
tree823ba0a5f0f062692d04f32dfb2b26240fd71a7b
parent7c47f23ee92afa07c748700f1de22fd8b8ccf967 (diff)
add basic float_array parsing
-rw-r--r--include/kalmia.h16
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/geometry/CMakeLists.txt7
-rw-r--r--src/geometry/geometry.c71
-rw-r--r--src/geometry/geometry.h20
-rw-r--r--src/geometry/geometry.test.c49
-rw-r--r--src/test/test.h2
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