chsprintf minimal @p sprintf() patch

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

Moderators: RoccoMarco, barthess

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

chsprintf minimal @p sprintf() patch

Postby tdwebste » Mon Dec 02, 2013 4:43 pm

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 <tdwebste@gmail.com>
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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: chsprintf minimal @p sprintf() patch

Postby Giovanni » Mon Dec 02, 2013 5:23 pm

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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: chsprintf minimal @p sprintf() patch

Postby Giovanni » Tue Dec 03, 2013 10:39 am

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

Postby tdwebste » Wed Dec 04, 2013 1:29 am

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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: chsprintf minimal @p sprintf() patch

Postby Giovanni » Wed Dec 04, 2013 12:31 pm

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

Postby tdwebste » Fri Dec 06, 2013 10:40 pm

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

Postby tdwebste » Sat Dec 07, 2013 2:02 am

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


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 13 guests