diff --git a/src/bluetooth.c b/src/bluetooth.c index 1889bf7..aa5f05a 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -24,7 +24,6 @@ #endif #include // malloc, free -#include #include "socket.h" @@ -231,7 +230,7 @@ dc_bluetooth_addr2str(dc_bluetooth_address_t address, char *str, size_t size) if (str == NULL || size < DC_BLUETOOTH_SIZE) return NULL; - int n = snprintf(str, size, "%02X:%02X:%02X:%02X:%02X:%02X", + int n = dc_platform_snprintf(str, size, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned char)((address >> 40) & 0xFF), (unsigned char)((address >> 32) & 0xFF), (unsigned char)((address >> 24) & 0xFF), diff --git a/src/context-private.h b/src/context-private.h index 7f50a68..fed80e5 100644 --- a/src/context-private.h +++ b/src/context-private.h @@ -28,6 +28,8 @@ #include +#include "platform.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -40,12 +42,6 @@ extern "C" { #define FUNCTION __FUNCTION__ #endif -#if defined(__GNUC__) -#define ATTR_FORMAT_PRINTF(a,b) __attribute__((format(printf, a, b))) -#else -#define ATTR_FORMAT_PRINTF(a,b) -#endif - #ifdef ENABLE_LOGGING #define HEXDUMP(context, loglevel, prefix, data, size) dc_context_hexdump (context, loglevel, __FILE__, __LINE__, FUNCTION, prefix, data, size) #define SYSERROR(context, errcode) dc_context_syserror (context, DC_LOGLEVEL_ERROR, __FILE__, __LINE__, FUNCTION, errcode) @@ -63,7 +59,7 @@ extern "C" { #endif dc_status_t -dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *format, ...) ATTR_FORMAT_PRINTF(6, 7); +dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *format, ...) DC_ATTR_FORMAT_PRINTF(6, 7); dc_status_t dc_context_syserror (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, int errcode); diff --git a/src/context.c b/src/context.c index 21c1610..8e32f78 100644 --- a/src/context.c +++ b/src/context.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -36,6 +35,7 @@ #endif #include "context-private.h" +#include "platform.h" #include "timer.h" struct dc_context_t { @@ -49,55 +49,6 @@ struct dc_context_t { }; #ifdef ENABLE_LOGGING -/* - * A wrapper for the vsnprintf function, which will always null terminate the - * string and returns a negative value if the destination buffer is too small. - */ -static int -l_vsnprintf (char *str, size_t size, const char *format, va_list ap) -{ - int n; - - if (size == 0) - return -1; - -#ifdef _MSC_VER - /* - * The non-standard vsnprintf implementation provided by MSVC doesn't null - * terminate the string and returns a negative value if the destination - * buffer is too small. - */ - n = _vsnprintf (str, size - 1, format, ap); - if (n == size - 1 || n < 0) - str[size - 1] = 0; -#else - /* - * The C99 vsnprintf function will always null terminate the string. If the - * destination buffer is too small, the return value is the number of - * characters that would have been written if the buffer had been large - * enough. - */ - n = vsnprintf (str, size, format, ap); - if (n >= 0 && (size_t) n >= size) - n = -1; -#endif - - return n; -} - -static int -l_snprintf (char *str, size_t size, const char *format, ...) -{ - va_list ap; - int n; - - va_start (ap, format); - n = l_vsnprintf (str, size, format, ap); - va_end (ap); - - return n; -} - static int l_hexdump (char *str, size_t size, const unsigned char data[], size_t n) { @@ -244,7 +195,7 @@ dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, return DC_STATUS_SUCCESS; va_start (ap, format); - l_vsnprintf (context->msg, sizeof (context->msg), format, ap); + dc_platform_vsnprintf (context->msg, sizeof (context->msg), format, ap); va_end (ap); context->logfunc (context, loglevel, file, line, function, context->msg, context->userdata); @@ -310,7 +261,7 @@ dc_context_hexdump (dc_context_t *context, dc_loglevel_t loglevel, const char *f if (context->logfunc == NULL) return DC_STATUS_SUCCESS; - n = l_snprintf (context->msg, sizeof (context->msg), "%s: size=%u, data=", prefix, size); + n = dc_platform_snprintf (context->msg, sizeof (context->msg), "%s: size=%u, data=", prefix, size); if (n >= 0) { n = l_hexdump (context->msg + n, sizeof (context->msg) - n, data, size); diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index 550bf7c..629e482 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -1447,7 +1447,7 @@ hw_ostc3_device_fwupdate3 (dc_device_t *abstract, const char *filename) for (unsigned int len = 0; len < SZ_FIRMWARE; len += SZ_FIRMWARE_BLOCK) { char status[SZ_DISPLAY + 1]; // Status message on the display - snprintf (status, sizeof(status), " Uploading %2d%%", (100 * len) / SZ_FIRMWARE); + dc_platform_snprintf (status, sizeof(status), " Uploading %2d%%", (100 * len) / SZ_FIRMWARE); hw_ostc3_device_display (abstract, status); rc = hw_ostc3_firmware_block_write (device, FIRMWARE_AREA + len, firmware->data + len, SZ_FIRMWARE_BLOCK); @@ -1466,7 +1466,7 @@ hw_ostc3_device_fwupdate3 (dc_device_t *abstract, const char *filename) for (unsigned int len = 0; len < SZ_FIRMWARE; len += SZ_FIRMWARE_BLOCK) { unsigned char block[SZ_FIRMWARE_BLOCK]; char status[SZ_DISPLAY + 1]; // Status message on the display - snprintf (status, sizeof(status), " Verifying %2d%%", (100 * len) / SZ_FIRMWARE); + dc_platform_snprintf (status, sizeof(status), " Verifying %2d%%", (100 * len) / SZ_FIRMWARE); hw_ostc3_device_display (abstract, status); rc = hw_ostc3_firmware_block_read (device, FIRMWARE_AREA + len, block, sizeof (block)); diff --git a/src/irda.c b/src/irda.c index 8c5d612..a5bb8e4 100644 --- a/src/irda.c +++ b/src/irda.c @@ -24,7 +24,6 @@ #endif #include // malloc, free -#include // snprintf #include #include "socket.h" @@ -314,7 +313,7 @@ dc_irda_open (dc_iostream_t **out, dc_context_t *context, unsigned int address, peer.irdaDeviceID[1] = (address >> 8) & 0xFF; peer.irdaDeviceID[2] = (address >> 16) & 0xFF; peer.irdaDeviceID[3] = (address >> 24) & 0xFF; - snprintf (peer.irdaServiceName, sizeof(peer.irdaServiceName), "LSAP-SEL%u", lsap); + dc_platform_snprintf (peer.irdaServiceName, sizeof(peer.irdaServiceName), "LSAP-SEL%u", lsap); #else struct sockaddr_irda peer; peer.sir_family = AF_IRDA; diff --git a/src/platform.c b/src/platform.c index 16a3c08..4164549 100644 --- a/src/platform.c +++ b/src/platform.c @@ -28,6 +28,8 @@ #include #endif +#include + #include "platform.h" int @@ -49,3 +51,48 @@ dc_platform_sleep (unsigned int milliseconds) return 0; } + +int +dc_platform_vsnprintf (char *str, size_t size, const char *format, va_list ap) +{ + int n = 0; + + if (size == 0) + return -1; + +#ifdef _MSC_VER + /* + * The non-standard vsnprintf implementation provided by MSVC doesn't null + * terminate the string and returns a negative value if the destination + * buffer is too small. + */ + n = _vsnprintf (str, size - 1, format, ap); + if (n == size - 1 || n < 0) + str[size - 1] = 0; +#else + /* + * The C99 vsnprintf function will always null terminate the string. If the + * destination buffer is too small, the return value is the number of + * characters that would have been written if the buffer had been large + * enough. + */ + n = vsnprintf (str, size, format, ap); + if (n >= 0 && (size_t) n >= size) + n = -1; +#endif + + return n; +} + +int +dc_platform_snprintf (char *str, size_t size, const char *format, ...) +{ + va_list ap; + int n = 0; + + va_start (ap, format); + n = dc_platform_vsnprintf (str, size, format, ap); + va_end (ap); + + return n; +} diff --git a/src/platform.h b/src/platform.h index 438aa7d..a652503 100644 --- a/src/platform.h +++ b/src/platform.h @@ -22,10 +22,18 @@ #ifndef DC_PLATFORM_H #define DC_PLATFORM_H +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#if defined(__GNUC__) +#define DC_ATTR_FORMAT_PRINTF(a,b) __attribute__((format(printf, a, b))) +#else +#define DC_ATTR_FORMAT_PRINTF(a,b) +#endif + #ifdef _WIN32 #define DC_PRINTF_SIZE "%Iu" #else @@ -33,7 +41,6 @@ extern "C" { #endif #ifdef _MSC_VER -#define snprintf _snprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp #if _MSC_VER < 1800 @@ -47,6 +54,13 @@ extern "C" { int dc_platform_sleep(unsigned int milliseconds); +/* + * A wrapper for the vsnprintf function, which will always null terminate the + * string and returns a negative value if the destination buffer is too small. + */ +int dc_platform_snprintf (char *str, size_t size, const char *format, ...) DC_ATTR_FORMAT_PRINTF(3, 4); +int dc_platform_vsnprintf (char *str, size_t size, const char *format, va_list ap) DC_ATTR_FORMAT_PRINTF(3, 0); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/serial_posix.c b/src/serial_posix.c index b23f69d..a189e15 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -37,7 +37,6 @@ #ifdef HAVE_IOKIT_SERIAL_IOSS_H #include #endif -#include #include #include #include @@ -226,7 +225,7 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out) continue; char filename[sizeof(device->name)]; - int n = snprintf (filename, sizeof (filename), "%s/%s", DIRNAME, ep->d_name); + int n = dc_platform_snprintf (filename, sizeof (filename), "%s/%s", DIRNAME, ep->d_name); if (n < 0 || (size_t) n >= sizeof (filename)) { return DC_STATUS_NOMEMORY; } diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index 2d8122c..6ffc7bc 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -897,7 +897,7 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac break; } - len = snprintf(pathname, sizeof(pathname), "%s/%s", dive_directory, de->name); + len = dc_platform_snprintf(pathname, sizeof(pathname), "%s/%s", dive_directory, de->name); if (len < 0 || (unsigned int) len >= sizeof(pathname)) { dc_status_set_error(&status, DC_STATUS_PROTOCOL); break;