Replacing chprintf by our custom one, renaming current one.

This commit is contained in:
Fabien Poussin 2017-03-31 15:37:21 +02:00
parent a1d8f2604f
commit 3022e23b4d
4 changed files with 790 additions and 424 deletions

View File

@ -1,375 +1,286 @@
/* /*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* /*
Concepts and parts of this file have been contributed by Fabio Utzig, Concepts and parts of this file have been contributed by Fabio Utzig,
chvprintf() added by Brent Roman. chvprintf() added by Brent Roman.
*/ */
/** /**
* @file chprintf.c * @file chprintf.c
* @brief Mini printf-like functionality. * @brief Mini printf-like functionality.
* *
* @addtogroup chprintf * @addtogroup chprintf
* @{ * @{
*/ */
#include "hal.h" #include "ch.h"
#include "chprintf.h" #include "chprintf.h"
#include "memstreams.h"
//#include "error_handling.h" #define MAX_FILLER 11
/**
#define MAX_FILLER 11 * That's out default %f precision here. Two digits should be fine?
#define FLOAT_PRECISION 9 * That's important on the lcd screen
*/
int getRemainingStack(thread_t *otp); #define FLOAT_PRECISION 100
static char *long_to_string_with_divisor(char *p,
static char *long_to_string_with_divisor(char *p, long num,
long num, unsigned radix,
unsigned radix, long divisor) {
long divisor) { int i;
int i; char *q;
char *q; long l, ll;
long l, ll;
l = num;
l = num; if (divisor == 0) {
if (divisor == 0) { ll = num;
ll = num; } else {
} else { ll = divisor;
ll = divisor; }
}
q = p + MAX_FILLER;
q = p + MAX_FILLER; do {
do { i = (int)(l % radix);
i = (int)(l % radix); i += '0';
i += '0'; if (i > '9')
if (i > '9') i += 'A' - '0' - 10;
i += 'A' - '0' - 10; *--q = i;
*--q = i; l /= radix;
l /= radix; } while ((ll /= radix) != 0);
} while ((ll /= radix) != 0);
i = (int)(p + MAX_FILLER - q);
i = (int)(p + MAX_FILLER - q); do
do *p++ = *q++;
*p++ = *q++; while (--i);
while (--i);
return p;
return p; }
}
static char *ltoa(char *p, long num, unsigned radix) {
static char *ch_ltoa(char *p, long num, unsigned radix) {
return long_to_string_with_divisor(p, num, radix, 0);
return long_to_string_with_divisor(p, num, radix, 0); }
}
#if CHPRINTF_USE_FLOAT
#if CHPRINTF_USE_FLOAT char *ftoa(char *p, double num, unsigned long precision) {
static const long pow10[FLOAT_PRECISION] = { if (num < 0) {
10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 *p++ = '-';
}; return ftoa(p, -num, precision);
}
static char *ftoa(char *p, double num, unsigned long precision) { long l;
long l; if (isnan(num)) {
*p++ = 'N';
if ((precision == 0) || (precision > FLOAT_PRECISION)) *p++ = 'a';
precision = FLOAT_PRECISION; *p++ = 'N';
precision = pow10[precision - 1]; return p;
}
l = (long)num;
p = long_to_string_with_divisor(p, l, 10, 0); if (precision == 0)
*p++ = '.'; precision = FLOAT_PRECISION;
l = (long)((num - l) * precision);
return long_to_string_with_divisor(p, l, 10, precision / 10); l = (long)num;
} p = long_to_string_with_divisor(p, l, 10, 0);
#endif *p++ = '.';
l = (long)((num - l) * precision);
/** return long_to_string_with_divisor(p, l, 10, precision / 10);
* @brief System formatted output function. }
* @details This function implements a minimal @p vprintf()-like functionality #endif
* with output on a @p BaseSequentialStream.
* The general parameters format is: %[-][width|*][.precision|*][l|L]p. #include "error_handling.h"
* The following parameter types (p) are supported: int getRemainingStack(Thread *otp);
* - <b>x</b> hexadecimal integer.
* - <b>X</b> hexadecimal long. /**
* - <b>o</b> octal integer. * @brief System formatted output function.
* - <b>O</b> octal long. * @details This function implements a minimal @p vprintf()-like functionality
* - <b>d</b> decimal signed integer. * with output on a @p BaseSequentialStream.
* - <b>D</b> decimal signed long. * The general parameters format is: %[-][width|*][.precision|*][l|L]p.
* - <b>u</b> decimal unsigned integer. * The following parameter types (p) are supported:
* - <b>U</b> decimal unsigned long. * - <b>x</b> hexadecimal integer.
* - <b>c</b> character. * - <b>X</b> hexadecimal long.
* - <b>s</b> string. * - <b>o</b> octal integer.
* . * - <b>O</b> octal long.
* * - <b>d</b> decimal signed integer.
* @param[in] chp pointer to a @p BaseSequentialStream implementing object * - <b>D</b> decimal signed long.
* @param[in] fmt formatting string * - <b>u</b> decimal unsigned integer.
* @param[in] ap list of parameters * - <b>U</b> decimal unsigned long.
* @return The number of bytes that would have been * - <b>c</b> character.
* written to @p chp if no stream error occurs * - <b>s</b> string.
* * .
* @api *
*/ * @param[in] chp pointer to a @p BaseSequentialStream implementing object
int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { * @param[in] fmt formatting string
char *p, *s, c, filler; * @param[in] ap list of parameters
int i, precision, width; *
int n = 0; * @api
bool is_long, left_align; */
long l; void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
#if CHPRINTF_USE_FLOAT char *p, *s, c, filler;
float f; int i, precision, width;
char tmpbuf[2*MAX_FILLER + 1]; bool_t is_long, left_align;
#else long l;
char tmpbuf[MAX_FILLER + 1]; #if CHPRINTF_USE_FLOAT
#endif float f;
char tmpbuf[2*MAX_FILLER + 1];
// efiAssert(getRemainingStack(chThdGetSelfX()) > 128, "lowstck#1c", 0); #else
char tmpbuf[MAX_FILLER + 1];
while (true) { #endif
c = *fmt++;
if (c == 0) efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "lowstck#1c");
return n;
if (c != '%') {
streamPut(chp, (uint8_t)c); while (TRUE) {
n++; c = *fmt++;
continue; if (c == 0)
} return;
p = tmpbuf; if (c != '%') {
s = tmpbuf; chSequentialStreamPut(chp, (uint8_t)c);
left_align = FALSE; continue;
if (*fmt == '-') { }
fmt++; // we are here if c == '%' meaning we have a control sequence
left_align = TRUE; p = tmpbuf;
} s = tmpbuf;
filler = ' '; left_align = FALSE;
if (*fmt == '0') { if (*fmt == '-') {
fmt++; fmt++;
filler = '0'; left_align = TRUE;
} }
width = 0; filler = ' ';
while (TRUE) { if ((*fmt == '.') || (*fmt == '0')) {
c = *fmt++; fmt++;
if (c >= '0' && c <= '9') filler = '0';
c -= '0'; }
else if (c == '*') width = 0;
c = va_arg(ap, int); while (TRUE) {
else c = *fmt++;
break; if (c >= '0' && c <= '9')
width = width * 10 + c; c -= '0';
} else if (c == '*')
precision = 0; c = va_arg(ap, int);
if (c == '.') { else
while (TRUE) { break;
c = *fmt++; width = width * 10 + c;
if (c >= '0' && c <= '9') }
c -= '0'; precision = 0;
else if (c == '*') if (c == '.') {
c = va_arg(ap, int); while (TRUE) {
else c = *fmt++;
break; if (c >= '0' && c <= '9')
precision *= 10; c -= '0';
precision += c; else if (c == '*')
} c = va_arg(ap, int);
} else
/* Long modifier.*/ break;
if (c == 'l' || c == 'L') { precision *= 10;
is_long = TRUE; precision += c;
if (*fmt) }
c = *fmt++; }
} /* Long modifier.*/
else if (c == 'l' || c == 'L') {
is_long = (c >= 'A') && (c <= 'Z'); is_long = TRUE;
if (*fmt)
/* Command decoding.*/ c = *fmt++;
switch (c) { }
case 'c': else
filler = ' '; is_long = (c >= 'A') && (c <= 'Z');
*p++ = va_arg(ap, int);
break; /* Command decoding.*/
case 's': switch (c) {
filler = ' '; case 'c':
if ((s = va_arg(ap, char *)) == 0) filler = ' ';
s = "(null)"; *p++ = va_arg(ap, int);
if (precision == 0) break;
precision = 32767; case 's':
for (p = s; *p && (--precision >= 0); p++) filler = ' ';
; if ((s = va_arg(ap, char *)) == 0)
break; s = "(null)";
case 'D': if (precision == 0)
case 'd': precision = 32767;
case 'I': for (p = s; *p && (--precision >= 0); p++)
case 'i': ;
if (is_long) break;
l = va_arg(ap, long); case 'D':
else case 'd':
l = va_arg(ap, int); case 'I':
if (l < 0) { case 'i':
*p++ = '-'; if (is_long)
l = -l; l = va_arg(ap, long);
} else
p = ch_ltoa(p, l, 10); l = va_arg(ap, int);
break; if (l < 0) {
#if CHPRINTF_USE_FLOAT *p++ = '-';
case 'f': l = -l;
f = (float) va_arg(ap, double); }
if (f < 0) { p = ltoa(p, l, 10);
*p++ = '-'; break;
f = -f; #if CHPRINTF_USE_FLOAT
} case 'f':
p = ftoa(p, f, precision); f = (float) va_arg(ap, double);
break; if (f < 0) {
#endif *p++ = '-';
case 'X': f = -f;
case 'x': }
c = 16; p = ftoa(p, f, precision);
goto unsigned_common; break;
case 'U': #endif
case 'u': case 'X':
c = 10; case 'x':
goto unsigned_common; c = 16;
case 'O': goto unsigned_common;
case 'o': case 'U':
c = 8; case 'u':
unsigned_common: c = 10;
if (is_long) goto unsigned_common;
l = va_arg(ap, unsigned long); case 'O':
else case 'o':
l = va_arg(ap, unsigned int); c = 8;
p = ch_ltoa(p, l, c); unsigned_common:
break; if (is_long)
default: l = va_arg(ap, unsigned long);
*p++ = c; else
break; l = va_arg(ap, unsigned int);
} p = ltoa(p, l, c);
i = (int)(p - s); break;
if ((width -= i) < 0) default:
width = 0; *p++ = c;
if (left_align == FALSE) break;
width = -width; }
if (width < 0) { i = (int)(p - s);
if (*s == '-' && filler == '0') { if ((width -= i) < 0)
streamPut(chp, (uint8_t)*s++); width = 0;
n++; if (left_align == FALSE)
i--; width = -width;
} if (width < 0) {
do { if (*s == '-' && filler == '0') {
streamPut(chp, (uint8_t)filler); chSequentialStreamPut(chp, (uint8_t)*s++);
n++; i--;
} while (++width != 0); }
} do {
while (--i >= 0) { chSequentialStreamPut(chp, (uint8_t)filler);
streamPut(chp, (uint8_t)*s++); } while (++width != 0);
n++; }
} if (i > 0) {
chSequentialStreamWrite(chp, (uint8_t*)s, i);
while (width) { }
streamPut(chp, (uint8_t)filler); s += i;
n++;
width--; while (width) {
} chSequentialStreamPut(chp, (uint8_t)filler);
} width--;
} }
}
/** }
* @brief System formatted output function.
* @details This function implements a minimal @p printf() like functionality /** @} */
* with output on a @p BaseSequentialStream.
* 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] chp pointer to a @p BaseSequentialStream implementing object
* @param[in] fmt formatting string
*
* @api
*/
int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
va_list ap;
int formatted_bytes;
va_start(ap, fmt);
formatted_bytes = chvprintf(chp, fmt, ap);
va_end(ap);
return formatted_bytes;
}
/**
* @brief System formatted output function.
* @details This function implements a minimal @p snprintf()-like functionality.
* 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.
* .
* @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 number of characters (excluding the
* terminating NUL byte) that would have been
* stored in @p str if there was room.
*
* @api
*/
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_wo_nul, 0);
/* Performing the print operation using the common code.*/
chp = (BaseSequentialStream *)(void *)&ms;
va_start(ap, fmt);
retval = chvprintf(chp, fmt, ap);
va_end(ap);
/* 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;
}
/** @} */

