chsprintf minimal @p sprintf() patch

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
tdwebste
Posts: 35
Joined: Mon Jan 14, 2013 2:01 pm

chsprintf minimal @p sprintf() patch

Post by tdwebste »

We have added chsprint to implement a minimal @p sprintf() like functionality with
output to a string.


Your feed back is appreciated.

How do I attach a patch file? I am getting The extension " " is not allowed for everything I have tried.


From 8a4411d184dc884a9a3e03a1a7fa54356d6d0dbd Mon Sep 17 00:00:00 2001
From: Timothy Webster <[email protected]>
Date: Sun, 1 Dec 2013 23:33:22 -0500
Subject: [PATCH] chibios sprint

chsprintf
This function implements a minimal @p sprintf() like functionality with
output to a string.
---
os/various/chprintf.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 176 insertions(+)

diff --git a/os/various/chprintf.c b/os/various/chprintf.c
index 5d3d38e..0960eaa 100644
--- a/os/various/chprintf.c
+++ b/os/various/chprintf.c
@@ -259,4 +259,180 @@ unsigned_common:
}
}

+/**
+ * @brief Formatted string function.
+ * @details This function implements a minimal @p sprintf() like functionality
+ * with output to a string.
+ * The general parameters format is: %[-][width|*][.precision|*][l|L]p.
+ * The following parameter types (p) are supported:
+ * - <b>x</b> hexadecimal integer.
+ * - <b>X</b> hexadecimal long.
+ * - <b>o</b> octal integer.
+ * - <b>O</b> octal long.
+ * - <b>d</b> decimal signed integer.
+ * - <b>D</b> decimal signed long.
+ * - <b>u</b> decimal unsigned integer.
+ * - <b>U</b> decimal unsigned long.
+ * - <b>c</b> character.
+ * - <b>s</b> string.
+ * .
+ *
+ * @param[in] buf pointer to a string buffer
+ * @param[in] fmt formatting string
+ */
+void chsprintf(char *buf, const char *fmt, ...) {
+ va_list ap;
+ char *p, *s, c, filler;
+ int i, precision, width;
+ bool_t is_long, left_align;
+ long l;
+#if CHPRINTF_USE_FLOAT
+ float f;
+ char tmpbuf[2*MAX_FILLER + 1];
+#else
+ char tmpbuf[MAX_FILLER + 1];
+#endif
+
+ va_start(ap, fmt);
+ while (TRUE) {
+ c = *fmt++;
+ if (c == 0) {
+ va_end(ap);
+ *(buf++) = 0;
+ return;
+ }
+ if (c != '%') {
+ *(buf++) = (uint8_t)c;
+ continue;
+ }
+ p = tmpbuf;
+ s = tmpbuf;
+ left_align = FALSE;
+ if (*fmt == '-') {
+ fmt++;
+ left_align = TRUE;
+ }
+ filler = ' ';
+ if (*fmt == '.') {
+ fmt++;
+ filler = '0';
+ }
+ width = 0;
+ while (TRUE) {
+ c = *fmt++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c == '*')
+ c = va_arg(ap, int);
+ else
+ break;
+ width = width * 10 + c;
+ }
+ precision = 0;
+ if (c == '.') {
+ while (TRUE) {
+ c = *fmt++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c == '*')
+ c = va_arg(ap, int);
+ else
+ break;
+ precision *= 10;
+ precision += c;
+ }
+ }
+ /* Long modifier.*/
+ if (c == 'l' || c == 'L') {
+ is_long = TRUE;
+ if (*fmt)
+ c = *fmt++;
+ }
+ else
+ is_long = (c >= 'A') && (c <= 'Z');
+
+ /* Command decoding.*/
+ switch (c) {
+ case 'c':
+ filler = ' ';
+ *p++ = va_arg(ap, int);
+ break;
+ case 's':
+ filler = ' ';
+ if ((s = va_arg(ap, char *)) == 0)
+ s = "(null)";
+ if (precision == 0)
+ precision = 32767;
+ for (p = s; *p && (--precision >= 0); p++)
+ ;
+ break;
+ case 'D':
+ case 'd':
+ case 'I':
+ case 'i':
+ if (is_long)
+ l = va_arg(ap, long);
+ else
+ l = va_arg(ap, int);
+ if (l < 0) {
+ *p++ = '-';
+ l = -l;
+ }
+ p = ltoa(p, l, 10);
+ break;
+#if CHPRINTF_USE_FLOAT
+ case 'f':
+ f = (float) va_arg(ap, double);
+ if (f < 0) {
+ *p++ = '-';
+ f = -f;
+ }
+ p = ftoa(p, f);
+ break;
+#endif
+ case 'X':
+ case 'x':
+ c = 16;
+ goto unsigned_common;
+ case 'U':
+ case 'u':
+ c = 10;
+ goto unsigned_common;
+ case 'O':
+ case 'o':
+ c = 8;
+unsigned_common:
+ if (is_long)
+ l = va_arg(ap, unsigned long);
+ else
+ l = va_arg(ap, unsigned int);
+ p = ltoa(p, l, c);
+ break;
+ default:
+ *p++ = c;
+ break;
+ }
+ i = (int)(p - s);
+ if ((width -= i) < 0)
+ width = 0;
+ if (left_align == FALSE)
+ width = -width;
+ if (width < 0) {
+ if (*s == '-' && filler == '0') {
+ *(buf++) = (uint8_t)*s++;
+ i--;
+ }
+ do
+ *(buf++) = (uint8_t)filler;
+ while (++width != 0);
+ }
+ while (--i >= 0)
+ *(buf++) = (uint8_t)*s++;
+
+ while (width) {
+ *(buf++) = (uint8_t)filler;
+ width--;
+ }
+ }
+}
/** @} */
--
1.8.1.2
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chsprintf minimal @p sprintf() patch

Post by Giovanni »

Hi,

I need to verify if there is an easier way to implement chsprintf(), duplicating all the code looks a bit wasteful. Probably it is possible to create a string writer implementing a stream and using the normal chprintf() for printing.

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chsprintf minimal @p sprintf() patch

Post by Giovanni »

Hi,

I added an alternate implementation of chsnprintf() that uses memstreams internally. Note the "N", I prefer this variant for safety reasons.

Please let me go if it works for you.

Giovanni
tdwebste
Posts: 35
Joined: Mon Jan 14, 2013 2:01 pm

Re: chsprintf minimal @p sprintf() patch

Post by tdwebste »

Thx
Which release repository did you add it to? 2.6 or 2.7.
We are still on 2.6, But we are looking to migrate to 2.7
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chsprintf minimal @p sprintf() patch

Post by Giovanni »

Hi,

Both, it will be in 2.6.2 and 2.7.0.

Note that 2.7.0 probably will never be released and replaced by the 3.0.0 branch. Everything is going in 2.6.2 anyway.

Giovanni
tdwebste
Posts: 35
Joined: Mon Jan 14, 2013 2:01 pm

Re: chsprintf minimal @p sprintf() patch

Post by tdwebste »

I know I am missing something easy.

git grep include -- 'chprintf.[ch]'
chprintf.c:#include "ch.h"
chprintf.c:#include "chprintf.h"
chprintf.c:#include "memstreams.h"
chprintf.h:#include <stdarg.h>


chprintf.c:297: undefined reference to `msObjectInit'

ideas?
tdwebste
Posts: 35
Joined: Mon Jan 14, 2013 2:01 pm

Re: chsprintf minimal @p sprintf() patch

Post by tdwebste »

Forgot to add
$(CHIBIOS)/os/various/memstreams.c \
to my Makefile.
Post Reply