snprintf() fix

This commit is contained in:
Pavel Kirienko
2015-03-21 16:01:16 +03:00
parent 71d4b02a7f
commit bc5d07ab2a
2 changed files with 41 additions and 9 deletions
@@ -134,6 +134,14 @@
# define UAVCAN_IMPLEMENT_PLACEMENT_NEW 0
#endif
/**
* Allows the user's application to provide custom implementation of uavcan::snprintf(),
* which is often useful on deeply embedded systems.
*/
#ifndef UAVCAN_USE_EXTERNAL_SNPRINTF
# define UAVCAN_USE_EXTERNAL_SNPRINTF 0
#endif
/**
* Run time checks.
* Resolves to the standard assert() by default.
+33 -9
View File
@@ -2,11 +2,11 @@
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#ifndef UAVCAN_STDINT_HPP_INCLUDED
#define UAVCAN_STDINT_HPP_INCLUDED
#ifndef UAVCAN_STD_HPP_INCLUDED
#define UAVCAN_STD_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <cstdio>
#include <cstdarg>
#if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
# error UAVCAN_CPP_VERSION
@@ -20,8 +20,6 @@
namespace uavcan
{
using std::snprintf; // Can be used to replace standard snprintf() with a user-provided one.
typedef std::uint8_t uint8_t;
typedef std::uint16_t uint16_t;
typedef std::uint32_t uint32_t;
@@ -37,13 +35,11 @@ typedef std::int64_t int64_t;
#else
# include <stdint.h> // Standard integer types from C library
# include <stdio.h> // snprintf() from the C library
# include <stdio.h> // vsnprintf() from the C library
namespace uavcan
{
using ::snprintf;
typedef ::uint8_t uint8_t;
typedef ::uint16_t uint16_t;
typedef ::uint32_t uint32_t;
@@ -58,4 +54,32 @@ typedef ::int64_t int64_t;
#endif
#endif // UAVCAN_STDINT_HPP_INCLUDED
namespace uavcan
{
/**
* Wrapper over the standard snprintf(). This wrapper is needed because different standards and different
* implementations of C++ do not agree whether snprintf() should be defined in std:: or in ::. The solution
* is to use 'using namespace std' hack inside the wrapper, so the compiler will be able to pick whatever
* definition is available in the standard library. Alternatively, the user's application can provide a
* custom implementation of uavcan::snprintf().
*/
#if __GNUC__
__attribute__ ((format(printf, 3, 4)))
#endif
extern int snprintf(char* out, std::size_t maxlen, const char* format, ...);
#if !UAVCAN_USE_EXTERNAL_SNPRINTF
inline int snprintf(char* out, std::size_t maxlen, const char* format, ...)
{
using namespace std; // This way we can pull vsnprintf() either from std:: or from ::.
va_list args;
va_start(args, format);
const int return_value = vsnprintf(out, maxlen, format, args);
va_end(args);
return return_value;
}
#endif
}
#endif // UAVCAN_STD_HPP_INCLUDED