View File

@ -0,0 +1,375 @@
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Concepts and parts of this file have been contributed by Fabio Utzig,
chvprintf() added by Brent Roman.
*/
/**
* @file chprintf.c
* @brief Mini printf-like functionality.
*
* @addtogroup chprintf
* @{
*/
#include "hal.h"
#include "chprintf.h"
#include "memstreams.h"
//#include "error_handling.h"
#define MAX_FILLER 11
#define FLOAT_PRECISION 9
int getRemainingStack(thread_t *otp);
static char *long_to_string_with_divisor(char *p,
long num,
unsigned radix,
long divisor) {
int i;
char *q;
long l, ll;
l = num;
if (divisor == 0) {
ll = num;
} else {
ll = divisor;
}
q = p + MAX_FILLER;
do {
i = (int)(l % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
l /= radix;
} while ((ll /= radix) != 0);
i = (int)(p + MAX_FILLER - q);
do
*p++ = *q++;
while (--i);
return p;
}
static char *ch_ltoa(char *p, long num, unsigned radix) {
return long_to_string_with_divisor(p, num, radix, 0);
}
#if CHPRINTF_USE_FLOAT
static const long pow10[FLOAT_PRECISION] = {
10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
};
static char *ftoa(char *p, double num, unsigned long precision) {
long l;
if ((precision == 0) || (precision > FLOAT_PRECISION))
precision = FLOAT_PRECISION;
precision = pow10[precision - 1];
l = (long)num;
p = long_to_string_with_divisor(p, l, 10, 0);
*p++ = '.';
l = (long)((num - l) * precision);
return long_to_string_with_divisor(p, l, 10, precision / 10);
}
#endif
/**
* @brief System formatted output function.
* @details This function implements a minimal @p vprintf()-like functionality
* with output on a @p BaseSequentialStream.
* 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] 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
*/
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
float f;
char tmpbuf[2*MAX_FILLER + 1];
#else
char tmpbuf[MAX_FILLER + 1];
#endif
// efiAssert(getRemainingStack(chThdGetSelfX()) > 128, "lowstck#1c", 0);
while (true) {
c = *fmt++;
if (c == 0)
return n;
if (c != '%') {
streamPut(chp, (uint8_t)c);
n++;
continue;
}
p = tmpbuf;
s = tmpbuf;
left_align = FALSE;
if (*fmt == '-') {
fmt++;
left_align = TRUE;
}
filler = ' ';
if (*fmt == '0') {
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 = ch_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, precision);
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 = ch_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') {
streamPut(chp, (uint8_t)*s++);
n++;
i--;
}
do {
streamPut(chp, (uint8_t)filler);
n++;
} while (++width != 0);
}
while (--i >= 0) {
streamPut(chp, (uint8_t)*s++);
n++;
}
while (width) {
streamPut(chp, (uint8_t)filler);
n++;
width--;
}
}
}
/**
* @brief System formatted output function.
* @details This function implements a minimal @p printf() like functionality
* with output on a @p BaseSequentialStream.
* 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] chp pointer to a @p BaseSequentialStream implementing object
* @param[in] fmt formatting string
*
* @api
*/
int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
va_list ap;
int formatted_bytes;
va_start(ap, fmt);
formatted_bytes = chvprintf(chp, fmt, ap);
va_end(ap);
return formatted_bytes;
}
/**
* @brief System formatted output function.
* @details This function implements a minimal @p snprintf()-like functionality.
* 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.
* .
* @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 number of characters (excluding the
* terminating NUL byte) that would have been
* stored in @p str if there was room.
*
* @api
*/
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_wo_nul, 0);
/* Performing the print operation using the common code.*/
chp = (BaseSequentialStream *)(void *)&ms;
va_start(ap, fmt);
retval = chvprintf(chp, fmt, ap);
va_end(ap);
/* 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;
}
/** @} */

