Use configuration value for formatter bufsize.
[bertos.git] / bertos / mware / formatwr.c
index b87a904cbe5c0e5fa65df69c33c957fc7b584af0..afc4976e269af94db0ec05c25d731364fa8e0101 100644 (file)
@@ -26,7 +26,7 @@
  * 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/)
  *
  * -->
  *
  * 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
 
 #include "formatwr.h"
 
-#include <cfg/cfg_formatwr.h>  /* CONFIG_ macros */
+#include "cfg/cfg_formatwr.h"  /* CONFIG_ macros */
 #include <cfg/debug.h>         /* ASSERT */
 
-#include <mware/pgm.h>
+#include <cpu/pgm.h>
 #include <mware/hex.h>
 
 #ifndef CONFIG_PRINTF_N_FORMATTER
        /* 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
+       #warning FIXME: be sure to fix buffer size below
+       #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)
+                */
+               #define FRMWRI_BUFSIZE 50
+       #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. */
@@ -836,13 +846,16 @@ 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':
+                       case 'z':
+                               /* for the 'z' modifier, we make this assumption */
+                               STATIC_ASSERT(sizeof(size_t) == sizeof(long));
                                l_modifier = true;
                                format++;
                                break;
@@ -899,13 +912,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 */