Add more C99 compat functions

This commit is contained in:
Hugues Delorme 2016-03-14 17:02:30 +01:00
parent 2f873e3089
commit 33317b2613
8 changed files with 86 additions and 26 deletions

View File

@ -126,7 +126,8 @@ if(NOT GMIO_BUILD_STRICT_C90)
if(CMAKE_C_COMPILER_IS_GCC_COMPATIBLE) if(CMAKE_C_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND CMAKE_REQUIRED_LIBRARIES m) # -lm list(APPEND CMAKE_REQUIRED_LIBRARIES m) # -lm
endif() endif()
check_function_exists(powf GMIO_HAVE_POWF_FUNC) check_function_exists(powf GMIO_HAVE_POWF_FUNC)
check_function_exists(sqrtf GMIO_HAVE_SQRTF_FUNC)
set(CMAKE_REQUIRED_LIBRARIES) # Pop changes set(CMAKE_REQUIRED_LIBRARIES) # Pop changes
check_include_files(stdbool.h GMIO_HAVE_STDBOOL_H) check_include_files(stdbool.h GMIO_HAVE_STDBOOL_H)
@ -294,6 +295,8 @@ if(GMIO_BUILD_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif() endif()
message(STATUS "CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}")
# Examples: # Examples:
# cmake -DCMAKE_INSTALL_PREFIX=gcc-linux64 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=_d # cmake -DCMAKE_INSTALL_PREFIX=gcc-linux64 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=_d
# cmake -DCMAKE_INSTALL_PREFIX=gcc-linux64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_RELEASE_POSTFIX= # cmake -DCMAKE_INSTALL_PREFIX=gcc-linux64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_RELEASE_POSTFIX=

View File

@ -0,0 +1,39 @@
/****************************************************************************
** gmio
** Copyright Fougue (2 Mar. 2015)
** 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".
****************************************************************************/
#ifndef GMIO_INTERNAL_C99_MATH_COMPAT_H
#define GMIO_INTERNAL_C99_MATH_COMPAT_H
#include "../global.h"
#include <math.h>
#ifdef GMIO_HAVE_POWF_FUNC
# define gmio_powf powf
#else
/* No powf() function, call pow(double) as fallback */
GMIO_INLINE float gmio_powf(float x)
{ return (float)pow((double)x); }
#endif
#ifdef GMIO_HAVE_SQRTF_FUNC
# define gmio_sqrtf sqrtf
#else
/* No sqrtf() function, call sqrt(double) as fallback */
GMIO_INLINE float gmio_sqrtf(float x)
{ return (float)sqrt((double)x); }
#endif
#endif /* GMIO_INTERNAL_C99_MATH_COMPAT_H */

View File

@ -33,7 +33,7 @@
#elif defined(GMIO_HAVE_WIN__VSNPRINTF_FUNC) #elif defined(GMIO_HAVE_WIN__VSNPRINTF_FUNC)
# define gmio_vsnprintf _vsnprintf # define gmio_vsnprintf _vsnprintf
#else #else
/* No existing vsnprintf()-like function, call unsafe vsprintf() as fallback */ /* No vsnprintf()-like function, call unsafe vsprintf() as fallback */
GMIO_INLINE int gmio_vsnprintf( GMIO_INLINE int gmio_vsnprintf(
char* buf, size_t bufn, const char* fmt, va_list args) char* buf, size_t bufn, const char* fmt, va_list args)
{ {
@ -53,7 +53,7 @@ GMIO_INLINE int gmio_vsnprintf(
#elif defined(GMIO_HAVE_WIN__SNPRINTF_FUNC) #elif defined(GMIO_HAVE_WIN__SNPRINTF_FUNC)
# define gmio_snprintf _snprintf # define gmio_snprintf _snprintf
#else #else
/* No existing snprintf()-like function, translate to gmio_vsnprintf() call */ /* No snprintf()-like function, translate to gmio_vsnprintf() call */
GMIO_INLINE int gmio_snprintf(char* buf, size_t bufn, const char* fmt, ...) GMIO_INLINE int gmio_snprintf(char* buf, size_t bufn, const char* fmt, ...)
{ {
int ret = 0; int ret = 0;

View File

@ -0,0 +1,31 @@
/****************************************************************************
** gmio
** Copyright Fougue (2 Mar. 2015)
** 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".
****************************************************************************/
#ifndef GMIO_INTERNAL_C99_STDLIB_COMPAT_H
#define GMIO_INTERNAL_C99_STDLIB_COMPAT_H
#include "../global.h"
#include <stdlib.h>
#ifdef GMIO_HAVE_STRTOF_FUNC
# define gmio_strtof strtof
#else
/* No strtof() function, call strtod() as fallback */
GMIO_INLINE float gmio_strtof(const char* str, char** endptr)
{ return (float)strtod(str, endptr); }
#endif
#endif /* GMIO_INTERNAL_C99_STDLIB_COMPAT_H */

View File

@ -10,6 +10,7 @@
#define GMIO_INTERNAL_FAST_ATOF_H #define GMIO_INTERNAL_FAST_ATOF_H
#include "../global.h" #include "../global.h"
#include "c99_math_compat.h"
#include "string_ascii_utils.h" #include "string_ascii_utils.h"
#include <float.h> #include <float.h>
@ -375,12 +376,7 @@ GMIO_INLINE const char* fast_atof_move(const char* in, float* result)
/* Assume that the exponent is a whole number. /* Assume that the exponent is a whole number.
* strtol10() will deal with both + and - signs, * strtol10() will deal with both + and - signs,
* but calculate as float to prevent overflow at FLT_MAX */ * but calculate as float to prevent overflow at FLT_MAX */
value *= value *= gmio_powf(10.f, (float)strtol10(in, &in));
#ifdef GMIO_HAVE_POWF_FUNC
powf(10.f, (float)strtol10(in, &in));
#else
(float)pow(10., (double)strtol10(in, &in));
#endif
} }
*result = negative ? -value : value; *result = negative ? -value : value;
return in; return in;

View File

@ -129,6 +129,7 @@ GMIO_INLINE float gmio_to_float32(const char* str);
* -- Implementation * -- Implementation
*/ */
#include "c99_stdlib_compat.h"
#include "helper_stream.h" #include "helper_stream.h"
#include "string_ascii_utils.h" #include "string_ascii_utils.h"
#ifdef GMIO_STRINGSTREAM_USE_FAST_ATOF #ifdef GMIO_STRINGSTREAM_USE_FAST_ATOF
@ -137,7 +138,6 @@ GMIO_INLINE float gmio_to_float32(const char* str);
#endif #endif
#include <errno.h> #include <errno.h>
#include <stdlib.h>
const char* gmio_stringstream_current_char( const char* gmio_stringstream_current_char(
const struct gmio_stringstream* sstream) const struct gmio_stringstream* sstream)
@ -206,12 +206,9 @@ int gmio_get_float32(const char* str, float* value_ptr)
#if defined(GMIO_STRINGSTREAM_USE_FAST_ATOF) #if defined(GMIO_STRINGSTREAM_USE_FAST_ATOF)
const char* end_ptr = NULL; const char* end_ptr = NULL;
*value_ptr = fast_strtof(str, &end_ptr); *value_ptr = fast_strtof(str, &end_ptr);
#elif defined(GMIO_HAVE_STRTOF_FUNC) /* Requires C99 */
char* end_ptr = NULL;
*value_ptr = strtof(str, &end_ptr);
#else #else
char* end_ptr = NULL; char* end_ptr = NULL;
*value_ptr = (float)strtod(str, &end_ptr); *value_ptr = gmio_strtof(str, &end_ptr);
#endif #endif
return (end_ptr == str || errno == ERANGE) ? -1 : 0; return (end_ptr == str || errno == ERANGE) ? -1 : 0;
} }
@ -220,10 +217,8 @@ float gmio_to_float32(const char* str)
{ {
#if defined(GMIO_STRINGSTREAM_USE_FAST_ATOF) #if defined(GMIO_STRINGSTREAM_USE_FAST_ATOF)
return fast_atof(str); return fast_atof(str);
#elif defined(GMIO_HAVE_STRTOF_FUNC) /* Requires C99 */
return strtof(str, NULL);
#else #else
return (float)strtod(str, NULL); return gmio_strtof(str, NULL);
#endif #endif
} }
@ -233,7 +228,7 @@ float gmio_stringstream_parse_float32(struct gmio_stringstream* sstream)
return gmio_stringstream_fast_atof(sstream); return gmio_stringstream_fast_atof(sstream);
#else #else
char strbuff_ptr[64]; char strbuff_ptr[64];
struct gmio_string strbuff = { &strbuff_ptr[0], 0, sizeof(strbuff_ptr) }; struct gmio_string strbuff = { strbuff_ptr, 0, sizeof(strbuff_ptr) };
gmio_stringstream_eat_word(sstream, &strbuff); gmio_stringstream_eat_word(sstream, &strbuff);
return (float)atof(strbuff_ptr); return (float)atof(strbuff_ptr);
#endif #endif

View File

@ -10,6 +10,7 @@
#define GMIO_INTERNAL_STRINGSTREAM_FAST_ATOF_H #define GMIO_INTERNAL_STRINGSTREAM_FAST_ATOF_H
#include "fast_atof.h" #include "fast_atof.h"
#include "c99_math_compat.h"
#include "stringstream.h" #include "stringstream.h"
GMIO_INLINE uint32_t gmio_stringstream_strtoul10( GMIO_INLINE uint32_t gmio_stringstream_strtoul10(
@ -105,12 +106,7 @@ GMIO_INLINE float gmio_stringstream_fast_atof(struct gmio_stringstream* sstream)
/* Assume that the exponent is a whole number. /* Assume that the exponent is a whole number.
* strtol10() will deal with both + and - signs, * strtol10() will deal with both + and - signs,
* but calculate as float to prevent overflow at FLT_MAX */ * but calculate as float to prevent overflow at FLT_MAX */
value *= value *= gmio_powf(10.f, (float)gmio_stringstream_strtol10(sstream));
#ifdef GMIO_HAVE_POWF_FUNC
powf(10.f, (float)gmio_stringstream_strtol10(sstream));
#else
(float)pow(10., (double)gmio_stringstream_strtol10(sstream));
#endif
} }
return negative ? -value : value; return negative ? -value : value;
} }

View File

@ -46,7 +46,7 @@ GMIO_INLINE void gmio_vec3d_normalize(struct gmio_vec3d* v);
* Implementation * Implementation
*/ */
#include <math.h> #include "c99_math_compat.h"
void gmio_vec3f_cross_product( void gmio_vec3f_cross_product(
const struct gmio_vec3f* u, const struct gmio_vec3f* u,
@ -88,7 +88,7 @@ double gmio_vec3d_sqr_length(const struct gmio_vec3d* v)
void gmio_vec3f_normalize(struct gmio_vec3f* v) void gmio_vec3f_normalize(struct gmio_vec3f* v)
{ {
const float d = (float)sqrt(gmio_vec3f_sqr_length(v)); const float d = gmio_sqrtf(gmio_vec3f_sqr_length(v));
if (d > 0.f) { if (d > 0.f) {
v->x /= d; v->x /= d;
v->y /= d; v->y /= d;