commit 12f153a9044ce5d888fa647e9c3603e6189ef787
parent a14c246d84d55c3f07fb925440b4ecc0eef38de3
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Mon, 17 Feb 2025 19:11:52 +0100
Refactor geometry parsing and introduce dynamic arrays for geometry lists
- Extracted `geometry_parse` function to unify geometry parsing in
`sphin_volume` and `sphin_surface`;
- Set up the API using rsys/dynamic_array to create generic lists of geometries
as member variables of `sphin_volume and `sphin_volume`.
Diffstat:
5 files changed, 97 insertions(+), 56 deletions(-)
diff --git a/src/sphin_config.c b/src/sphin_config.c
@@ -146,11 +146,16 @@ load_stream
}
else {
res = RES_BAD_ARG;
+ ERROR
+ (sphin,
+ "%s: %lu: Bad keyword\n",
+ txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
+ goto error;
}
if (RES_OK != res) {
ERROR
(sphin,
- "%s: %lu: Bad keyword\n",
+ "%s: %lu: Parsing error\n",
txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
goto error;
}
diff --git a/src/sphin_geometry.c b/src/sphin_geometry.c
@@ -21,6 +21,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#define _POSIX_C_SOURCE 200112L /* for strtok_r support */
#include "sphin_geometry.h"
@@ -56,3 +57,31 @@ geometry_copy
return str_copy(&dst->stl_filename, &src->stl_filename);
}
+res_T
+geometry_parse
+ (struct geometry* geom,
+ char* value)
+{
+ char* side = NULL;
+ char* filename = NULL;
+ char* token_ptr = NULL;
+ res_T res = RES_OK;
+
+ /* Parse side */
+ side = strtok_r(value, " \t", &token_ptr);
+ if (NULL == side){ res = RES_BAD_ARG; goto error; }
+ if (0 == strcmp(side, "FRONT")){ geom->side = SPHIN_FRONT; }
+ else if (0 == strcmp(side, "BACK")){ geom->side = SPHIN_BACK; }
+ else { res = RES_BAD_ARG; goto error; }
+
+ /* Parse filename */
+ filename = strtok_r(NULL, " \t", &token_ptr);
+ if (NULL == filename){ res = RES_BAD_ARG; goto error; }
+ res = str_set(&geom->stl_filename, filename);
+ if (RES_OK != res) { goto error; }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/sphin_geometry.h b/src/sphin_geometry.h
@@ -27,6 +27,7 @@
#include "sphin.h"
+#include <rsys/dynamic_array.h>
#include <rsys/str.h>
struct mem_allocator;
@@ -50,4 +51,21 @@ geometry_copy
(struct geometry* dst,
const struct geometry* src);
+extern LOCAL_SYM res_T
+geometry_parse
+ (struct geometry* geom,
+ char* value);
+
+/* Generate the dynamic array for the structure geometry and its API */
+#define DARRAY_NAME geometry /* Prefix for api functions and structures:
+ darray_geometry */
+#define DARRAY_DATA struct geometry
+/* Define the default functions for init, release and copy elements of the
+ * dynamic array */
+#define DARRAY_FUNCTOR_INIT geometry_init
+#define DARRAY_FUNCTOR_RELEASE geometry_release
+#define DARRAY_FUNCTOR_COPY geometry_copy
+/* Generate the code */
+#include <rsys/dynamic_array.h>
+
#endif /* SPHIN_GEOMETRY_H */
diff --git a/src/sphin_surface.c b/src/sphin_surface.c
@@ -37,7 +37,8 @@
struct sphin_surface {
struct str name;
struct sphin* sphin;
-
+ struct darray_geometry geometries; /* dynamic array of struct geometry. see
+ rsys/dynamic_array.h */
struct brdf* brdf;
ref_T ref;
};
@@ -99,28 +100,28 @@ static res_T
parse_geometry
(struct sphin_surface* surface,
struct txtrdr* txtrdr,
- char* value
- )
+ char* value)
{
struct geometry geom;
- struct str filename;
- char* token = NULL;
- char* token_ptr = NULL;
- char* side = NULL;
res_T res = RES_OK;
ASSERT(NULL != surface);
+ (void) txtrdr; /* Disable unused variable warning */
- str_init(surface->sphin->allocator, &filename);
geometry_init(surface->sphin->allocator, &geom);
+ res = geometry_parse(&geom, value);
+ if (RES_OK != res) { goto error; }
- token = strtok_r(value, " ", &token_ptr);
- if (NULL == token){ res = RES_BAD_ARG; goto error; }
+ /* Append a new element (geom) to the end of the volume->geometries dynamic array */
+ res = darray_geometry_push_back(&surface->geometries, &geom);
+ if (RES_OK != res) { goto error; }
- side = trim_keyword(token);
- if (0 == strcmp(side, "FRONT")){ geom.side = SPHIN_FRONT; }
- else if (0 == strcmp(side, "BACK")){ geom.side = SPHIN_BACK; }
- else { res = RES_BAD_ARG; goto error; }
+exit:
+ geometry_release(&geom);
+ return res;
+error:
+ goto exit;
+}
token = strtok_r(NULL, " ", &token_ptr);
if (NULL == token){ res = RES_BAD_ARG; goto error; }
@@ -132,12 +133,10 @@ parse_geometry
/* TODO: Add geometry to surface->geometries */
exit:
- str_release(&filename);
return res;
error:
goto exit;
}
-
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -179,9 +178,7 @@ parse_surface
/* parse value */
token = strtok_r(NULL, "", &token_ptr);
if (NULL == token){ res = RES_BAD_ARG; goto error; }
- value = trim_string(token);
- if (NULL == value){ res = RES_BAD_ARG; goto error; }
-
+ value = token;
if (0 == strcmp(keyword, "geometry")){
res = parse_geometry(surface, txtrdr, value);
}
@@ -192,8 +189,8 @@ parse_surface
break;
}
}
-
exit:
+ str_release(&line);
return res;
error:
goto exit;
diff --git a/src/sphin_volume.c b/src/sphin_volume.c
@@ -37,7 +37,8 @@
struct sphin_volume {
struct str name;
double ka;
-
+ struct darray_geometry geometries; /* dynamic array of struct geometry. see
+ rsys/dynamic_array.h */
struct sphin* sphin;
ref_T ref;
};
@@ -66,6 +67,7 @@ volume_create
volume->sphin = sphin;
str_init(sphin->allocator, &volume->name);
+ darray_geometry_init(sphin->allocator, &volume->geometries);
res = str_set(&volume->name, name);
if (RES_OK != res) { goto error; }
@@ -90,6 +92,7 @@ release_volume(ref_T* address)
volume = CONTAINER_OF(address, struct sphin_volume, ref);
str_release(&volume->name);
+ darray_geometry_release(&volume->geometries);
sphin = volume->sphin;
MEM_RM(sphin->allocator, volume);
SPHIN(ref_put(sphin));
@@ -99,62 +102,53 @@ static res_T
parse_geometry
(struct sphin_volume* volume,
struct txtrdr* txtrdr,
- char* value
- )
+ char* value)
{
- struct geometry* geom = NULL;
- struct str filename;
- char* token = NULL;
- char* token_ptr = NULL;
- char* side = NULL;
+ struct geometry geom;
res_T res = RES_OK;
ASSERT(NULL != volume);
+ (void) txtrdr; /* Disable unused variable warning */
- str_init(volume->sphin->allocator, &filename);
- geometry_init(volume->sphin->allocator, geom);
-
- token = strtok_r(value, " ", &token_ptr);
- if (NULL == token){ res = RES_BAD_ARG; goto error; }
-
- side = trim_keyword(token);
- if (0 == strcmp(side, "FRONT")){ geom->side = SPHIN_FRONT; }
- else if (0 == strcmp(side, "BACK")){ geom->side = SPHIN_BACK; }
- else { res = RES_BAD_ARG; goto error; }
-
- token = strtok_r(NULL, " ", &token_ptr);
- if (NULL == token){ res = RES_BAD_ARG; goto error; }
- res = str_set(&filename, trim_keyword(token));
+ geometry_init(volume->sphin->allocator, &geom);
+ res = geometry_parse(&geom, value);
if (RES_OK != res) { goto error; }
- str_copy(&geom->stl_filename, &filename);
-
- /* TODO: Add geometry to volume->geometries */
+ /* Append a new element (geom) to the end of the volume->geometries dynamic array */
+ res = darray_geometry_push_back(&volume->geometries, &geom);
+ if (RES_OK != res) { goto error; }
exit:
- str_release(&filename);
+ geometry_release(&geom);
return res;
error:
- if (geom != NULL) { geometry_release(geom); }
goto exit;
}
static res_T
parse_ka
-(struct sphin_volume* volume,
- struct txtrdr* txtrdr,
- char* value
- )
+ (struct sphin_volume* volume,
+ struct txtrdr* txtrdr,
+ char* value) /* ka: 1.2 */
{
+ char* token = NULL;
+ char* token_ptr = NULL;
res_T res = RES_OK;
double ka;
ASSERT(NULL != volume);
+ (void) txtrdr; /* Disable unused variable warning */
- res = cstr_to_double(value, &ka);
+ token = strtok_r(value, " \t", &token_ptr);
+
+ res = cstr_to_double(token, &ka);
if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+ if (ka < 0) { res = RES_BAD_ARG; goto error; }
volume->ka = ka;
+ token = strtok_r(NULL, " \t", &token_ptr);
+ if(NULL != token) { res = RES_BAD_ARG; goto error; }
+
exit:
return res;
error:
@@ -204,9 +198,7 @@ parse_volume
/* parse value */
token = strtok_r(NULL, "", &token_ptr);
if (NULL == token){ res = RES_BAD_ARG; goto error; }
- value = trim_string(token);
- if (NULL == value){ res = RES_BAD_ARG; goto error; }
-
+ value = token;
if (0 == strcmp(keyword, "geometry")){
res = parse_geometry(volume, txtrdr, value);
}