star-stl

Load STereo Lithography (StL) file format
git clone git://git.meso-star.fr/star-stl.git
Log | Files | Refs | README | LICENSE

commit bbd3f13e07a28593599bf9dfab0bd45a884d6547
parent 41e30f5b84e9356817c7a327f374dc3a7a0b4ab0
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 25 Oct 2019 13:43:50 +0200

Merge branch 'release-0.3.3'

Diffstat:
MREADME.md | 5+++++
Mcmake/CMakeLists.txt | 2+-
Msrc/sstl.c | 78++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
3 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md @@ -15,6 +15,11 @@ can be edited, built, tested and installed as any CMake project. ## Release notes +### Version 0.3.3 + +- Fix star-stl lack of reentrancy. When used from a code using strtok, + star-stl was corrupting the strtok context. + ### Version 0.3.2 - Update the version of the RSys dependency to 0.6: replace the deprecated diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -66,7 +66,7 @@ endif() set(VERSION_MAJOR 0) set(VERSION_MINOR 3) -set(VERSION_PATCH 2) +set(VERSION_PATCH 3) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set_target_properties(sstl PROPERTIES DEFINE_SYMBOL SSTL_SHARED_BUILD diff --git a/src/sstl.c b/src/sstl.c @@ -26,6 +26,8 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ +#define _POSIX_C_SOURCE 200112L /* strtok_r support */ + #include "sstl.h" #include <rsys/cstr.h> @@ -36,9 +38,13 @@ #include <rsys/ref_count.h> #include <rsys/stretchy_array.h> +#include <string.h> + #ifdef COMPILER_CL #pragma warning(push) #pragma warning(disable:4706) /* Assignment within a condition */ + + #define strtok_r strtok_s #endif struct solid { @@ -176,7 +182,8 @@ parse_float3 char* str, float vert[3], const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { char* tk; int i; @@ -184,7 +191,7 @@ parse_float3 ASSERT(str && vert && filename); FOR_EACH(i, 0, 3) { - tk = strtok(i==0 ? str : NULL, " \t"); + tk = strtok_r(i==0 ? str : NULL, " \t", tok_ctx); if(!tk) { print_log(sstl, LOG_ERROR, "%s:%lu: expecting 3D coordinates.\n", filename, (unsigned long)iline); @@ -198,7 +205,7 @@ parse_float3 return res; } } - tk = strtok(NULL, "\0"); + tk = strtok_r(NULL, "\0", tok_ctx); if(tk) { /* Unexpected remaining chars */ print_log(sstl, LOG_WARNING, "%s:%lu: unexpected directive \"%s\".\n", filename, (unsigned long)iline, tk); @@ -212,7 +219,8 @@ parse_name_string char* str, char** out_name, const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { char* name = NULL; char* tk; @@ -222,7 +230,7 @@ parse_name_string if(!str) goto exit; /* Handle name with spaces */ - for(tk = strtok(str, " \t"); tk; tk = strtok(NULL, " \t")) { + for(tk = strtok_r(str, " \t", tok_ctx); tk; tk = strtok_r(NULL, " \t", tok_ctx)) { char* remain = NULL; if(name) name[strlen(name)] = ' '; /* Replace '\0' by ' ' */ remain = sa_add(name, strlen(tk) + 1/*NULL char*/); @@ -253,12 +261,13 @@ parse_solid_name struct solid* solid, char* line, const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { res_T res = RES_OK; ASSERT(sstl && solid && !solid->name); - if(!line || strcmp(strtok(line, " \t"), "solid")) { + if(!line || strcmp(strtok_r(line, " \t", tok_ctx), "solid")) { print_log(sstl, LOG_ERROR, "%s:%lu: missing the \"solid [NAME]\" directive.\n", filename, (unsigned long)iline); @@ -267,7 +276,7 @@ parse_solid_name } res = parse_name_string - (sstl, strtok(NULL, "\0"), &solid->name, filename, iline); + (sstl, strtok_r(NULL, "\0", tok_ctx), &solid->name, filename, iline, tok_ctx); if(res != RES_OK) goto error; exit: @@ -284,21 +293,22 @@ parse_solid_vertex unsigned* const index, char* line, const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { struct vertex vertex; unsigned* found_id; res_T res = RES_OK; ASSERT(sstl && solid && index); - if(!line || strcmp(strtok(line, " \t"), "vertex")) { + if(!line || strcmp(strtok_r(line, " \t", tok_ctx), "vertex")) { print_log(sstl, LOG_ERROR, "%s:%lu: missing a \"vertex X Y Z\" directive.\n", filename, (unsigned long)iline); return RES_BAD_ARG; } - res = parse_float3(sstl, strtok(NULL, "\0"), vertex.xyz, filename, iline); + res = parse_float3(sstl, strtok_r(NULL, "\0", tok_ctx), vertex.xyz, filename, iline, tok_ctx); if(res != RES_OK) return res; /* Look for an already registered vertex position */ @@ -327,14 +337,15 @@ parse_outer_loop (struct sstl* sstl, char* line, const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { char* tk; ASSERT(sstl); if(!line - || strcmp(strtok(line, " \t"), "outer") - || !(tk = strtok(NULL, " \t")) + || strcmp(strtok_r(line, " \t", tok_ctx), "outer") + || !(tk = strtok_r(NULL, " \t", tok_ctx)) || strcmp(tk, "loop")) { print_log(sstl, LOG_ERROR, "%s:%lu: missing the \"outer loop\" directive.\n", @@ -342,7 +353,7 @@ parse_outer_loop return RES_BAD_ARG; } - tk = strtok(NULL, "\0"); + tk = strtok_r(NULL, "\0", tok_ctx); if(tk && strspn(tk, " \t\r\n") != strlen(tk)) { /* Invalid remaining chars */ print_log(sstl, LOG_WARNING, "%s:%lu: malformed \"outer loop\" directive.\n", @@ -357,19 +368,20 @@ parse_directive const char* directive, char* line, const char* filename, - const size_t iline) + const size_t iline, + char** tok_ctx) { char* tk; ASSERT(sstl && directive); - if(!line || strcmp(strtok(line, " \t"), directive)) { + if(!line || strcmp(strtok_r(line, " \t", tok_ctx), directive)) { print_log(sstl, LOG_ERROR, "%s:%lu: missing the \"%s\" directive.\n", filename, (unsigned long)iline, directive); return RES_BAD_ARG; } - tk = strtok(NULL, " \0"); + tk = strtok_r(NULL, " \0", tok_ctx); if(tk && strspn(tk, " \t\r\n") != strlen(tk)) { /* Invalid remaining chars */ print_log(sstl, LOG_WARNING, "%s:%lu: malformed \"%s\" directive.\n", @@ -380,7 +392,11 @@ parse_directive } static res_T -load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) +load_stream + (struct sstl* sstl, + FILE* stream, + const char* stream_name, + char** tok_ctx) { res_T res = RES_OK; struct streamer streamer; @@ -393,7 +409,7 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) clear(sstl); line = streamer_read_line(&streamer); - res = parse_solid_name(sstl, &solid, line, streamer.name, streamer.iline); + res = parse_solid_name(sstl, &solid, line, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; for(;;) { /* Parse the solid facets */ @@ -409,7 +425,7 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) goto error; } - tk = strtok(line, " \t"); + tk = strtok_r(line, " \t", tok_ctx); /* Stop on "endsolid" directive */ if(!strcmp(tk, "endsolid")) @@ -417,7 +433,7 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) /* Parse the facet normal directive */ if(strcmp(tk, "facet") - || !(tk = strtok(NULL, " \t")) + || !(tk = strtok_r(NULL, " \t", tok_ctx)) || strcmp(tk, "normal")) { print_log(sstl, LOG_ERROR, "%s:%lu: missing or malformed \"facet normal X Y Z\" directive.\n", @@ -426,19 +442,19 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) goto error; } res = parse_float3 - (sstl, strtok(NULL, "\0"), normal, streamer.name, streamer.iline); + (sstl, strtok_r(NULL, "\0", tok_ctx), normal, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; /* Parse the Outer loop directive */ line = streamer_read_line(&streamer); - res = parse_outer_loop(sstl, line, streamer.name, streamer.iline); + res = parse_outer_loop(sstl, line, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; /* Parse the facet vertices. Assume that only 3 vertices are submitted */ FOR_EACH(ivertex, 0, 3) { line = streamer_read_line(&streamer); res = parse_solid_vertex - (sstl, &solid, facet+ivertex, line, streamer.name, streamer.iline); + (sstl, &solid, facet+ivertex, line, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; } @@ -453,11 +469,11 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) f3_set(sa_add(solid.normals, 3), normal); line = streamer_read_line(&streamer); - res = parse_directive(sstl, "endloop", line, streamer.name, streamer.iline); + res = parse_directive(sstl, "endloop", line, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; line = streamer_read_line(&streamer); - res = parse_directive(sstl, "endfacet", line, streamer.name, streamer.iline); + res = parse_directive(sstl, "endfacet", line, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; } @@ -465,7 +481,7 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) if(sstl->verbose && solid.name) { char* name = NULL; res = parse_name_string - (sstl, strtok(NULL, "\0"), &name, streamer.name, streamer.iline); + (sstl, strtok_r(NULL, "\0", tok_ctx), &name, streamer.name, streamer.iline, tok_ctx); if(res != RES_OK) goto error; /* Compare the "endsolid" name with the one of the "solid" directive */ @@ -570,6 +586,7 @@ res_T sstl_load(struct sstl* sstl, const char* filename) { FILE* file; + char* tok_ctx; res_T res = RES_OK; if(!sstl || !filename) @@ -580,7 +597,7 @@ sstl_load(struct sstl* sstl, const char* filename) print_log(sstl, LOG_ERROR, "Error opening `%s'.\n", filename); return RES_IO_ERR; } - res = load_stream(sstl, file, filename); + res = load_stream(sstl, file, filename, &tok_ctx); fclose(file); return res; } @@ -588,8 +605,9 @@ sstl_load(struct sstl* sstl, const char* filename) res_T sstl_load_stream(struct sstl* sstl, FILE* stream) { + char* tok_ctx; if(!sstl || !stream) return RES_BAD_ARG; - return load_stream(sstl, stream, "STREAM"); + return load_stream(sstl, stream, "STREAM", &tok_ctx); } res_T