X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fmware%2Fformatwr.c;h=0f3c00d18ee5f2dd354fef5d5ce43b22d2c0d7dd;hb=e25abecb6a6ff52917d44d1331e5af831aeceb9c;hp=0a36cee8d5daca793250c0c42463ae93d1ea2343;hpb=c22fe24a0da896a52dbc3882390ec18a440ef56a;p=bertos.git diff --git a/bertos/mware/formatwr.c b/bertos/mware/formatwr.c index 0a36cee8..0f3c00d1 100644 --- a/bertos/mware/formatwr.c +++ b/bertos/mware/formatwr.c @@ -26,11 +26,10 @@ * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * - * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/) + * Copyright 2003, 2004, 2005, 2008 Develer S.r.l. (http://www.develer.com/) * * --> * - * \version $Id$ * * \brief Basic "printf", "sprintf" and "fprintf" formatter. * @@ -43,24 +42,24 @@ * controlled by giving a -D option a compilation time: * * \code - * -D CONFIG_PRINTF=PRINTF_FULL Full ANSI printf formatter + * -D CONFIG_PRINTF=PRINTF_FULL Full ANSI printf formatter, with some C99 extensions * -D CONFIG_PRINTF=PRINTF_NOFLOAT Exclude support for floats * -D CONFIG_PRINTF=PRINTF_REDUCED Simplified formatter (see below) - * -D CONFIG_PRINTF=PRINTF_NOMODIFIERS Exclude 'l' and 'h' modifiers in reduced version + * -D CONFIG_PRINTF=PRINTF_NOMODIFIERS Exclude "l", "z" and "h" modifiers in reduced version * -D CONFIG_PRINTF=PRINTF_DISABLED No formatter at all * \endcode * * Code size on AVR4 with GCC 3.4.1 (-O2): - * PRINTF_FULL 2912byte (0xB60) - * PRINTF_NOFLOAT 1684byte (0x694) - * PRINTF_REDUCED 924byte (0x39C) - * PRINTF_NOMODIFIERS 416byte (0x1A0) + * \li PRINTF_FULL 2912byte (0xB60) + * \li PRINTF_NOFLOAT 1684byte (0x694) + * \li PRINTF_REDUCED 924byte (0x39C) + * \li PRINTF_NOMODIFIERS 416byte (0x1A0) * * Code/data size in words on DSP56K with CodeWarrior 6.0: - * PRINTF_FULL 1493/45 - * PRINTF_NOFLOAT 795/45 - * PRINTF_REDUCED 482/0 - * PRINTF_NOMODIFIERS 301/0 + * \li PRINTF_FULL 1493/45 + * \li PRINTF_NOFLOAT 795/45 + * \li PRINTF_REDUCED 482/0 + * \li PRINTF_NOMODIFIERS 301/0 * * The reduced version of formatter is suitable when program size is critical * rather than formatting power. This routine uses less than 20 bytes of @@ -82,7 +81,7 @@ #include "cfg/cfg_formatwr.h" /* CONFIG_ macros */ #include /* ASSERT */ -#include +#include #include #ifndef CONFIG_PRINTF_N_FORMATTER @@ -106,15 +105,25 @@ /* Maximum precision for floating point values */ typedef long double max_float_t; - /*bernie: save some memory, who cares about floats with lots of decimals? */ - #define FRMWRI_BUFSIZE 134 - #warning 134 is too much, the code must be fixed to have a lower precision limit + #if CONFIG_FRMWRI_BUFSIZE + #define FRMWRI_BUFSIZE CONFIG_FRMWRI_BUFSIZE + #else + /* Conservative estimate. Max float is 3.40282e+038, so %f (but not %e or %g) must have + * space for: sign + all 38 digits + '.' + 6 decimal digits (default) + * Use a high value to avoid unexpected buffer overflows. + */ + #define FRMWRI_BUFSIZE 134 + #endif #else - /* - * Conservative estimate. Should be (probably) 12 (which is the size necessary - * to represent (2^32-1) in octal plus the sign bit. - */ - #define FRMWRI_BUFSIZE 16 + #if CONFIG_FRMWRI_BUFSIZE + #define FRMWRI_BUFSIZE CONFIG_FRMWRI_BUFSIZE + #else + /* + * Conservative estimate. Should be (probably) 12 (which is the size necessary + * to represent (2^32-1) in octal plus the sign bit. + */ + #define FRMWRI_BUFSIZE 16 + #endif #endif /* Probably useful for fancy microcontrollers such as the PIC, nobody knows. */ @@ -495,14 +504,21 @@ NEXT_FLAG: { case 'l': case 'L': + #if SIZEOF_SIZE_T == SIZEOF_LONG case 'z': flags.l_L_modifier = true; + #elif SIZEOF_SIZE_T == SIZEOF_INT + flags.l_L_modifier = true; + case 'z': + #endif format++; break; + case 'h': flags.h_modifier = true; format++; break; + } /* @@ -588,7 +604,7 @@ NEXT_FLAG: case 'p': case 'X': if (format_flag == 'p') -#if defined(__AVR__) || defined(__I196__) /* 16bit pointers */ +#if defined(__AVR__) || defined(__I196__) || defined(__MSP430__) /* 16bit pointers */ ulong = (unsigned long)(unsigned short)va_arg(ap, char *); #else /* 32bit pointers */ ulong = (unsigned long)va_arg(ap, char *); @@ -836,14 +852,20 @@ FLOATING_CONVERSION: } #if CONFIG_PRINTF > PRINTF_NOMODIFIERS - /*=================================*/ - /* Optional 'l' or 'h' modifiers ? */ - /*=================================*/ + /* + * Optional 'l', 'z' or 'h' modifiers? + */ l_modifier = h_modifier = false; switch (PGM_READ_CHAR(format)) { case 'l': + #if SIZEOF_SIZE_T == SIZEOF_LONG + case 'z': l_modifier = true; + #elif SIZEOF_SIZE_T == SIZEOF_INT + l_modifier = true; + case 'z': + #endif format++; break; @@ -899,13 +921,22 @@ FLOATING_CONVERSION: CONVERSION_LOOP: #if CONFIG_PRINTF > PRINTF_NOMODIFIERS if (h_modifier) - u_val = (format_flag == 'd') ? - (short)va_arg(ap, int) : (unsigned short)va_arg(ap, int); + { + if (format_flag == 'd') + u_val = (short)va_arg(ap, int); + else + u_val = (unsigned short)va_arg(ap, int); + } else if (l_modifier) u_val = va_arg(ap, long); else - u_val = (format_flag == 'd') ? - va_arg(ap,int) : va_arg(ap,unsigned int); + { + if (format_flag == 'd') + u_val = va_arg(ap, int); + else + u_val = va_arg(ap, unsigned int); + } + #else /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */ u_val = va_arg(ap,int); #endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */