diff --git a/os/various/chprintf.c b/os/various/chprintf.c
index 838cd7ce8..36dad0de9 100644
--- a/os/various/chprintf.c
+++ b/os/various/chprintf.c
@@ -113,12 +113,15 @@ static char *ftoa(char *p, double num, unsigned long precision) {
* @param[in] chp pointer to a @p BaseSequentialStream implementing object
* @param[in] fmt formatting string
* @param[in] ap list of parameters
+ * @return The number of bytes that would have been
+ * written to @p chp if no stream error occurs
*
* @api
*/
-void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
+int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
char *p, *s, c, filler;
int i, precision, width;
+ int n = 0;
bool is_long, left_align;
long l;
#if CHPRINTF_USE_FLOAT
@@ -131,9 +134,10 @@ void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
while (TRUE) {
c = *fmt++;
if (c == 0)
- return;
+ return n;
if (c != '%') {
chSequentialStreamPut(chp, (uint8_t)c);
+ n++;
continue;
}
p = tmpbuf;
@@ -251,17 +255,22 @@ unsigned_common:
if (width < 0) {
if (*s == '-' && filler == '0') {
chSequentialStreamPut(chp, (uint8_t)*s++);
+ n++;
i--;
}
do {
chSequentialStreamPut(chp, (uint8_t)filler);
+ n++;
} while (++width != 0);
}
- while (--i >= 0)
+ while (--i >= 0) {
chSequentialStreamPut(chp, (uint8_t)*s++);
+ n++;
+ }
while (width) {
chSequentialStreamPut(chp, (uint8_t)filler);
+ n++;
width--;
}
}
@@ -284,11 +293,14 @@ unsigned_common:
* - c character.
* - s string.
* .
+ * @post @p str is NUL-terminated, unless @p size is 0.
*
* @param[in] str pointer to a buffer
* @param[in] size maximum size of the buffer
* @param[in] fmt formatting string
- * @return The size of the generated string.
+ * @return The number of characters (excluding the
+ * terminating NUL byte) that would have been
+ * stored in @p str if there was room.
*
* @api
*/
@@ -296,20 +308,30 @@ int chsnprintf(char *str, size_t size, const char *fmt, ...) {
va_list ap;
MemoryStream ms;
BaseSequentialStream *chp;
+ size_t size_wo_nul;
+ int retval;
+
+ if (size > 0)
+ size_wo_nul = size - 1;
+ else
+ size_wo_nul = 0;
/* Memory stream object to be used as a string writer, reserving one
byte for the final zero.*/
- msObjectInit(&ms, (uint8_t *)str, size - 1, 0);
+ msObjectInit(&ms, (uint8_t *)str, size_wo_nul, 0);
/* Performing the print operation using the common code.*/
chp = (BaseSequentialStream *)&ms;
va_start(ap, fmt);
- chvprintf(chp, fmt, ap);
+ retval = chvprintf(chp, fmt, ap);
va_end(ap);
- /* Final zero and size return.*/
- str[ms.eos] = 0;
- return ms.eos;
+ /* Terminate with a zero, unless size==0.*/
+ if (ms.eos < size)
+ str[ms.eos] = 0;
+
+ /* Return number of bytes that would have been written.*/
+ return retval;
}
/** @} */
diff --git a/os/various/chprintf.h b/os/various/chprintf.h
index c9bd3d91f..5d624a5f1 100644
--- a/os/various/chprintf.h
+++ b/os/various/chprintf.h
@@ -37,7 +37,7 @@
#ifdef __cplusplus
extern "C" {
#endif
- void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap);
+ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap);
int chsnprintf(char *str, size_t size, const char *fmt, ...);
#ifdef __cplusplus
}
@@ -66,12 +66,15 @@ extern "C" {
*
* @api
*/
-static inline void chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
+static inline int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
va_list ap;
+ int formatted_bytes;
va_start(ap, fmt);
- chvprintf(chp, fmt, ap);
+ formatted_bytes = chvprintf(chp, fmt, ap);
va_end(ap);
+
+ return formatted_bytes;
}
#endif /* _CHPRINTF_H_ */