Import simple chart drawing code.
[bertos.git] / mware / formatwr.c
index d63aa68463ce2b9a9c3c88eadf7114d8013cce44..d83faba32885829471aedaed8cad361b970f3508 100755 (executable)
  * controlled by giving a -D option a compilation time:
  *
  * \code
- *  -D CONFIG_PRINTF_NOFLOAT      Exclude support for floats
- *  -D CONFIG_PRINTF_REDUCED      Simplified formatter (see below)
- *  -D CONFIG_PRINTF_NOMODIFIERS  Exclude 'l' and 'h' modifiers in reduced version
+ *  -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
  *
  * It means that real variables are not supported as well as field
  * width and precision arguments.
- *
- * The last eight (h and l modifiers) can easily be removed
- * by defining the \c CONFIG_PRINTF_NOMODIFIERS macro.
  */
 
 /*
  * $Log$
+ * 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.
  *
 #include <compiler.h> /* progmem macros */
 #include <config.h> /* CONFIG_ macros */
 
-#ifndef CONFIG_PRINTF_NOFLOAT
+#if CONFIG_PRINTF
+
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
 #include <float.h>
-#endif /* CONFIG_PRINTF_NOFLOAT */
+#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
 
 #ifndef FRMWRI_BUFSIZE
 /*bernie: save some memory, who cares about floats with lots of decimals? */
 #define MEM_ATTRIBUTE
 #endif
 
-#ifndef CONFIG_PRINTF_NOMODIFIERS
-#define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
+       #define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
 #else
-#define IS_SHORT (sizeof(int) == 2)
-#endif
+       #define IS_SHORT (sizeof(int) == 2)
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
 
 
-#ifndef CONFIG_PRINTF_NOFLOAT
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
 
 static char *float_conversion(MEM_ATTRIBUTE long double value,
                MEM_ATTRIBUTE short nr_of_digits,
@@ -262,7 +285,7 @@ CLEAN_UP:
        return (buf_pointer);
 }
 
-#endif /* !CONFIG_PRINTF_NOFLOAT */
+#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
 
 /*!
  * This routine forms the core and entry of the formatter.
@@ -275,10 +298,10 @@ PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
                void *secret_pointer,
                va_list ap)
 {
+#if CONFIG_PRINTF > PRINTF_REDUCED
        MEM_ATTRIBUTE static char bad_conversion[] = "???";
        MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
 
-#ifndef CONFIG_PRINTF_REDUCED
        MEM_ATTRIBUTE char format_flag;
        MEM_ATTRIBUTE int precision;
        MEM_ATTRIBUTE int n;
@@ -288,7 +311,7 @@ PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
        MEM_ATTRIBUTE char nonzero_value;
        MEM_ATTRIBUTE unsigned long ulong, div_factor;
 
-#ifndef CONFIG_PRINTF_NOFLOAT
+#if CONFIG_PRINTF >  PRINTF_NOFLOAT
        MEM_ATTRIBUTE long double fvalue;
 #endif
 
@@ -305,7 +328,7 @@ PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
                {
                        if (!format_flag)
                                return (nr_of_chars);
-                       put_one_char (format_flag, secret_pointer);
+                       put_one_char(format_flag, secret_pointer);
                        nr_of_chars++;
                }
                if (PGM_READ_CHAR(format) == '%')    /* %% prints as % */
@@ -552,7 +575,7 @@ INTEGRAL_CONVERSION:
                                }
                                break;
 
-#ifndef CONFIG_PRINTF_NOFLOAT
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
                        case 'g':
                        case 'G':
                                n = 1;
@@ -600,7 +623,7 @@ FLOATING_CONVERSION:
                                }
                                break;
 
-#else /* CONFIG_PRINTF_NOFLOAT */
+#else /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
                        case 'g':
                        case 'G':
                        case 'f':
@@ -610,7 +633,7 @@ FLOATING_CONVERSION:
                                while (*ptr)
                                        ptr++;
                                break;
-#endif /* CONFIG_PRINTF_NOFLOAT */
+#endif /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
 
                        case '\0': /* Really bad place to find NUL in */
                                format--;
@@ -670,16 +693,15 @@ FLOATING_CONVERSION:
                        }
        }
 
-#else /* CONFIG_PRINTF_REDUCED starts here */
+#else /* PRINTF_REDUCED starts here */
 
-#ifndef CONFIG_PRINTF_NOMODIFIERS
+#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_NOMODIFIERS */
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
 
-       char l_modifier, h_modifier;
        char format_flag;
        unsigned int nr_of_chars, base;
        char outChar;
@@ -692,11 +714,11 @@ FLOATING_CONVERSION:
                {
                        if (!format_flag)
                                return (nr_of_chars);
-                       put_one_char (format_flag, secret_pointer);
+                       put_one_char(format_flag, secret_pointer);
                        nr_of_chars++;
                }
 
-#ifndef CONFIG_PRINTF_NOMODIFIERS
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
                /*=================================*/
                /* Optional 'l' or 'h' modifiers ? */
                /*=================================*/
@@ -713,22 +735,22 @@ FLOATING_CONVERSION:
                                format++;
                                break;
                }
-#endif /* !CONFIG_PRINTF_NOMODIFIERS */
+#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);
+                               put_one_char(format_flag, secret_pointer);
                                nr_of_chars++;
                                continue;
 
                        case 's':
                                ptr = va_arg(ap, char *);
-                               while (format_flag = *ptr++)
+                               while ((format_flag = *ptr++))
                                {
-                                       put_one_char (format_flag, secret_pointer);
+                                       put_one_char(format_flag, secret_pointer);
                                        nr_of_chars++;
                                }
                                continue;
@@ -758,7 +780,7 @@ FLOATING_CONVERSION:
                                        div_val = 0x10000000;
 
 CONVERSION_LOOP:
-#ifndef CONFIG_PRINTF_NOMODIFIERS
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
                                if (h_modifier)
                                        u_val = (format_flag == 'd') ?
                                                (short)va_arg(ap, int) : (unsigned short)va_arg(ap, int);
@@ -767,15 +789,15 @@ CONVERSION_LOOP:
                                else
                                        u_val = (format_flag == 'd') ?
                                                va_arg(ap,int) : va_arg(ap,unsigned int);
-#else /* CONFIG_PRINTF_NOMODIFIERS */
+#else /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
                                u_val = va_arg(ap,int);
-#endif /* CONFIG_PRINTF_NOMODIFIERS */
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
                                if (format_flag == 'd')
                                {
                                        if (((int)u_val) < 0)
                                        {
                                                u_val = - u_val;
-                                               put_one_char ('-', secret_pointer);
+                                               put_one_char('-', secret_pointer);
                                                nr_of_chars++;
                                        }
                                }
@@ -787,11 +809,13 @@ CONVERSION_LOOP:
                                {
                                        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);
+                                       }
+                                       put_one_char(outChar, secret_pointer);
                                        nr_of_chars++;
                                        u_val %= div_val;
                                        div_val /= base;
@@ -800,5 +824,7 @@ CONVERSION_LOOP:
 
                } /* end switch(format_flag...) */
        }
-#endif /* CONFIG_PRINTF_REDUCED */
+#endif /* CONFIG_PRINTF > PRINTF_REDUCED */
 }
+
+#endif /* CONFIG_PRINTF */