/*!
* \file
* <!--
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
* This file is part of DevLib - See devlib/README for information.
* -->
*
* \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 chann-
- * els or new format specifiers.
+ * 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.
+ * controlled by giving a -D option a compilation time:
*
- * -DFLOAT_SUPPORT Full ANSI formatter
- * -DNO_FLOATS Full ANSI except floats
- * -DREDUCED_SUPPORT Reduced 'int' type of converter
+ * \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
+ * \endcode
*
* The reduced version of formatter is suitable when program size is critical
* rather than formatting power. This routine uses less than 20 bytes of
* 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
- * removing the line "#define MODIFIERS_IN_REDUCED".
+ * The last eight (h and l modifiers) can easily be removed
+ * by defining the \c CONFIG_PRINTF_NOMODIFIERS macro.
*/
/*
* $Log$
+ * 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.
*
*
*/
-/* bernie */
-#define FLOAT_SUPPORT
-#undef NO_FLOATS
-#undef REDUCED_SUPPORT
-
-#ifndef FLOAT_SUPPORT
-#ifndef NO_FLOATS
-#ifndef REDUCED_SUPPORT
-#error -DFLOAT_SUPPORT, -DNO_FLOATS or -DREDUCED_SUPPORT missing
-#endif
-#endif
-#endif
-
-/* Make it easy for customers to disable h and l
- modifiers in REDUCED_SUPPORT by removing the next #define */
-#define MODIFIERS_IN_REDUCED
-
#include "formatwr.h"
-#include "compiler.h" /* progmem macros */
+#include <compiler.h> /* progmem macros */
+#include <config.h> /* CONFIG_ macros */
+
+#ifndef CONFIG_PRINTF_NOFLOAT
#include <float.h>
+#endif /* CONFIG_PRINTF_NOFLOAT */
#ifndef FRMWRI_BUFSIZE
/*bernie: save some memory, who cares about floats with lots of decimals? */
#define MEM_ATTRIBUTE
#endif
-#ifdef MODIFIERS_IN_REDUCED
+#ifndef CONFIG_PRINTF_NOMODIFIERS
#define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
#else
#define IS_SHORT (sizeof(int) == 2)
#endif
-#ifdef FLOAT_SUPPORT
+#ifndef CONFIG_PRINTF_NOFLOAT
static char *float_conversion(MEM_ATTRIBUTE long double value,
MEM_ATTRIBUTE short nr_of_digits,
}
nr_of_digits--;
if (alternate_flag)
- {
/* %#G - No removal of trailing zeros */
g_flag = 0;
- }
else
- {
/* %G - Removal of trailing zeros */
alternate_flag = 1;
- }
}
/* %e or %E */
{
*buf_pointer++ = '0';
if ((n = nr_of_digits) || alternate_flag)
- {
*buf_pointer++ = '.';
- }
i = 0;
while (--i > integral_10_log && nr_of_digits)
{
nr_of_digits--;
}
if (integral_10_log < (-n - 1))
- {
/* Nothing more to do */
goto CLEAN_UP;
- }
dec_point_pos = 1;
}
else
value *= 10; /* Prepare for next shot */
*buf_pointer++ = n + '0';
if ( ! i++ && (nr_of_digits || alternate_flag))
- {
*buf_pointer++ = '.';
- }
}
/* Rounding possible */
n = 1;
}
else
- {
n = 0;
- }
}
} while (cp-- > buf);
if (n)
cp--;
}
else
- {
*cp = *(cp - 1);
- }
cp--;
}
integral_10_log++;
if (g_flag)
{
while (*(buf_pointer - 1) == '0')
- {
buf_pointer--;
- }
if (*(buf_pointer - 1) == '.')
- {
buf_pointer--;
- }
}
/* %e or %E */
integral_10_log = -integral_10_log;
}
else
- {
*buf_pointer++ = '+';
- }
n = 0;
buf_pointer +=10;
do
return (buf_pointer);
}
-#endif /* FLOAT_SUPPORT */
+#endif /* !CONFIG_PRINTF_NOFLOAT */
/*!
* This routine forms the core and entry of the formatter.
MEM_ATTRIBUTE static char bad_conversion[] = "???";
MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
-#ifndef REDUCED_SUPPORT
+#ifndef CONFIG_PRINTF_REDUCED
MEM_ATTRIBUTE char format_flag;
MEM_ATTRIBUTE int precision;
MEM_ATTRIBUTE int n;
MEM_ATTRIBUTE char nonzero_value;
MEM_ATTRIBUTE unsigned long ulong, div_factor;
-#ifdef FLOAT_SUPPORT
+#ifndef CONFIG_PRINTF_NOFLOAT
MEM_ATTRIBUTE long double fvalue;
#endif
}
break;
-#ifdef FLOAT_SUPPORT
+#ifndef CONFIG_PRINTF_NOFLOAT
case 'g':
case 'G':
n = 1;
}
break;
-#else /* !FLOAT_SUPPORT */
+#else /* CONFIG_PRINTF_NOFLOAT */
case 'g':
case 'G':
case 'f':
while (*ptr)
ptr++;
break;
-#endif /* !FLOAT_SUPPORT */
+#endif /* CONFIG_PRINTF_NOFLOAT */
case '\0': /* Really bad place to find NUL in */
format--;
}
}
-#else /* REDUCED_SUPPORT STARTS HERE */
+#else /* CONFIG_PRINTF_REDUCED starts here */
-#ifdef MODIFIERS_IN_REDUCED
+#ifndef CONFIG_PRINTF_NOMODIFIERS
char l_modifier, h_modifier;
unsigned long u_val, div_val;
#else
unsigned int u_val, div_val;
-#endif
+#endif /* CONFIG_PRINTF_NOMODIFIERS */
+
+ char l_modifier, h_modifier;
char format_flag;
unsigned int nr_of_chars, base;
char outChar;
nr_of_chars++;
}
-#ifdef MODIFIERS_IN_REDUCED
+#ifndef CONFIG_PRINTF_NOMODIFIERS
/*=================================*/
/* Optional 'l' or 'h' modifiers ? */
/*=================================*/
format++;
break;
}
-#endif
+#endif /* !CONFIG_PRINTF_NOMODIFIERS */
switch (format_flag = PGM_READ_CHAR(format++))
{
div_val = 0x10000000;
CONVERSION_LOOP:
-#ifdef MODIFIERS_IN_REDUCED
+#ifndef CONFIG_PRINTF_NOMODIFIERS
if (h_modifier)
u_val = (format_flag == 'd') ?
(short)va_arg(ap, int) : (unsigned short)va_arg(ap, int);
else
u_val = (format_flag == 'd') ?
va_arg(ap,int) : va_arg(ap,unsigned int);
-#else
+#else /* CONFIG_PRINTF_NOMODIFIERS */
u_val = va_arg(ap,int);
-#endif
+#endif /* CONFIG_PRINTF_NOMODIFIERS */
if (format_flag == 'd')
{
if (((int)u_val) < 0)
} /* end switch(format_flag...) */
}
-#endif
+#endif /* CONFIG_PRINTF_REDUCED */
}