Replace some sprintf() calls with snprintf()

This commit is contained in:
Hugues Delorme 2016-03-10 15:23:01 +01:00
parent aa372aa507
commit 47123e2d26
5 changed files with 59 additions and 23 deletions

View File

@ -135,6 +135,11 @@ if(NOT GMIO_BUILD_STRICT_C90)
if(WIN32 AND NOT GMIO_HAVE_SNPRINTF_FUNC)
check_function_exists(_snprintf GMIO_HAVE_WIN__SNPRINTF_FUNC)
endif()
check_function_exists(vsnprintf GMIO_HAVE_VSNPRINTF_FUNC)
if(WIN32 AND NOT GMIO_HAVE_VSNPRINTF_FUNC)
check_function_exists(_vsnprintf GMIO_HAVE_WIN__VSNPRINTF_FUNC)
endif()
endif()
# Check POSIX features

View File

@ -28,6 +28,9 @@
# define BENCHMARK_TIMER_LIBC
#endif
#include "../../src/gmio_core/internal/c99_stdio_compat.h"
#include "../../src/gmio_core/internal/string.h"
/* Benchmark timers */
struct benchmark_timer
@ -78,26 +81,27 @@ static gmio_time_ms_t benchmark_timer_elapsed_ms(const struct benchmark_timer* t
/* Wraps around formatted printing functions */
/*! Wrap around sprintf() to be used with gprintf_func_exec_time() */
static void sprintf_wrap(void* cookie, const char* fmt, ...)
/*! Wrap around snprintf() to be used with gprintf_func_exec_time() */
static void snprintf_wrap(void* cookie, const char* fmt, ...)
{
struct gmio_string* str = (struct gmio_string*)cookie;
va_list args;
va_start(args, fmt);
vsprintf((char*)cookie, fmt, args);
gmio_vsnprintf(str->ptr, str->max_len, fmt, args);
va_end(args);
}
/*! Wrap around printf() to be used with gprintf_func_exec_time() */
static void printf_wrap(void* cookie, const char* fmt, ...)
/*! Wrap around fprintf() to be used with gprintf_func_exec_time() */
static void fprintf_wrap(void* cookie, const char* fmt, ...)
{
FILE* file = (FILE*)cookie;
va_list args;
GMIO_UNUSED(cookie);
va_start(args, fmt);
vprintf(fmt, args);
vfprintf(file, fmt, args);
va_end(args);
}
/*! Typedef on pointer to printf-wrap functions(eg. sprintf_wrap()) */
/*! Typedef on pointer to printf-wrap functions(eg. snprintf_wrap()) */
typedef void (*func_gprintf_t)(void*, const char*, ...);
@ -133,7 +137,7 @@ static const char n_a[] = "N/A";
static void gprintf_func_string(
/* Annex data for func_gprintf (ex: char* for sprintf()) */
void* cookie,
/* Function ptr on a printf wrap (ex: sprintf_wrap()) */
/* Function ptr on a printf wrap (ex: snprintf_wrap()) */
func_gprintf_t func_gprintf,
/* Width of the print column, if any (can be == 0) */
size_t width_column,
@ -157,7 +161,11 @@ static void gprintf_func_exec_time(
if (has_time) {
char str_time[128] = {0};
/* TODO: %ull is not accepted by mingw, find a fix(maybe %ul64) */
sprintf(str_time, "%u%s", (unsigned)time, unit_time_str);
gmio_snprintf(str_time,
sizeof(str_time),
"%u%s",
(unsigned)time,
unit_time_str);
gprintf_func_string(cookie, func_gprintf, width_column, str_time);
}
else {
@ -174,7 +182,7 @@ static void gprintf_func_exec_ratio(
{
if (!(ratio < 0)) { /* Valid ratio */
char str_ratio[128] = {0};
sprintf(str_ratio, "%.2f", ratio);
gmio_snprintf(str_ratio, sizeof(str_ratio), "%.2f", ratio);
gprintf_func_string(cookie, func_gprintf, width_column, str_ratio);
}
else {
@ -189,7 +197,7 @@ static void printf_func_exec_time(
bool has_time)
{
gprintf_func_exec_time(
NULL, &printf_wrap, width_column, time_ms, has_time);
stdout, &fprintf_wrap, width_column, time_ms, has_time);
}
/*! Returns the strlen of the longest tag string */
@ -234,13 +242,14 @@ static size_t find_maxlen_cmp_result_func_exec_time(
func_select_cmp_result_func_exec_infos_t func_select_exec_infos)
{
char strbuff[1024] = {0};
struct gmio_string str = gmio_string(strbuff, 0, sizeof(strbuff));
size_t max_len = 0;
size_t i;
for (i = 0; i < res_array.count; ++i) {
gmio_time_ms_t time = 0;
bool has_time = false;
func_select_exec_infos(&res_array.ptr[i], &time, &has_time);
gprintf_func_exec_time(strbuff, &sprintf_wrap, 0, time, has_time);
gprintf_func_exec_time(&str, &snprintf_wrap, 0, time, has_time);
max_len = size_t_max(safe_strlen(strbuff), max_len);
}
return max_len;
@ -251,11 +260,12 @@ static size_t find_maxlen_cmp_result_ratio(
struct benchmark_cmp_result_array res_array)
{
char strbuff[1024] = {0};
struct gmio_string str = gmio_string(strbuff, 0, sizeof(strbuff));
size_t max_len = 0;
size_t i;
for (i = 0; i < res_array.count; ++i) {
const float ratio = res_array.ptr[i].func2_func1_ratio;
gprintf_func_exec_ratio(strbuff, &sprintf_wrap, 0, ratio);
gprintf_func_exec_ratio(&str, &snprintf_wrap, 0, ratio);
max_len = size_t_max(safe_strlen(strbuff), max_len);
}
return max_len;
@ -404,7 +414,7 @@ void benchmark_print_results(
result.has_func2_exec_time);
printf(" | ");
gprintf_func_exec_ratio(
NULL, printf_wrap,
stdout, fprintf_wrap,
width_ratio_col, result.func2_func1_ratio);
printf("\n");
}

View File

@ -44,6 +44,8 @@
#cmakedefine GMIO_HAVE_POWF_FUNC
#cmakedefine GMIO_HAVE_SNPRINTF_FUNC
#cmakedefine GMIO_HAVE_WIN__SNPRINTF_FUNC
#cmakedefine GMIO_HAVE_VSNPRINTF_FUNC
#cmakedefine GMIO_HAVE_WIN__VSNPRINTF_FUNC
/* POSIX */
#cmakedefine GMIO_HAVE_SYS_TYPES_H

View File

@ -18,29 +18,47 @@
#include "../global.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
/* Note:
* Visual C++ provides snprintf() since version 2015, before that it was
* used to provide only equivalent _snprintf()
* Visual C++ provides vsnprintf() since version 2005, before it used to
* provide only _vsnprintf()
*
* snprintf() appears in C99
* vsnprintf() appeared in C99
*/
#ifdef GMIO_HAVE_VSNPRINTF_FUNC
# define gmio_vsnprintf vsnprintf
#elif defined(GMIO_HAVE_WIN__VSNPRINTF_FUNC)
# define gmio_vsnprintf _vsnprintf
#else
/* No existing vsnprintf()-like function, call unsafe vsprintf() as fallback */
GMIO_INLINE int gmio_vsnprintf(
char* buf, size_t bufn, const char* fmt, va_list args)
{
return vsprintf(buf, fmt, args);
}
#endif
/* Note:
* Visual C++ provides snprintf() since version 2015, before it used to
* provide only _snprintf()
*
* snprintf() appeared in C99
*/
#ifdef GMIO_HAVE_SNPRINTF_FUNC
# define gmio_snprintf snprintf
#elif defined(GMIO_HAVE_WIN__SNPRINTF_FUNC)
# define gmio_snprintf _snprintf
#else
# include <stdarg.h>
/* No existing snprintf()-like function, call unsafe vsprintf() as fallback */
/* No existing snprintf()-like function, translate to gmio_vsnprintf() call */
GMIO_INLINE int gmio_snprintf(char* buf, size_t bufn, const char* fmt, ...)
{
int ret = 0;
va_list args;
va_start(args, fmt);
ret = vsprintf(buf, fmt, args);
ret = gmio_vsnprintf(buf, bufn, fmt, args);
va_end(args);
return ret;
}

View File

@ -16,6 +16,7 @@
#include "utest_assert.h"
#include "../benchmarks/commons/benchmark_tools.h"
#include "../src/gmio_core/internal/c99_stdio_compat.h"
#include "../src/gmio_core/internal/fast_atof.h"
#include <stdio.h>
@ -49,9 +50,9 @@ static void test_internal__run_atof(float (*func_atof)(const char*))
for (i = 0; i < GMIO_ARRAY_SIZE(float_array); ++i) {
const float f = float_array[i];
float fres = 0.f;
sprintf(strbuff, "%f", f);
gmio_snprintf(strbuff, sizeof(strbuff), "%f", f);
fres = func_atof(strbuff);
sprintf(strbuff, "%E", f);
gmio_snprintf(strbuff, sizeof(strbuff), "%E", f);
fres = func_atof(strbuff);
}
}