1
0
Fork 0

feat(printf): add vsnprintf function

fixes #5
development
Marco Paland 7 years ago
parent 0e2a4175f6
commit cd4481a6f2

@ -30,19 +30,21 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "printf.h" #include "printf.h"
// buffer size used for printf (created on stack) // buffer size used omly for printf (created on stack)
#define PRINTF_BUFFER_SIZE 128U #define PRINTF_BUFFER_SIZE 128U
// ntoa conversion buffer size, this must be big enough to hold one converted numeric number (created on stack) // ntoa conversion buffer size, this must be big enough to hold
// one converted numeric number including padded zeros (created on stack)
#define PRINTF_NTOA_BUFFER_SIZE 32U #define PRINTF_NTOA_BUFFER_SIZE 32U
// ftoa conversion buffer size, this must be big enough to hold one converted float number (created on stack) // ftoa conversion buffer size, this must be big enough to hold
// one converted float number including padded zeros (created on stack)
#define PRINTF_FTOA_BUFFER_SIZE 32U #define PRINTF_FTOA_BUFFER_SIZE 32U
// define this to support floating point (%f) // define this to support floating point (%f)
@ -349,14 +351,14 @@ static size_t _ftoa(double value, char* buffer, size_t maxlen, unsigned int prec
// internal vsnprintf // internal vsnprintf
static size_t _vsnprintf(char* buffer, size_t buffer_len, const char* format, va_list va) static int _vsnprintf(char* buffer, size_t buffer_len, const char* format, va_list va)
{ {
unsigned int flags, width, precision, n; unsigned int flags, width, precision, n;
size_t idx = 0U; size_t idx = 0U;
// check if buffer is valid // check if buffer is valid
if (!buffer) { if (!buffer) {
return 0U; return -1;
} }
while ((idx < buffer_len) && *format) while ((idx < buffer_len) && *format)
@ -587,7 +589,7 @@ static size_t _vsnprintf(char* buffer, size_t buffer_len, const char* format, va
} }
// return written chars without terminating \0 // return written chars without terminating \0
return idx; return (int)idx;
} }
@ -598,12 +600,12 @@ int printf(const char* format, ...)
va_list va; va_list va;
va_start(va, format); va_start(va, format);
char buffer[PRINTF_BUFFER_SIZE]; char buffer[PRINTF_BUFFER_SIZE];
size_t ret = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, va); int ret = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, va);
va_end(va); va_end(va);
for (size_t i = 0U; i < ret; ++i) { for (size_t i = 0U; i < ret; ++i) {
_putchar(buffer[i]); _putchar(buffer[i]);
} }
return (int)ret; return ret;
} }
@ -611,9 +613,9 @@ int sprintf(char* buffer, const char* format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
size_t ret = _vsnprintf(buffer, (size_t)-1, format, va); int ret = _vsnprintf(buffer, (size_t)-1, format, va);
va_end(va); va_end(va);
return (int)ret; return ret;
} }
@ -621,7 +623,14 @@ int snprintf(char* buffer, size_t count, const char* format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
size_t ret = _vsnprintf(buffer, count, format, va); int ret = _vsnprintf(buffer, count, format, va);
va_end(va); va_end(va);
return (int)ret; return ret;
} }
inline int vsnprintf(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(buffer, count, format, va);
}

@ -32,7 +32,7 @@
#ifndef _PRINTF_H_ #ifndef _PRINTF_H_
#define _PRINTF_H_ #define _PRINTF_H_
#include <stddef.h> #include <stdarg.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -62,19 +62,21 @@ int printf(const char* format, ...);
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING SNPRINTF INSTEAD! * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING SNPRINTF INSTEAD!
* \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
* \param format A string that specifies the format of the output * \param format A string that specifies the format of the output
* \return The number of characters that are written into the array, not counting the terminating null character * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/ */
int sprintf(char* buffer, const char* format, ...); int sprintf(char* buffer, const char* format, ...);
/** /**
* Tiny snprintf implementation * Tiny snprintf/vsnprintf implementation
* \param buffer A pointer to the buffer where to store the formatted string * \param buffer A pointer to the buffer where to store the formatted string
* \param count The maximum number of characters to store in the buffer, INCLUDING the terminating null character * \param count The maximum number of characters to store in the buffer, including a terminating null character
* \param format A string that specifies the format of the output * \param format A string that specifies the format of the output
* \return The number of characters that are written into the array, not counting the terminating null character * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
* If the formatted string is truncated the buffer size (count) is returned
*/ */
int snprintf(char* buffer, size_t count, const char* format, ...); int snprintf(char* buffer, size_t count, const char* format, ...);
int vsnprintf(char* buffer, size_t count, const char* format, va_list va);
#ifdef __cplusplus #ifdef __cplusplus

Loading…
Cancel
Save