diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2014-10-26 10:17:14 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2014-10-26 10:17:14 +0000 |
commit | 6f20fa7916b73f30337a6b411d64e4b6fd65d5cc (patch) | |
tree | 608554511e4dfd72eec396657df5c62eea8a0d62 /os/various | |
parent | da0a231bbcac124415c001ae59a576d5cefeb07b (diff) | |
download | ChibiOS-6f20fa7916b73f30337a6b411d64e4b6fd65d5cc.tar.gz ChibiOS-6f20fa7916b73f30337a6b411d64e4b6fd65d5cc.tar.bz2 ChibiOS-6f20fa7916b73f30337a6b411d64e4b6fd65d5cc.zip |
Again #538.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7422 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/various')
-rw-r--r-- | os/various/chprintf.c | 40 | ||||
-rw-r--r-- | os/various/chprintf.h | 9 |
2 files changed, 37 insertions, 12 deletions
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: * - <b>c</b> character.
* - <b>s</b> 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_ */
|