From 849a645b5ffd3d267c71730ae77f24af794920cf Mon Sep 17 00:00:00 2001 From: rusefi Date: Fri, 7 Apr 2017 16:06:29 -0400 Subject: [PATCH] https://github.com/rusefi/rusefi/issues/388 --- os/hal/lib/streams/chprintf.c | 170 +++++++++---- os/hal/lib/streams/chprintf.c.orig | 375 ----------------------------- os/hal/lib/streams/chprintf.h | 39 +-- os/hal/lib/streams/chprintf.h.orig | 49 ---- 4 files changed, 133 insertions(+), 500 deletions(-) delete mode 100644 os/hal/lib/streams/chprintf.c.orig delete mode 100644 os/hal/lib/streams/chprintf.h.orig diff --git a/os/hal/lib/streams/chprintf.c b/os/hal/lib/streams/chprintf.c index 2a8d81cdc..1d1c14e33 100644 --- a/os/hal/lib/streams/chprintf.c +++ b/os/hal/lib/streams/chprintf.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + 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. @@ -27,15 +27,16 @@ * @{ */ -#include "ch.h" +#include "hal.h" #include "chprintf.h" +#include "memstreams.h" +//#include "error_handling.h" #define MAX_FILLER 11 -/** - * That's out default %f precision here. Two digits should be fine? - * That's important on the lcd screen - */ -#define FLOAT_PRECISION 100 +#define FLOAT_PRECISION 9 + +int getRemainingStack(thread_t *otp); + static char *long_to_string_with_divisor(char *p, long num, unsigned radix, @@ -69,28 +70,22 @@ static char *long_to_string_with_divisor(char *p, return p; } -// custom_ name in order to avoid method signature conflict with standard libraries -static char *custom_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); } #if CHPRINTF_USE_FLOAT -char *ftoa(char *p, double num, unsigned long precision) { - if (num < 0) { - *p++ = '-'; - return ftoa(p, -num, precision); - } - long l; - if (isnan(num)) { - *p++ = 'N'; - *p++ = 'a'; - *p++ = 'N'; - return p; - } +static const long pow10[FLOAT_PRECISION] = { + 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 +}; - if (precision == 0) +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); @@ -100,9 +95,6 @@ char *ftoa(char *p, double num, unsigned long precision) { } #endif -#include "error_handling.h" -int getRemainingStack(thread_t *otp); - /** * @brief System formatted output function. * @details This function implements a minimal @p vprintf()-like functionality @@ -124,12 +116,15 @@ int getRemainingStack(thread_t *otp); * @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 @@ -139,18 +134,17 @@ void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { char tmpbuf[MAX_FILLER + 1]; #endif - efiAssertVoid(getRemainingStack(chThdGetSelfX()) > 64, "lowstck#1c"); +// efiAssert(getRemainingStack(chThdGetSelfX()) > 128, "lowstck#1c", 0); - - while (TRUE) { + while (true) { c = *fmt++; if (c == 0) - return; + return n; if (c != '%') { - chSequentialStreamPut(chp, (uint8_t)c); + streamPut(chp, (uint8_t)c); + n++; continue; } - // we are here if c == '%' meaning we have a control sequence p = tmpbuf; s = tmpbuf; left_align = FALSE; @@ -159,7 +153,7 @@ void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { left_align = TRUE; } filler = ' '; - if ((*fmt == '.') || (*fmt == '0')) { + if (*fmt == '0') { fmt++; filler = '0'; } @@ -224,7 +218,7 @@ void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { *p++ = '-'; l = -l; } - p = custom_ltoa(p, l, 10); + p = ch_ltoa(p, l, 10); break; #if CHPRINTF_USE_FLOAT case 'f': @@ -252,7 +246,7 @@ unsigned_common: l = va_arg(ap, unsigned long); else l = va_arg(ap, unsigned int); - p = custom_ltoa(p, l, c); + p = ch_ltoa(p, l, c); break; default: *p++ = c; @@ -265,23 +259,117 @@ unsigned_common: width = -width; if (width < 0) { if (*s == '-' && filler == '0') { - chSequentialStreamPut(chp, (uint8_t)*s++); + streamPut(chp, (uint8_t)*s++); + n++; i--; } do { - chSequentialStreamPut(chp, (uint8_t)filler); + streamPut(chp, (uint8_t)filler); + n++; } while (++width != 0); } - if (i > 0) { - chSequentialStreamWrite(chp, (uint8_t*)s, i); + while (--i >= 0) { + streamPut(chp, (uint8_t)*s++); + n++; } - s += i; while (width) { - chSequentialStreamPut(chp, (uint8_t)filler); + 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: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - c character. + * - s 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: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - 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 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; +} + /** @} */ diff --git a/os/hal/lib/streams/chprintf.c.orig b/os/hal/lib/streams/chprintf.c.orig deleted file mode 100644 index 1d1c14e33..000000000 --- a/os/hal/lib/streams/chprintf.c.orig +++ /dev/null @@ -1,375 +0,0 @@ -/* - 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: - * - x hexadecimal integer. - * - X hexadecimal long. - * - o octal integer. - * - O octal long. - * - d decimal signed integer. - * - D decimal signed long. - * - u decimal unsigned integer. - * - U decimal unsigned long. - * - c character. - * - s 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: - * - x hexadecimal integer. - * - X hexadecimal long. - * - o octal integer. - * - O octal long. - * - d decimal signed integer. - * - D decimal signed long. - * - u decimal unsigned integer. - * - U decimal unsigned long. - * - c character. - * - s 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: - * - x hexadecimal integer. - * - X hexadecimal long. - * - o octal integer. - * - O octal long. - * - d decimal signed integer. - * - D decimal signed long. - * - u decimal unsigned integer. - * - U decimal unsigned long. - * - 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 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; -} - -/** @} */ diff --git a/os/hal/lib/streams/chprintf.h b/os/hal/lib/streams/chprintf.h index 050616eff..a86af2e4b 100644 --- a/os/hal/lib/streams/chprintf.h +++ b/os/hal/lib/streams/chprintf.h @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + 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. @@ -26,7 +26,6 @@ #define _CHPRINTF_H_ #include -#include /** * @brief Float type support. @@ -38,43 +37,13 @@ #ifdef __cplusplus extern "C" { #endif - void chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap); - char *ftoa(char *p, double num, unsigned long precision); + 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 -/** - * @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: - * - x hexadecimal integer. - * - X hexadecimal long. - * - o octal integer. - * - O octal long. - * - d decimal signed integer. - * - D decimal signed long. - * - u decimal unsigned integer. - * - U decimal unsigned long. - * - c character. - * - s 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_ */ /** @} */ diff --git a/os/hal/lib/streams/chprintf.h.orig b/os/hal/lib/streams/chprintf.h.orig deleted file mode 100644 index a86af2e4b..000000000 --- a/os/hal/lib/streams/chprintf.h.orig +++ /dev/null @@ -1,49 +0,0 @@ -/* - 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 - -/** - * @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_ */ - -/** @} */