#ifdef __GNUC__
#define attribute(x) __attribute__(x)
#else
#define attribute(x)
#endif
namespace alx {
// va_list version
int sprintf(char *str, std::ptrdiff_t *written,
std::ptrdiff_t buf_size, const char *format, va_list ap)
attribute((format (printf, 4, 0)));
// general version
int sprintf(char *str, std::ptrdiff_t *written,
std::ptrdiff_t buf_size, const char *format, ...)
#ifdef __GNUC__
__attribute__attribute((format (printf, 4, 5)))
#endif
;
// deduce size from buffer argument
template<std::size_t N>
int sprintf(char(&buff)[N], std::ptrdiff_t *written,
const char *fmt, ...)
#ifdef __GNUC__
__attribute__attribute((format (printf, 3, 4)))
#endif
;
}
#undef attribute
// template definition
template<std::size_t N>
int alx::sprintf(char(&buff)[N], std::ptrdiff_t *written,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int result = alx::sprintf(buff, written, N, fmt, ap);
va_end(ap);
return result;
}