Refactor to use new protocol module and sipo.
[bertos.git] / mware / formatwr.c
diff --git a/mware/formatwr.c b/mware/formatwr.c
deleted file mode 100755 (executable)
index bc1a504..0000000
+++ /dev/null
@@ -1,931 +0,0 @@
-/*!
- * \file
- * <!--
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * This file is part of DevLib - See devlib/README for information.
- * -->
- *
- * \version $Id$
- *
- * \brief Basic "printf", "sprintf" and "fprintf" formatter.
- *
- * This module is 100% reentrant and can be adapted to user-defined routines
- * that needs formatters with special properties like different output
- * channels or new format specifiers.
- *
- * To reduce size in applications not using real numbers or long integers
- * the formatter may be compiled to exclude certain parts.  This is
- * controlled by giving a -D option a compilation time:
- *
- * \code
- *  -D CONFIG_PRINTF=PRINTF_FULL         Full ANSI printf formatter
- *  -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_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)
- *
- * 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
- *
- * The reduced version of formatter is suitable when program size is critical
- * rather than formatting power.  This routine uses less than 20 bytes of
- * stack space which makes it practical even in systems with less than 256
- * bytes of user RAM.
- *
- * The only formatting specifiers supported by the reduced formatter are:
- * \code
- *    %% %c %s %d %o %x %X and %hd %ho %hx %hX %ld %lo %lx %lX
- * \endcode
- *
- * It means that real variables are not supported as well as field
- * width and precision arguments.
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.9  2004/09/14 21:06:23  bernie
- *#* Spelling fix.
- *#*
- *#* Revision 1.8  2004/08/25 14:12:09  rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.7  2004/08/04 15:53:47  rasky
- *#* Nuove opzioni di configurazione per formatted_write e ridotto maggiormente l'utilizzo dellos tack
- *#*
- *#* Revision 1.6  2004/07/30 14:34:10  rasky
- *#* Vari fix per documentazione e commenti
- *#* Aggiunte PP_CATn e STATIC_ASSERT
- *#*
- *#* Revision 1.5  2004/07/29 22:57:09  bernie
- *#* Switch to new-style config handling.
- *#*
- *#* Revision 1.4  2004/07/21 00:20:20  bernie
- *#* Allow completely disabling printf()-like formatter.
- *#*
- *#* Revision 1.3  2004/07/18 22:00:15  bernie
- *#* Reorganize configuration parameters to match DevLib's convention.
- *#*
- *#* Revision 1.2  2004/06/03 11:27:09  bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1  2004/05/23 15:43:16  bernie
- *#* Import mware modules.
- *#*
- *#*/
-
-#include "formatwr.h"
-#include <compiler.h> /* progmem macros */
-#include <config.h> /* CONFIG_ macros */
-#include <debug.h> /* ASSERT */
-
-#ifndef CONFIG_PRINTF_N_FORMATTER
-       /*! Enable arcane %n formatter */
-       #define CONFIG_PRINTF_N_FORMATTER 0
-#endif
-
-#ifndef CONFIG_PRINTF_OCTAL_FORMATTER
-       /*! Enable %o formatter */
-       #define CONFIG_PRINTF_OCTAL_FORMATTER 0
-#endif
-
-// True if we must keep a count of the number of characters we print
-#define CONFIG_PRINTF_COUNT_CHARS (CONFIG_PRINTF_RETURN_COUNT || CONFIG_PRINTF_N_FORMATTER)
-
-#if CONFIG_PRINTF
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
-#include <float.h>
-#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
-/*bernie: save some memory, who cares about floats with lots of decimals? */
-/*#define FRMWRI_BUFSIZE 134*/
-       #error 134 is too much, the code must be fixed to have a lower precision limit
-#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
-
-#ifndef MEM_ATTRIBUTE
-#define MEM_ATTRIBUTE
-#endif
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
-       #define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
-#else
-       #define IS_SHORT (sizeof(int) == 2)
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
-
-static char *float_conversion(MEM_ATTRIBUTE long double value,
-               MEM_ATTRIBUTE short nr_of_digits,
-               MEM_ATTRIBUTE char *buf,
-               MEM_ATTRIBUTE char format_flag,
-               MEM_ATTRIBUTE char g_flag,
-               MEM_ATTRIBUTE bool alternate_flag)
-{
-       MEM_ATTRIBUTE char *cp;
-       MEM_ATTRIBUTE char *buf_pointer;
-       MEM_ATTRIBUTE short n, i, dec_point_pos, integral_10_log;
-
-       buf_pointer = buf;
-       integral_10_log = 0;
-
-       if (value >= 1)
-       {
-               while (value >= 1e11) /* To speed up things a bit */
-               {
-                       value /= 1e10;
-                       integral_10_log += 10;
-               }
-               while (value >= 10)
-               {
-                       value /= 10;
-                       integral_10_log++;
-               }
-       }
-       else if (value) /* Not just 0.0 */
-       {
-               while (value <= 1e-10) /* To speed up things a bit */
-               {
-                       value *= 1e10;
-                       integral_10_log -= 10;
-               }
-               while (value < 1)
-               {
-                       value *= 10;
-                       integral_10_log--;
-               }
-       }
-       if (g_flag)
-       {
-               if (integral_10_log < nr_of_digits && integral_10_log >= -4)
-               {
-                       format_flag = 0;
-                       nr_of_digits -= integral_10_log;
-               }
-               nr_of_digits--;
-               if (alternate_flag)
-                       /* %#G - No removal of trailing zeros */
-                       g_flag = 0;
-               else
-                       /* %G - Removal of trailing zeros */
-                       alternate_flag = true;
-       }
-
-       /* %e or %E */
-       if (format_flag)
-       {
-               dec_point_pos = 0;
-       }
-       else
-       {
-               /* Less than one... */
-               if (integral_10_log < 0)
-               {
-                       *buf_pointer++ = '0';
-                       if ((n = nr_of_digits) || alternate_flag)
-                               *buf_pointer++ = '.';
-                       i = 0;
-                       while (--i > integral_10_log && nr_of_digits)
-                       {
-                               *buf_pointer++ = '0';
-                               nr_of_digits--;
-                       }
-                       if (integral_10_log < (-n - 1))
-                               /* Nothing more to do */
-                               goto CLEAN_UP;
-                       dec_point_pos = 1;
-               }
-               else
-               {
-                       dec_point_pos = - integral_10_log;
-               }
-       }
-
-       i = dec_point_pos;
-       while (i <= nr_of_digits )
-       {
-               value -= (long double)(n = (short)value); /* n=Digit value=Remainder */
-               value *= 10; /* Prepare for next shot */
-               *buf_pointer++ = n + '0';
-               if ( ! i++ && (nr_of_digits || alternate_flag))
-                       *buf_pointer++ = '.';
-       }
-
-       /* Rounding possible */
-       if (value >= 5)
-       {
-               n = 1; /* Carry */
-               cp = buf_pointer - 1;
-               do
-               {
-                       if (*cp != '.')
-                       {
-                               if ( (*cp += n) == ('9' + 1) )
-                               {
-                                       *cp = '0';
-                                       n = 1;
-                               }
-                               else
-                                       n = 0;
-                       }
-               } while (cp-- > buf);
-               if (n)
-               {
-                       /* %e or %E */
-                       if (format_flag)
-                       {
-                               cp = buf_pointer;
-                               while (cp > buf)
-                               {
-                                       if (*(cp - 1) == '.')
-                                       {
-                                               *cp = *(cp - 2);
-                                               cp--;
-                                       }
-                                       else
-                                               *cp = *(cp - 1);
-                                       cp--;
-                               }
-                               integral_10_log++;
-                       }
-                       else
-                       {
-                               cp = ++buf_pointer;
-                               while (cp > buf)
-                               {
-                                       *cp = *(cp - 1);
-                                       cp--;
-                               }
-                       }
-                       *buf = '1';
-               }
-       }
-
-CLEAN_UP:
-       /* %G - Remove trailing zeros */
-       if (g_flag)
-       {
-               while (*(buf_pointer - 1) == '0')
-                       buf_pointer--;
-               if (*(buf_pointer - 1) == '.')
-                       buf_pointer--;
-       }
-
-       /* %e or %E */
-       if (format_flag)
-       {
-               *buf_pointer++ = format_flag;
-               if (integral_10_log < 0)
-               {
-                       *buf_pointer++ = '-';
-                       integral_10_log = -integral_10_log;
-               }
-               else
-                       *buf_pointer++ = '+';
-               n = 0;
-               buf_pointer +=10;
-               do
-               {
-                       n++;
-                       *buf_pointer++ = (integral_10_log % 10) + '0';
-                       integral_10_log /= 10;
-               } while ( integral_10_log || n < 2 );
-               for ( i = n ; n > 0 ; n-- )
-                       *(buf_pointer - 11 - i + n) = *(buf_pointer - n);
-               buf_pointer -= 10;
-       }
-       return (buf_pointer);
-}
-
-#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
-
-/*!
- * This routine forms the core and entry of the formatter.
- *
- * The conversion performed conforms to the ANSI specification for "printf".
- */
-int
-PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
-               void put_one_char(char, void *),
-               void *secret_pointer,
-               va_list ap)
-{
-#if CONFIG_PRINTF > PRINTF_REDUCED
-       MEM_ATTRIBUTE static char bad_conversion[] = "???";
-       MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
-
-       MEM_ATTRIBUTE int precision;
-       MEM_ATTRIBUTE int n;
-#if CONFIG_PRINTF_COUNT_CHARS
-       MEM_ATTRIBUTE int nr_of_chars;
-#endif
-       MEM_ATTRIBUTE int field_width;
-       MEM_ATTRIBUTE char format_flag;
-       enum PLUS_SPACE_FLAGS {
-               PSF_NONE, PSF_PLUS, PSF_MINUS
-       };
-       enum DIV_FACTOR {
-               DIV_DEC, DIV_HEX,
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-               DIV_OCT,
-#endif
-       };
-       struct {
-               MEM_ATTRIBUTE enum PLUS_SPACE_FLAGS plus_space_flag : 2;
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-               MEM_ATTRIBUTE enum DIV_FACTOR div_factor : 2;
-#else
-               MEM_ATTRIBUTE enum DIV_FACTOR div_factor : 1;
-#endif
-               MEM_ATTRIBUTE bool left_adjust : 1;
-               MEM_ATTRIBUTE bool l_L_modifier : 1;
-               MEM_ATTRIBUTE bool h_modifier : 1;
-               MEM_ATTRIBUTE bool alternate_flag : 1;
-               MEM_ATTRIBUTE bool nonzero_value : 1;
-               MEM_ATTRIBUTE bool zeropad : 1;
-       } flags;
-       MEM_ATTRIBUTE unsigned long ulong;
-
-#if CONFIG_PRINTF >  PRINTF_NOFLOAT
-       MEM_ATTRIBUTE long double fvalue;
-#endif
-
-       MEM_ATTRIBUTE char *buf_pointer;
-       MEM_ATTRIBUTE char *ptr;
-       MEM_ATTRIBUTE const char *hex;
-       MEM_ATTRIBUTE char buf[FRMWRI_BUFSIZE];
-
-#if CONFIG_PRINTF_COUNT_CHARS
-       nr_of_chars = 0;
-#endif
-       for (;;)    /* Until full format string read */
-       {
-               while ((format_flag = PGM_READ_CHAR(format++)) != '%')    /* Until '%' or '\0' */
-               {
-                       if (!format_flag)
-#if CONFIG_PRINTF_RETURN_COUNT
-                               return (nr_of_chars);
-#else
-                               return 0;
-#endif
-                       put_one_char(format_flag, secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                       nr_of_chars++;
-#endif
-               }
-               if (PGM_READ_CHAR(format) == '%')    /* %% prints as % */
-               {
-                       format++;
-                       put_one_char('%', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                       nr_of_chars++;
-#endif
-                       continue;
-               }
-
-               flags.left_adjust = false;
-               flags.alternate_flag = false;
-               flags.plus_space_flag = PSF_NONE;
-               flags.zeropad = false;
-               ptr = buf_pointer = &buf[0];
-               hex = "0123456789ABCDEF";
-
-               /* check for leading '-', '+', ' ','#' or '0' flags  */
-               for (;;)
-               {
-                       switch (PGM_READ_CHAR(format))
-                       {
-                               case ' ':
-                                       if (flags.plus_space_flag)
-                                               goto NEXT_FLAG;
-                               case '+':
-                                       flags.plus_space_flag = PSF_PLUS;
-                                       goto NEXT_FLAG;
-                               case '-':
-                                       flags.left_adjust = true;
-                                       goto NEXT_FLAG;
-                               case '#':
-                                       flags.alternate_flag = true;
-                                       goto NEXT_FLAG;
-                               case '0':
-                                       flags.zeropad = true;
-                                       goto NEXT_FLAG;
-                       }
-                       break;
-NEXT_FLAG:
-                       format++;
-               }
-
-               /* Optional field width (may be '*') */
-               if (PGM_READ_CHAR(format) == '*')
-               {
-                       field_width = va_arg(ap, int);
-                       if (field_width < 0)
-                       {
-                               field_width = -field_width;
-                               flags.left_adjust = true;
-                       }
-                       format++;
-               }
-               else
-               {
-                       field_width = 0;
-                       while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
-                               field_width = field_width * 10 + (PGM_READ_CHAR(format++) - '0');
-               }
-
-               if (flags.left_adjust)
-                       flags.zeropad = false;
-
-               /* Optional precision (or '*') */
-               if (PGM_READ_CHAR(format) == '.')
-               {
-                       if (PGM_READ_CHAR(++format) == '*')
-                       {
-                               precision = va_arg(ap, int);
-                               format++;
-                       }
-                       else
-                       {
-                               precision = 0;
-                               while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
-                                       precision = precision * 10 + (PGM_READ_CHAR(format++) - '0');
-                       }
-               }
-               else
-                       precision = -1;
-
-               /* At this point, "left_adjust" is nonzero if there was
-                * a sign, "zeropad" is 1 if there was a leading zero
-                * and 0 otherwise, "field_width" and "precision"
-                * contain numbers corresponding to the digit strings
-                * before and after the decimal point, respectively,
-                * and "plus_space_flag" is either 0 (no flag) or
-                * contains a plus or space character. If there was no
-                * decimal point, "precision" will be -1.
-                */
-
-               flags.l_L_modifier = false;
-               flags.h_modifier = false;
-
-               /* Optional 'l','L' r 'h' modifier? */
-               switch (PGM_READ_CHAR(format))
-               {
-                       case 'l':
-                       case 'L':
-                               flags.l_L_modifier = true;
-                               format++;
-                               break;
-                       case 'h':
-                               flags.h_modifier = true;
-                               format++;
-                               break;
-               }
-
-               /*
-                * At exit from the following switch, we will emit
-                * the characters starting at "buf_pointer" and
-                * ending at "ptr"-1
-                */
-               switch (format_flag = PGM_READ_CHAR(format++))
-               {
-#if CONFIG_PRINTF_N_FORMATTER
-                       case 'n':
-                               if (sizeof(short) != sizeof(int))
-                               {
-                                       if (sizeof(int) != sizeof(long))
-                                       {
-                                               if (h_modifier)
-                                                       *va_arg(ap, short *) = nr_of_chars;
-                                               else if (flags.l_L_modifier)
-                                                       *va_arg(ap, long *) = nr_of_chars;
-                                               else
-                                                       *va_arg(ap, int *) = nr_of_chars;
-                                       }
-                                       else
-                                       {
-                                               if (h_modifier)
-                                                       *va_arg(ap, short *) = nr_of_chars;
-                                               else
-                                                       *va_arg(ap, int *) = nr_of_chars;
-                                       }
-                               }
-                               else
-                               {
-                                       if (flags.l_L_modifier)
-                                               *va_arg(ap, long *) = nr_of_chars;
-                                       else
-                                               *va_arg(ap, int *) = nr_of_chars;
-                               }
-                               continue;
-#endif
-                       case 'c':
-                               buf[0] = va_arg(ap, int);
-                               ptr++;
-                               break;
-
-                       case 's':
-                               if ( !(buf_pointer = va_arg(ap, char *)) )
-                                       buf_pointer = null_pointer;
-                               if (precision < 0)
-                                       precision = 10000;
-                               for (n=0; *buf_pointer++ && n < precision; n++)
-                                       ;
-                               ptr = --buf_pointer;
-                               buf_pointer -= n;
-                               break;
-
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-                       case 'o':
-                               if (flags.alternate_flag && !precision)
-                                       precision++;
-#endif
-                       case 'x':
-                               hex = "0123456789abcdef";
-                       case 'u':
-                       case 'p':
-                       case 'X':
-                               if (format_flag == 'p')
-#if defined(__AVR__) || defined(__I196__) /* 16bit pointers */
-                                       ulong = (unsigned long)(unsigned short)va_arg(ap, char *);
-#else /* 32bit pointers */
-                               ulong = (unsigned long)va_arg(ap, char *);
-#endif /* 32bit pointers */
-                               else if (sizeof(short) == sizeof(int))
-                                       ulong = flags.l_L_modifier ?
-                                               va_arg(ap, unsigned long) : (unsigned long)va_arg(ap, unsigned int);
-                               else
-                                       ulong = flags.h_modifier ?
-                                               (unsigned long)(unsigned short) va_arg(ap, int)
-                                               : (unsigned long)va_arg(ap, int);
-                               flags.div_factor = 
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-                                       (format_flag == 'o') ? DIV_OCT : 
-#endif
-                                       (format_flag == 'u') ? DIV_DEC : DIV_HEX;
-                               flags.plus_space_flag = PSF_NONE;
-                               goto INTEGRAL_CONVERSION;
-
-                       case 'd':
-                       case 'i':
-                               if (sizeof(short) == sizeof(long))
-                               {
-                                       if ( (long)(ulong = va_arg(ap, unsigned long)) < 0)
-                                       {
-                                               flags.plus_space_flag = PSF_MINUS;
-                                               ulong = (unsigned long)(-((signed long)ulong));
-                                       }
-                               }
-                               else if (sizeof(short) == sizeof(int))
-                               {
-                                       if ( (long)(ulong = flags.l_L_modifier ?
-                                                               va_arg(ap,unsigned long) : (unsigned long)va_arg(ap,int)) < 0)
-                                       {
-                                               flags.plus_space_flag = PSF_MINUS;
-                                               ulong = (unsigned long)(-((signed long)ulong));
-                                       }
-                               }
-                               else
-                               {
-                                       if ( (signed long)(ulong = (unsigned long) (flags.h_modifier ?
-                                                                       (short) va_arg(ap, int) : va_arg(ap,int))) < 0)
-                                       {
-                                               flags.plus_space_flag = PSF_MINUS;
-                                               ulong = (unsigned long)(-((signed long)ulong));
-                                       }
-                               }
-                               flags.div_factor = DIV_DEC;
-
-                               /* Now convert to digits */
-INTEGRAL_CONVERSION:
-                               ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
-                               flags.nonzero_value = (ulong != 0);
-
-                               /* No char if zero and zero precision */
-                               if (precision != 0 || flags.nonzero_value)
-                               {
-                                       switch (flags.div_factor)
-                                       {
-                                       case DIV_DEC:
-                                               do
-                                                       *--buf_pointer = hex[ulong % 10];
-                                               while (ulong /= 10);
-                                               break;
-
-                                       case DIV_HEX:
-                                               do
-                                                       *--buf_pointer = hex[ulong % 16];
-                                               while (ulong /= 16);
-                                               break;
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-                                       case DIV_OCT:
-                                               do
-                                                       *--buf_pointer = hex[ulong % 8];
-                                               while (ulong /= 8);
-                                               break;
-#endif
-                                       }
-                               }
-
-                               /* "precision" takes precedence */
-                               if (precision < 0)
-                                       if (flags.zeropad)
-                                               precision = field_width - (flags.plus_space_flag != PSF_NONE);
-                               while (precision > (int)(ptr - buf_pointer))
-                                       *--buf_pointer = '0';
-
-                               if (flags.alternate_flag && flags.nonzero_value)
-                               {
-                                       if (format_flag == 'x' || format_flag == 'X')
-                                       {
-                                               *--buf_pointer = format_flag;
-                                               *--buf_pointer = '0';
-                                       }
-#if CONFIG_PRINTF_OCTAL_FORMATTER
-                                       else if ((format_flag == 'o') && (*buf_pointer != '0'))
-                                       {
-                                               *--buf_pointer = '0';
-                                       }
-#endif
-                               }
-                               ASSERT(buf_pointer >= buf);
-                               break;
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
-                       case 'g':
-                       case 'G':
-                               n = 1;
-                               format_flag -= 2;
-                               if (! precision)
-                               {
-                                       precision = 1;
-                               }
-                               goto FLOATING_CONVERSION;
-                       case 'f':
-                               format_flag = 0;
-                       case 'e':
-                       case 'E':
-                               n = 0;
-FLOATING_CONVERSION:
-                               if (precision < 0)
-                               {
-                                       precision = 6;
-                               }
-                               if (sizeof(double) != sizeof(long double))
-                               {
-                                       if ( (fvalue = flags.l_L_modifier ?
-                                                               va_arg(ap,long double) : va_arg(ap,double)) < 0)
-                                       {
-                                               flags.plus_space_flag = PSF_MINUS;
-                                               fvalue = -fvalue;
-                                       }
-                               }
-                               else if ( (fvalue = va_arg(ap,long double)) < 0)
-                               {
-                                       flags.plus_space_flag = PSF_MINUS;
-                                       fvalue = -fvalue;
-                               }
-                               ptr = float_conversion (fvalue,
-                                               (short)precision,
-                                               buf_pointer += field_width,
-                                               format_flag,
-                                               (char)n,
-                                               flags.alternate_flag);
-                               if (flags.zeropad)
-                               {
-                                       precision = field_width - (flags.plus_space_flag != PSF_NONE);
-                                       while (precision > ptr - buf_pointer)
-                                               *--buf_pointer = '0';
-                               }
-                               break;
-
-#else /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
-                       case 'g':
-                       case 'G':
-                       case 'f':
-                       case 'e':
-                       case 'E':
-                               ptr = buf_pointer = bad_conversion;
-                               while (*ptr)
-                                       ptr++;
-                               break;
-#endif /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
-
-                       case '\0': /* Really bad place to find NUL in */
-                               format--;
-
-                       default:
-                               /* Undefined conversion! */
-                               ptr = buf_pointer = bad_conversion;
-                               ptr += 3;
-                               break;
-
-               }
-
-               /*
-                * This part emittes the formatted string to "put_one_char".
-                */
-
-               /* If field_width == 0 then nothing should be written. */
-               precision = ptr - buf_pointer;
-
-               if ( precision > field_width)
-               {
-                       n = 0;
-               }
-               else
-               {
-                       n = field_width - precision - (flags.plus_space_flag != PSF_NONE);
-               }
-
-               /* emit any leading pad characters */
-               if (!flags.left_adjust)
-                       while (--n >= 0)
-                       {
-                               put_one_char(' ', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                               nr_of_chars++;
-#endif
-                       }
-
-               /* emit flag characters (if any) */
-               if (flags.plus_space_flag)
-               {
-                       put_one_char(flags.plus_space_flag == PSF_PLUS ? '+' : '-', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                       nr_of_chars++;
-#endif
-               }
-
-               /* emit the string itself */
-               while (--precision >= 0)
-               {
-                       put_one_char(*buf_pointer++, secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                       nr_of_chars++;
-#endif
-               }
-
-               /* emit trailing space characters */
-               if (flags.left_adjust)
-                       while (--n >= 0)
-                       {
-                               put_one_char(' ', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
-                               nr_of_chars++;
-#endif
-                       }
-       }
-
-#else /* PRINTF_REDUCED starts here */
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
-       char l_modifier, h_modifier;
-       unsigned long u_val, div_val;
-#else
-       unsigned int u_val, div_val;
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
-       char format_flag;
-       unsigned int nr_of_chars, base;
-       char outChar;
-       char *ptr;
-
-       nr_of_chars = 0;
-       for (;;)    /* Until full format string read */
-       {
-               while ((format_flag = PGM_READ_CHAR(format++)) != '%')    /* Until '%' or '\0' */
-               {
-                       if (!format_flag)
-                               return (nr_of_chars);
-                       put_one_char(format_flag, secret_pointer);
-                       nr_of_chars++;
-               }
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
-               /*=================================*/
-               /* Optional 'l' or 'h' modifiers ? */
-               /*=================================*/
-               l_modifier = h_modifier = 0;
-               switch (PGM_READ_CHAR(format))
-               {
-                       case 'l':
-                               l_modifier = 1;
-                               format++;
-                               break;
-
-                       case 'h':
-                               h_modifier = 1;
-                               format++;
-                               break;
-               }
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
-               switch (format_flag = PGM_READ_CHAR(format++))
-               {
-                       case 'c':
-                               format_flag = va_arg(ap, int);
-                       default:
-                               put_one_char(format_flag, secret_pointer);
-                               nr_of_chars++;
-                               continue;
-
-                       case 's':
-                               ptr = va_arg(ap, char *);
-                               while ((format_flag = *ptr++))
-                               {
-                                       put_one_char(format_flag, secret_pointer);
-                                       nr_of_chars++;
-                               }
-                               continue;
-
-                       case 'o':
-                               base = 8;
-                               if (IS_SHORT)
-                                       div_val = 0x8000;
-                               else
-                                       div_val = 0x40000000;
-                               goto CONVERSION_LOOP;
-
-                       case 'd':
-                               base = 10;
-                               if (IS_SHORT)
-                                       div_val = 10000;
-                               else
-                                       div_val = 1000000000;
-                               goto CONVERSION_LOOP;
-
-                       case 'X':
-                       case 'x':
-                               base = 16;
-                               if (IS_SHORT)
-                                       div_val = 0x1000;
-                               else
-                                       div_val = 0x10000000;
-
-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);
-                               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);
-#else /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-                               u_val = va_arg(ap,int);
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-                               if (format_flag == 'd')
-                               {
-                                       if (((int)u_val) < 0)
-                                       {
-                                               u_val = - u_val;
-                                               put_one_char('-', secret_pointer);
-                                               nr_of_chars++;
-                                       }
-                               }
-                               while (div_val > 1 && div_val > u_val)
-                               {
-                                       div_val /= base;
-                               }
-                               do
-                               {
-                                       outChar = (u_val / div_val) + '0';
-                                       if (outChar > '9')
-                                       {
-                                               if (format_flag == 'x')
-                                                       outChar += 'a'-'9'-1;
-                                               else
-                                                       outChar += 'A'-'9'-1;
-                                       }
-                                       put_one_char(outChar, secret_pointer);
-                                       nr_of_chars++;
-                                       u_val %= div_val;
-                                       div_val /= base;
-                               }
-                               while (div_val);
-
-               } /* end switch(format_flag...) */
-       }
-#endif /* CONFIG_PRINTF > PRINTF_REDUCED */
-}
-
-#endif /* CONFIG_PRINTF */