View File

@ -1,49 +1,80 @@
/* /*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/** /**
* @file chprintf.h * @file chprintf.h
* @brief Mini printf-like functionality. * @brief Mini printf-like functionality.
* *
* @addtogroup chprintf * @addtogroup chprintf
* @{ * @{
*/ */
#ifndef _CHPRINTF_H_ #ifndef _CHPRINTF_H_
#define _CHPRINTF_H_ #define _CHPRINTF_H_
#include <stdarg.h> #include <stdarg.h>
#include <math.h>
/**
* @brief Float type support. /**
*/ * @brief Float type support.
#if !defined(CHPRINTF_USE_FLOAT) || defined(__DOXYGEN__) */
#define CHPRINTF_USE_FLOAT FALSE #if !defined(CHPRINTF_USE_FLOAT) || defined(__DOXYGEN__)
#endif #define CHPRINTF_USE_FLOAT FALSE
#endif
#ifdef __cplusplus
extern "C" { #ifdef __cplusplus
#endif extern "C" {
int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap); #endif
int chprintf(BaseSequentialStream *chp, const char *fmt, ...); void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap);
int chsnprintf(char *str, size_t size, const char *fmt, ...); char *ftoa(char *p, double num, unsigned long precision);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _CHPRINTF_H_ */ /**
* @brief System formatted output function.
/** @} */ * @details This function implements a minimal @p printf() like functionality
* with output on a @p BaseSequentialStream.
* 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] chp pointer to a @p BaseSequentialStream implementing object
* @param[in] fmt formatting string
*
* @api
*/
static inline void chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
chvprintf(chp, fmt, ap);
va_end(ap);
}
#endif /* _CHPRINTF_H_ */
/** @} */

View File

@ -0,0 +1,49 @@
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file chprintf.h
* @brief Mini printf-like functionality.
*
* @addtogroup chprintf
* @{
*/
#ifndef _CHPRINTF_H_
#define _CHPRINTF_H_
#include <stdarg.h>
/**
* @brief Float type support.
*/
#if !defined(CHPRINTF_USE_FLOAT) || defined(__DOXYGEN__)
#define CHPRINTF_USE_FLOAT FALSE
#endif
#ifdef __cplusplus
extern "C" {
#endif
int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap);
int chprintf(BaseSequentialStream *chp, const char *fmt, ...);
int chsnprintf(char *str, size_t size, const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /* _CHPRINTF_H_ */
/** @} */