gmio_stl: add read/write option stla_dont_check_lc_numeric
gmio_stla_read() and gmio_stla_write() now checks LC_NUMERIC is either "C" or "POSIX", if not then GMIO_ERROR_BAD_LC_NUMERIC is returned. This option is controlled with: * gmio_stl_read_options.stla_dont_check_lc_numeric * gmio_write_read_options.stla_dont_check_lc_numeric
This commit is contained in:
parent
61e4fd5066
commit
89d268f052
@ -31,6 +31,9 @@ enum gmio_error
|
||||
/*! No error occurred, success */
|
||||
GMIO_ERROR_OK = 0,
|
||||
|
||||
/*! Unknown error */
|
||||
GMIO_ERROR_UNKNOWN,
|
||||
|
||||
/*! Pointer on argument memory block is NULL */
|
||||
GMIO_ERROR_NULL_MEMBLOCK,
|
||||
|
||||
@ -50,8 +53,8 @@ enum gmio_error
|
||||
*/
|
||||
GMIO_ERROR_STDIO,
|
||||
|
||||
/*! Unknown error */
|
||||
GMIO_ERROR_UNKNOWN
|
||||
/*! Checking of \c LC_NUMERIC failed(should be "C" or "POSIX") */
|
||||
GMIO_ERROR_BAD_LC_NUMERIC
|
||||
};
|
||||
|
||||
/*! Returns true if <tt>code == GMIO_NO_ERROR</tt> */
|
||||
|
62
src/gmio_core/internal/locale_utils.c
Normal file
62
src/gmio_core/internal/locale_utils.c
Normal file
@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
** gmio
|
||||
** Copyright Fougue (24 Jun. 2016)
|
||||
** contact@fougue.pro
|
||||
**
|
||||
** This software is a reusable library whose purpose is to provide complete
|
||||
** I/O support for various CAD file formats (eg. STL)
|
||||
**
|
||||
** This software is governed by the CeCILL-B license under French law and
|
||||
** abiding by the rules of distribution of free software. You can use,
|
||||
** modify and/ or redistribute the software under the terms of the CeCILL-B
|
||||
** license as circulated by CEA, CNRS and INRIA at the following URL
|
||||
** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
|
||||
****************************************************************************/
|
||||
|
||||
#include "locale_utils.h"
|
||||
|
||||
#include "../error.h"
|
||||
#include "string_ascii_utils.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const char *gmio_lc_numeric()
|
||||
{
|
||||
const char* lcnum = setlocale(LC_NUMERIC, NULL);
|
||||
return lcnum != NULL ? lcnum : "";
|
||||
}
|
||||
|
||||
bool gmio_lc_numeric_is_C()
|
||||
{
|
||||
const char* lc = gmio_lc_numeric();
|
||||
return (gmio_ascii_stricmp(lc, "C") == 0
|
||||
|| gmio_ascii_stricmp(lc, "POSIX") == 0);
|
||||
}
|
||||
|
||||
bool gmio_check_lc_numeric(int *error)
|
||||
{
|
||||
if (!gmio_lc_numeric_is_C())
|
||||
*error = GMIO_ERROR_BAD_LC_NUMERIC;
|
||||
return gmio_no_error(*error);
|
||||
}
|
||||
|
||||
static char global_lc_numeric[64] = {0};
|
||||
|
||||
void gmio_lc_numeric_save()
|
||||
{
|
||||
/* Save LC_NUMERIC
|
||||
* POSIX specifies that the pointer returned by setlocale(), not just the
|
||||
* contents of the pointed-to string, may be invalidated by subsequent calls
|
||||
* to setlocale */
|
||||
strncpy(global_lc_numeric,
|
||||
setlocale(LC_NUMERIC, NULL),
|
||||
GMIO_ARRAY_SIZE(global_lc_numeric));
|
||||
}
|
||||
|
||||
void gmio_lc_numeric_restore()
|
||||
{
|
||||
if (global_lc_numeric[0] != '\0')
|
||||
setlocale(LC_NUMERIC, global_lc_numeric);
|
||||
}
|
28
src/gmio_core/internal/locale_utils.h
Normal file
28
src/gmio_core/internal/locale_utils.h
Normal file
@ -0,0 +1,28 @@
|
||||
/****************************************************************************
|
||||
** gmio
|
||||
** Copyright Fougue (24 Jun. 2016)
|
||||
** contact@fougue.pro
|
||||
**
|
||||
** This software is a reusable library whose purpose is to provide complete
|
||||
** I/O support for various CAD file formats (eg. STL)
|
||||
**
|
||||
** This software is governed by the CeCILL-B license under French law and
|
||||
** abiding by the rules of distribution of free software. You can use,
|
||||
** modify and/ or redistribute the software under the terms of the CeCILL-B
|
||||
** license as circulated by CEA, CNRS and INRIA at the following URL
|
||||
** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
|
||||
****************************************************************************/
|
||||
|
||||
#include "../global.h"
|
||||
|
||||
const char* gmio_lc_numeric();
|
||||
|
||||
/*! Returns result of case-insensitive test <tt>LC_NUMERIC == "C|POSIX"</tt> */
|
||||
bool gmio_lc_numeric_is_C();
|
||||
|
||||
/*! Checks gmio_lc_numeric_is_C(), if false sets \p *error to
|
||||
* \c GMIO_ERROR_BAD_LC_NUMERIC*/
|
||||
bool gmio_check_lc_numeric(int* error);
|
||||
|
||||
void gmio_lc_numeric_save();
|
||||
void gmio_lc_numeric_restore();
|
@ -25,6 +25,7 @@
|
||||
#include "../../gmio_core/internal/helper_memblock.h"
|
||||
#include "../../gmio_core/internal/helper_stream.h"
|
||||
#include "../../gmio_core/internal/helper_task_iface.h"
|
||||
#include "../../gmio_core/internal/locale_utils.h"
|
||||
#include "../../gmio_core/internal/min_max.h"
|
||||
#include "../../gmio_core/internal/safe_cast.h"
|
||||
|
||||
@ -180,6 +181,8 @@ int gmio_stla_write(
|
||||
const struct gmio_stl_write_options* opts)
|
||||
{
|
||||
/* Constants */
|
||||
const bool check_lcnum =
|
||||
opts != NULL ? !opts->stla_dont_check_lc_numeric : true;
|
||||
const struct gmio_task_iface* task = opts != NULL ? &opts->task_iface : NULL;
|
||||
struct gmio_memblock_helper mblock_helper =
|
||||
gmio_memblock_helper(opts != NULL ? &opts->stream_memblock : NULL);
|
||||
@ -225,6 +228,8 @@ int gmio_stla_write(
|
||||
}
|
||||
|
||||
/* Check validity of input parameters */
|
||||
if (check_lcnum && !gmio_check_lc_numeric(&error))
|
||||
goto label_end;
|
||||
if (!gmio_check_memblock_size(&error, mblock, GMIO_STLA_FACET_SIZE_P2))
|
||||
goto label_end;
|
||||
if (!gmio_stl_check_mesh(&error, mesh))
|
||||
|
@ -30,7 +30,12 @@
|
||||
#include "../gmio_core/task_iface.h"
|
||||
#include "../gmio_core/text_format.h"
|
||||
|
||||
/*! Options of function gmio_stl_read() */
|
||||
/*! Options of function gmio_stl_read()
|
||||
*
|
||||
* Initialising gmio_stl_read_options with \c {0} (or \c {} in C++) is the
|
||||
* convenient way to set default values(passing \c NULL to gmio_stl_read() has
|
||||
* the same effect).
|
||||
*/
|
||||
struct gmio_stl_read_options
|
||||
{
|
||||
/*! Used by the stream to bufferize I/O operations
|
||||
@ -59,9 +64,27 @@ struct gmio_stl_read_options
|
||||
gmio_streamsize_t (*func_stla_get_streamsize)(
|
||||
struct gmio_stream* stream,
|
||||
struct gmio_memblock* stream_memblock);
|
||||
|
||||
/*! Flag allowing to disable checking of the current locale's numeric
|
||||
* formatting category
|
||||
*
|
||||
* If \c false then \c LC_NUMERIC is checked to be "C" or "POSIX". If check
|
||||
* fails then the function returns \c GMIO_ERROR_BAD_LC_NUMERIC
|
||||
*
|
||||
* This applies only for STL ascii, where it affects text-related standard
|
||||
* C functions(snprintf(), strtod(), ...)
|
||||
*
|
||||
* \c LC_NUMERIC checking is enabled by default.
|
||||
*/
|
||||
bool stla_dont_check_lc_numeric;
|
||||
};
|
||||
|
||||
/*! Options of function gmio_stl_write() */
|
||||
/*! Options of function gmio_stl_write()
|
||||
*
|
||||
* Initialising gmio_stl_write_options with \c {0} (or \c {} in C++) is the
|
||||
* convenient way to set default values(passing \c NULL to gmio_stl_write() has
|
||||
* the same effect).
|
||||
*/
|
||||
struct gmio_stl_write_options
|
||||
{
|
||||
/*! See gmio_stl_read_options::stream_memblock */
|
||||
@ -70,6 +93,9 @@ struct gmio_stl_write_options
|
||||
/*! See gmio_stl_read_options::task_iface */
|
||||
struct gmio_task_iface task_iface;
|
||||
|
||||
/*! See gmio_stl_read_options::stla_dont_check_lc_numeric */
|
||||
bool stla_dont_check_lc_numeric;
|
||||
|
||||
/*! Flag allowing to skip writting of any header/footer data, but just
|
||||
* triangles
|
||||
*
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "../gmio_core/internal/helper_memblock.h"
|
||||
#include "../gmio_core/internal/helper_stream.h"
|
||||
#include "../gmio_core/internal/helper_task_iface.h"
|
||||
#include "../gmio_core/internal/locale_utils.h"
|
||||
#include "../gmio_core/internal/min_max.h"
|
||||
#include "../gmio_core/internal/safe_cast.h"
|
||||
#include "../gmio_core/internal/stringstream.h"
|
||||
@ -114,11 +115,17 @@ int gmio_stla_read(
|
||||
struct gmio_stl_mesh_creator* mesh_creator,
|
||||
const struct gmio_stl_read_options* opts)
|
||||
{
|
||||
const bool check_lcnum =
|
||||
opts != NULL ? !opts->stla_dont_check_lc_numeric : true;
|
||||
struct gmio_memblock_helper mblock_helper =
|
||||
gmio_memblock_helper(opts != NULL ? &opts->stream_memblock : NULL);
|
||||
struct gmio_memblock* const mblock = &mblock_helper.memblock;
|
||||
char fixed_buffer[GMIO_STLA_READ_STRING_MAX_LEN];
|
||||
struct gmio_stla_parse_data parse_data;
|
||||
int error = GMIO_ERROR_OK;
|
||||
|
||||
if (check_lcnum && !gmio_check_lc_numeric(&error))
|
||||
goto label_end;
|
||||
|
||||
parse_data.token = unknown_token;
|
||||
parse_data.error = false;
|
||||
@ -145,13 +152,14 @@ int gmio_stla_read(
|
||||
|
||||
parse_solid(&parse_data);
|
||||
|
||||
gmio_memblock_helper_release(&mblock_helper);
|
||||
|
||||
if (parse_data.error)
|
||||
return GMIO_STL_ERROR_PARSING;
|
||||
error = GMIO_STL_ERROR_PARSING;
|
||||
if (parse_data.strstream_cookie.is_stop_requested)
|
||||
return GMIO_ERROR_TRANSFER_STOPPED;
|
||||
return GMIO_ERROR_OK;
|
||||
error = GMIO_ERROR_TRANSFER_STOPPED;
|
||||
|
||||
label_end:
|
||||
gmio_memblock_helper_release(&mblock_helper);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,9 +35,10 @@ const char* all_tests()
|
||||
UTEST_RUN(test_internal__byte_swap);
|
||||
UTEST_RUN(test_internal__byte_codec);
|
||||
UTEST_RUN(test_internal__fast_atof);
|
||||
UTEST_RUN(test_internal__locale_utils);
|
||||
UTEST_RUN(test_internal__safe_cast);
|
||||
UTEST_RUN(test_internal__stringstream);
|
||||
UTEST_RUN(test_internal__string_utils);
|
||||
UTEST_RUN(test_internal__string_ascii_utils);
|
||||
UTEST_RUN(test_internal__benchmark_gmio_fast_atof);
|
||||
|
||||
return NULL;
|
||||
|
@ -46,6 +46,7 @@ const char* all_tests()
|
||||
|
||||
UTEST_RUN(test_stl_read);
|
||||
UTEST_RUN(test_stl_read_multi_solid);
|
||||
UTEST_RUN(test_stla_lc_numeric);
|
||||
UTEST_RUN(test_stla_write);
|
||||
UTEST_RUN(test_stlb_read);
|
||||
UTEST_RUN(test_stlb_write);
|
||||
|
@ -17,16 +17,19 @@
|
||||
|
||||
#include "stream_buffer.h"
|
||||
|
||||
#include "../src/gmio_core/error.h"
|
||||
#include "../src/gmio_core/internal/byte_codec.h"
|
||||
#include "../src/gmio_core/internal/byte_swap.h"
|
||||
#include "../src/gmio_core/internal/convert.h"
|
||||
#include "../src/gmio_core/internal/fast_atof.h"
|
||||
#include "../src/gmio_core/internal/locale_utils.h"
|
||||
#include "../src/gmio_core/internal/numeric_utils.h"
|
||||
#include "../src/gmio_core/internal/safe_cast.h"
|
||||
#include "../src/gmio_core/internal/stringstream.h"
|
||||
#include "../src/gmio_core/internal/stringstream_fast_atof.h"
|
||||
#include "../src/gmio_core/internal/string_ascii_utils.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -264,7 +267,7 @@ static const char* test_internal__stringstream()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* test_internal__string_utils()
|
||||
static const char* test_internal__string_ascii_utils()
|
||||
{
|
||||
char c; /* for loop counter */
|
||||
|
||||
@ -328,3 +331,40 @@ static const char* test_internal__string_utils()
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* __tc__test_internal__locale_utils()
|
||||
{
|
||||
const char* lc = setlocale(LC_NUMERIC, "");
|
||||
if (lc != NULL
|
||||
&& gmio_ascii_stricmp(lc, "C") != 0
|
||||
&& gmio_ascii_stricmp(lc, "POSIX") != 0)
|
||||
{
|
||||
int error = GMIO_ERROR_OK;
|
||||
UTEST_ASSERT(!gmio_lc_numeric_is_C());
|
||||
UTEST_ASSERT(!gmio_check_lc_numeric(&error));
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_BAD_LC_NUMERIC, error);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\nskip: default locale is NULL or already C/POSIX");
|
||||
}
|
||||
|
||||
lc = setlocale(LC_NUMERIC, "C");
|
||||
if (lc != NULL) {
|
||||
int error = GMIO_ERROR_OK;
|
||||
UTEST_ASSERT(gmio_lc_numeric_is_C());
|
||||
UTEST_ASSERT(gmio_check_lc_numeric(&error));
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* test_internal__locale_utils()
|
||||
{
|
||||
const char* error_str = NULL;
|
||||
gmio_lc_numeric_save();
|
||||
printf("\ninfo: current locale is \"%s\"", gmio_lc_numeric());
|
||||
error_str = __tc__test_internal__locale_utils();
|
||||
gmio_lc_numeric_restore();
|
||||
return error_str;
|
||||
}
|
||||
|
@ -22,11 +22,13 @@
|
||||
#include "../src/gmio_core/error.h"
|
||||
#include "../src/gmio_core/internal/min_max.h"
|
||||
#include "../src/gmio_core/internal/string.h"
|
||||
#include "../src/gmio_core/internal/locale_utils.h"
|
||||
#include "../src/gmio_stl/stl_error.h"
|
||||
#include "../src/gmio_stl/stl_infos.h"
|
||||
#include "../src/gmio_stl/stl_io.h"
|
||||
#include "../src/gmio_stl/stl_io_options.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -342,6 +344,39 @@ static const char* test_stl_read_multi_solid()
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static const char* test_stla_lc_numeric()
|
||||
{
|
||||
struct gmio_stream null_stream = {0};
|
||||
const struct gmio_stl_mesh null_mesh = {0};
|
||||
struct gmio_stl_mesh_creator null_meshcreator = {0};
|
||||
int error[4] = {0};
|
||||
|
||||
gmio_lc_numeric_save();
|
||||
setlocale(LC_NUMERIC, "");
|
||||
if (!gmio_lc_numeric_is_C()) {
|
||||
struct gmio_stl_read_options read_opts = {0};
|
||||
struct gmio_stl_write_options write_opts = {0};
|
||||
|
||||
/* By default, check LC_NUMERIC */
|
||||
error[0] = gmio_stla_read(&null_stream, &null_meshcreator, NULL);
|
||||
error[1] = gmio_stl_write(
|
||||
GMIO_STL_FORMAT_ASCII, &null_stream, &null_mesh, NULL);
|
||||
error[2] = gmio_stla_read(&null_stream, &null_meshcreator, &read_opts);
|
||||
error[3] = gmio_stl_write(
|
||||
GMIO_STL_FORMAT_ASCII, &null_stream, &null_mesh, &write_opts);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\nskip: default locale is NULL or already C/POSIX");
|
||||
}
|
||||
gmio_lc_numeric_restore();
|
||||
for (size_t i = 0; i < GMIO_ARRAY_SIZE(error); ++i) {
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_BAD_LC_NUMERIC, error[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void generate_stlb_tests_models()
|
||||
{
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user