summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-05 20:38:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-05 20:38:39 +0000
commit36be54817fe1d8879f26b7f0e1797e8ba23e8a0f (patch)
treedcb1e1716e40880ec68883fdc0a50123eea77293
parent152b278e70541d86a06e76c25f37c9588526c6fa (diff)
downloadnuttx-36be54817fe1d8879f26b7f0e1797e8ba23e8a0f.tar.gz
nuttx-36be54817fe1d8879f26b7f0e1797e8ba23e8a0f.tar.bz2
nuttx-36be54817fe1d8879f26b7f0e1797e8ba23e8a0f.zip
Re-design vsprintf so that it does not use so much stack; handle 8051's 2-byte generic pointers.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@38 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/README.txt6
-rw-r--r--nuttx/arch/c5471/defconfig8
-rw-r--r--nuttx/arch/pjrc-8051/defconfig8
-rw-r--r--nuttx/arch/pjrc-8051/src/up_allocateheap.c2
-rw-r--r--nuttx/arch/pjrc-8051/src/up_irq.c4
-rw-r--r--nuttx/arch/sim/defconfig8
-rw-r--r--nuttx/include/nuttx/compiler.h18
-rw-r--r--nuttx/lib/Makefile3
-rw-r--r--nuttx/lib/lib_internal.h4
-rw-r--r--nuttx/lib/lib_libvsprintf.c1768
-rw-r--r--nuttx/lib/lib_nullstream.c62
11 files changed, 1307 insertions, 584 deletions
diff --git a/nuttx/arch/README.txt b/nuttx/arch/README.txt
index 64a77e924..35279349f 100644
--- a/nuttx/arch/README.txt
+++ b/nuttx/arch/README.txt
@@ -111,6 +111,12 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_PTHREAD.
CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE
+
+ Misc libc settings
+
+ CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
+ little smaller if we do not support fieldwidthes
+
Allow for architecture optimized implementations
The architecture can provide optimized versions of the
diff --git a/nuttx/arch/c5471/defconfig b/nuttx/arch/c5471/defconfig
index 1ce7dd879..e3f8d028a 100644
--- a/nuttx/arch/c5471/defconfig
+++ b/nuttx/arch/c5471/defconfig
@@ -136,6 +136,14 @@ CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
#
+# Misc libc settings
+#
+# CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
+# little smaller if we do not support fieldwidthes
+#
+CONFIG_NOPRINTF_FIELDWIDTH=n
+
+#
# Allow for architecture optimized implementations
#
# The architecture can provide optimized versions of the
diff --git a/nuttx/arch/pjrc-8051/defconfig b/nuttx/arch/pjrc-8051/defconfig
index 508440c27..c24f0a08d 100644
--- a/nuttx/arch/pjrc-8051/defconfig
+++ b/nuttx/arch/pjrc-8051/defconfig
@@ -103,6 +103,14 @@ CONFIG_DISABLE_SIGNALS=y
CONFIG_DISABLE_MQUEUE=y
#
+# Misc libc settings
+#
+# CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
+# little smaller if we do not support fieldwidthes
+#
+CONFIG_NOPRINTF_FIELDWIDTH=y
+
+#
# Allow for architecture optimized implementations
#
# The architecture can provide optimized versions of the
diff --git a/nuttx/arch/pjrc-8051/src/up_allocateheap.c b/nuttx/arch/pjrc-8051/src/up_allocateheap.c
index b6e6a0208..bdbe464b4 100644
--- a/nuttx/arch/pjrc-8051/src/up_allocateheap.c
+++ b/nuttx/arch/pjrc-8051/src/up_allocateheap.c
@@ -84,4 +84,4 @@ void up_addregion(void)
{
mm_addregion((FAR void*)UP_HEAP2_BASE, UP_HEAP2_END - UP_HEAP2_BASE);
}
-#endif \ No newline at end of file
+#endif
diff --git a/nuttx/arch/pjrc-8051/src/up_irq.c b/nuttx/arch/pjrc-8051/src/up_irq.c
index 772623167..e9f2c2a13 100644
--- a/nuttx/arch/pjrc-8051/src/up_irq.c
+++ b/nuttx/arch/pjrc-8051/src/up_irq.c
@@ -69,11 +69,15 @@
void up_irqinitialize(void)
{
+#if 1 /* remove me */
+ IE = 0;
+#else
/* Enable interrupts globally, but disable all interrupt
* sources.
*/
IE = 0x80;
+#endif
}
/************************************************************
diff --git a/nuttx/arch/sim/defconfig b/nuttx/arch/sim/defconfig
index 9d8aab7aa..1dbd2365d 100644
--- a/nuttx/arch/sim/defconfig
+++ b/nuttx/arch/sim/defconfig
@@ -103,6 +103,14 @@ CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
#
+# Misc libc settings
+#
+# CONFIG_NOPRINTF_FIELDWIDTH - sprintf-related logic is a
+# little smaller if we do not support fieldwidthes
+#
+CONFIG_NOPRINTF_FIELDWIDTH=n
+
+#
# Allow for architecture optimized implementations
#
# The architecture can provide optimized versions of the
diff --git a/nuttx/include/nuttx/compiler.h b/nuttx/include/nuttx/compiler.h
index 640129bed..304759065 100644
--- a/nuttx/include/nuttx/compiler.h
+++ b/nuttx/include/nuttx/compiler.h
@@ -80,6 +80,14 @@
# undef CONFIG_SMALL_MEMORY
+/* Long and int are (probably) the same size */
+
+# undef CONFIG_LONG_IS_NOT_INT
+
+/* The pointers and int are the same size */
+
+# undef CONFIG_PTR_IS_NOT_INT
+
/* GCC supports inlined functions */
# define CONFIG_HAVE_INLINE 1
@@ -140,6 +148,14 @@
# define CONFIG_SMALL_MEMORY 1
+/* Long and int are not the same size */
+
+# define CONFIG_LONG_IS_NOT_INT 1
+
+/* The generic point and int are not the same size */
+
+# define CONFIG_PTR_IS_NOT_INT 1
+
/* SDCC does not support inline functions */
# undef CONFIG_HAVE_INLINE
@@ -172,6 +188,8 @@
# define CODE
# undef CONFIG_SMALL_MEMORY
+# undef CONFIG_LONG_IS_NOT_INT
+# undef CONFIG_PTR_IS_NOT_INT
# undef CONFIG_HAVE_INLINE
# undef CONFIG_HAVE_LONG_LONG
# undef CONFIG_HAVE_DOUBLE
diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile
index 5e1c564bb..2189db7a5 100644
--- a/nuttx/lib/Makefile
+++ b/nuttx/lib/Makefile
@@ -52,7 +52,8 @@ STDIO_SRCS = lib_fopen.c lib_fclose.c \
lib_ungetc.c \
lib_printf.c lib_vprintf.c lib_fprintf.c lib_rawprintf.c lib_lowprintf.c \
lib_vfprintf.c lib_sprintf.c lib_libsprintf.c lib_vsprintf.c \
- lib_libvsprintf.c lib_stdstream.c lib_memstream.c lib_rawstream.c lib_lowstream.c \
+ lib_libvsprintf.c lib_stdstream.c lib_memstream.c \
+ lib_rawstream.c lib_lowstream.c lib_nullstream.c \
lib_sscanf.c
STDLIB_SRCS = lib_getenv.c lib_rand.c
MATH_SRCS = lib_rint.c
diff --git a/nuttx/lib/lib_internal.h b/nuttx/lib/lib_internal.h
index 5b72e7ce2..1017ed560 100644
--- a/nuttx/lib/lib_internal.h
+++ b/nuttx/lib/lib_internal.h
@@ -128,6 +128,10 @@ extern void lib_rawstream(struct lib_rawstream_s *rawstream,
extern void lib_lowstream(struct lib_stream_s *rawstream);
#endif
+/* Defined in lib_nullstream.c */
+
+extern void lib_nullstream(struct lib_stream_s *nullstream);
+
/* Defined in lib_libsprintf.c */
extern int lib_sprintf (struct lib_stream_s *obj,
diff --git a/nuttx/lib/lib_libvsprintf.c b/nuttx/lib/lib_libvsprintf.c
index 443d17d46..ebfd4dbea 100644
--- a/nuttx/lib/lib_libvsprintf.c
+++ b/nuttx/lib/lib_libvsprintf.c
@@ -60,6 +60,44 @@ enum
FMT_CENTER
};
+#define FLAG_SHOWPLUS 0x01
+#define FLAG_ALTFORM 0x02
+#define FLAG_HASDOT 0x04
+#define FLAG_HASASTERISKWIDTH 0x08
+#define FLAG_HASASTERISKTRUNC 0x10
+#define FLAG_LONGPRECISION 0x20
+#define FLAG_LONGLONGPRECISION 0x40
+#define FLAG_NEGATE 0x80
+
+#define SET_SHOWPLUS(f) do (f) |= FLAG_SHOWPLUS; while (0)
+#define SET_ALTFORM(f) do (f) |= FLAG_ALTFORM; while (0)
+#define SET_HASDOT(f) do (f) |= FLAG_HASDOT; while (0)
+#define SET_HASASTERISKWIDTH(f) do (f) |= FLAG_HASASTERISKWIDTH; while (0)
+#define SET_HASASTERISKTRUNC(f) do (f) |= FLAG_HASASTERISKTRUNC; while (0)
+#define SET_LONGPRECISION(f) do (f) |= FLAG_LONGPRECISION; while (0)
+#define SET_LONGLONGPRECISION(f) do (f) |= FLAG_LONGLONGPRECISION; while (0)
+#define SET_NEGATE(f) do (f) |= FLAG_NEGATE; while (0)
+
+#define CLR_SHOWPLUS(f) do (f) &= ~FLAG_SHOWPLUS; while (0)
+#define CLR_ALTFORM(f) do (f) &= ~FLAG_ALTFORM; while (0)
+#define CLR_HASDOT(f) do (f) &= ~FLAG_HASDOT; while (0)
+#define CLR_HASASTERISKWIDTH(f) do (f) &= ~FLAG_HASASTERISKWIDTH; while (0)
+#define CLR_HASASTERISKTRUNC(f) do (f) &= ~FLAG_HASASTERISKTRUNC; while (0)
+#define CLR_LONGPRECISION(f) do (f) &= ~FLAG_LONGPRECISION; while (0)
+#define CLR_LONGLONGPRECISION(f) do (f) &= ~FLAG_LONGLONGPRECISION; while (0)
+#define CLR_NEGATE(f) do (f) &= ~FLAG_NEGATE; while (0)
+#define CLR_SIGNED(f) do (f) &= ~(FLAG_SHOWPLUS|FLAG_NEGATE); while (0)
+
+#define IS_SHOWPLUS(f) (((f) & FLAG_SHOWPLUS) != 0)
+#define IS_ALTFORM(f) (((f) & FLAG_ALTFORM) != 0)
+#define IS_HASDOT(f) (((f) & FLAG_HASDOT) != 0)
+#define IS_HASASTERISKWIDTH(f) (((f) & FLAG_HASASTERISKWIDTH) != 0)
+#define IS_HASASTERISKTRUNC(f) (((f) & FLAG_HASASTERISKTRUNC) != 0)
+#define IS_LONGPRECISION(f) (((f) & FLAG_LONGPRECISION) != 0)
+#define IS_LONGLONGPRECISION(f) (((f) & FLAG_LONGLONGPRECISION) != 0)
+#define IS_NEGATE(f) (((f) & FLAG_NEGATE) != 0)
+#define IS_SIGNED(f) (((f) & (FLAG_SHOWPLUS|FLAG_NEGATE)) != 0)
+
/************************************************************
* Private Type Declarations
************************************************************/
@@ -68,24 +106,64 @@ enum
* Private Function Prototypes
************************************************************/
-static void utodec(char **pp, unsigned int n);
-static void _utodec(char **pp, unsigned int n);
-static void utohex(char **pp, unsigned int n);
-static void _utohex(char **pp, unsigned int n);
-static void utooct(char **pp, unsigned int n);
-static void _utooct(char **pp, unsigned int n);
-static void utobin(char **pp, unsigned int n);
-static void _utobin(char **pp, unsigned int n);
+/* Pointer to ASCII conversion */
+
+#ifdef CONFIG_PTR_IS_NOT_INT
+static void ptohex(struct lib_stream_s *obj, ubyte flags, void *p);
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static int getsizesize(ubyte fmt, ubyte flags, void *p)
+#endif /* CONFIG_NOPRINTF_FIELDWIDTH */
+#endif /* CONFIG_PTR_IS_NOT_INT */
+
+/* Unsigned int to ASCII conversion */
+
+static void utodec(struct lib_stream_s *obj, unsigned int n);
+static void utohex(struct lib_stream_s *obj, unsigned int n, ubyte a);
+static void utooct(struct lib_stream_s *obj, unsigned int n);
+static void utobin(struct lib_stream_s *obj, unsigned int n);
+static void utoascii(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, unsigned int lln);
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void fixup(ubyte fmt, ubyte *flags, int *n);
+static int getusize(ubyte fmt, ubyte flags, unsigned int lln);
+#endif
+
+/* Unsigned long int to ASCII conversion */
+
+#ifdef CONFIG_LONG_IS_NOT_INT
+static void lutodec(struct lib_stream_s *obj, unsigned long ln);
+static void lutohex(struct lib_stream_s *obj, unsigned long ln, ubyte a);
+static void lutooct(struct lib_stream_s *obj, unsigned long ln);
+static void lutobin(struct lib_stream_s *obj, unsigned long ln);
+static void lutoascii(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, unsigned long ln);
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void lfixup(ubyte fmt, ubyte *flags, long *ln);
+static int getlusize(ubyte fmt, ubyte flags, unsigned long ln);
+#endif
+#endif
+
+/* Unsigned long long int to ASCII conversions */
#ifdef CONFIG_HAVE_LONG_LONG
-static void llutodec(char **pp, unsigned long long n);
-static void _llutodec(char **pp, unsigned long long n);
-static void llutohex(char **pp, unsigned long long n);
-static void _llutohex(char **pp, unsigned long long n);
-static void llutooct(char **pp, unsigned long long n);
-static void _llutooct(char **pp, unsigned long long n);
-static void llutobin(char **pp, unsigned long long n);
-static void _llutobin(char **pp, unsigned long long n);
+static void llutodec(struct lib_stream_s *obj, unsigned long long lln);
+static void llutohex(struct lib_stream_s *obj, unsigned long long lln, ubyte a);
+static void llutooct(struct lib_stream_s *obj, unsigned long long lln);
+static void llutobin(struct lib_stream_s *obj, unsigned long long lln);
+static void llutoascii(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, unsigned long long lln);
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void llfixup(ubyte fmt, ubyte *flags, long long *lln);
+static int getllusize(ubyte fmt, ubyte flags, unsigned long long lln);
+#endif
+#endif
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void prejustify(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, int fieldwidth, int numwidth);
+static void postjustify(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, int fieldwidth, int numwidth);
#endif
/************************************************************
@@ -110,182 +188,899 @@ static const char g_nullstring[] = "(null)";
* Private Functions
************************************************************/
-static void utodec(char **pp, unsigned int n)
+/************************************************************
+ * Name: ptohex
+ ************************************************************/
+
+#ifdef CONFIG_PTR_IS_NOT_INT
+static void ptohex(struct lib_stream_s *obj, ubyte flags, void *p)
+{
+ union
+ {
+ uint32 dw;
+ void *p;
+ } u;
+ ubyte bits;
+
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with "0x" */
+
+ obj->put(obj, '0');
+ obj->put(obj, 'x');
+ }
+
+ u.dw = 0;
+ u.p = p;
+
+ for (bits = 8*sizeof(void *); bits > 0; bits -= 4)
+ {
+ ubyte nibble = (ubyte)((u.dw >> (bits - 4)) & 0xf);
+ if (nibble < 10)
+ {
+ obj->put(obj, nibble + '0');
+ }
+ else
+ {
+ obj->put(obj, nibble + 'a' - 10);
+ }
+ }
+}
+
+/************************************************************
+ * Name: getpsize
+ ************************************************************/
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static int getpsize(ubyte flags, void *p)
{
- _utodec(pp, n);
- **pp = 0;
+ struct lib_stream_s nullstream;
+ lib_nullstream(&nullstream);
+
+
+ ptohex(&nullstream, flags, p);
+ return nullstream.nput;
}
-static void _utodec(char **pp, unsigned int n)
+#endif /* CONFIG_NOPRINTF_FIELDWIDTH */
+#endif /* CONFIG_PTR_IS_NOT_INT */
+
+/************************************************************
+ * Name: utodec
+ ************************************************************/
+
+static void utodec(struct lib_stream_s *obj, unsigned int n)
{
unsigned int remainder = n % 10;
- unsigned int dividend = n / 10;
+ unsigned int dividend = n / 10;
if (dividend)
{
- _utodec(pp, dividend);
+ utodec(obj, dividend);
}
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void utohex(char **pp, unsigned int n)
+/************************************************************
+ * Name: utohex
+ ************************************************************/
+
+static void utohex(struct lib_stream_s *obj, unsigned int n, ubyte a)
{
- _utohex(pp, n);
- **pp = 0;
+ boolean nonleading = FALSE;
+ ubyte bits;
+
+ for (bits = 8*sizeof(unsigned int); bits > 0; bits -= 4)
+ {
+ ubyte nibble = (ubyte)((n >> (bits - 4)) & 0xf);
+ if (nibble || nonleading)
+ {
+ nonleading = TRUE;
+
+ if (nibble < 10)
+ {
+ obj->put(obj, nibble + '0');
+ }
+ else
+ {
+ obj->put(obj, nibble + a - 10);
+ }
+ }
+ }
}
-static void _utohex(char **pp, unsigned int n)
+/************************************************************
+ * Name: utooct
+ ************************************************************/
+
+static void utooct(struct lib_stream_s *obj, unsigned int n)
{
- unsigned int remainder = n & 0xf;
- unsigned int dividend = n >> 4;
+ unsigned int remainder = n & 0x7;
+ unsigned int dividend = n >> 3;
if (dividend)
{
- _utohex(pp, dividend);
+ utooct(obj, dividend);
}
- if (remainder < 10)
- {
- **pp = (char)(remainder + (unsigned int)'0');
- }
- else
+ obj->put(obj, (remainder + (unsigned int)'0'));
+}
+
+/************************************************************
+ * Name: utobin
+ ************************************************************/
+
+static void utobin(struct lib_stream_s *obj, unsigned int n)
+{
+ unsigned int remainder = n & 1;
+ unsigned int dividend = n >> 1;
+
+ if (dividend)
{
- **pp = (char)(remainder + ((unsigned int)'a' - 10));
+ utobin(obj, dividend);
}
- (*pp)++;
+
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void utooct(char **pp, unsigned int n)
+/************************************************************
+ * Name: lutoascii
+ ************************************************************/
+
+static void utoascii(struct lib_stream_s *obj, ubyte fmt, ubyte flags, unsigned int n)
{
- _utooct(pp, n);
- **pp = 0;
+ /* Perform the integer conversion according to the format specifier */
+
+ switch (fmt)
+ {
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if ((int)n < 0)
+ {
+ obj->put(obj, '-');
+ n = (unsigned int)(-(int)n);
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ utodec(obj, n);
+ }
+ break;
+
+ case 'u':
+ /* Unigned base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ utodec(obj, n);
+ }
+ break;
+
+#ifndef CONFIG_PTR_IS_NOT_INT
+ case 'p':
+#endif
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with "0x" */
+
+ obj->put(obj, '0');
+ obj->put(obj, 'x');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ if (fmt == 'X')
+ {
+ utohex(obj, n, 'A');
+ }
+ else
+ {
+ utohex(obj, n, 'a');
+ }
+ }
+ break;
+
+ case 'o':
+ /* Octal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with '0' */
+
+ obj->put(obj, '0');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ utooct(obj, n);
+ }
+ break;
+
+ case 'b':
+ /* Binary */
+ {
+ /* Convert the unsigned value to a string. */
+
+ utobin(obj, n);
+ }
+ break;
+
+#ifdef CONFIG_PTR_IS_NOT_INT
+ case 'p':
+#endif
+ default:
+ break;
+ }
}
-static void _utooct(char **pp, unsigned int n)
+/************************************************************
+ * Name: fixup
+ ************************************************************/
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void fixup(ubyte fmt, ubyte *flags, int *n)
{
- unsigned int remainder = n & 0x7;
- unsigned int dividend = n >> 3;
+ /* Perform the integer conversion according to the format specifier */
- if (dividend)
+ switch (fmt)
{
- _utooct(pp, dividend);
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+
+ if (n < 0)
+ {
+ SET_NEGATE(*flags);
+ CLR_SHOWPLUS(*flags);
+ *n = -*n;
+ }
+ break;
+
+ case 'u':
+ /* Unsigned base 10 */
+ break;
+
+ case 'p':
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ case 'o':
+ /* Octal */
+ case 'b':
+ /* Binary */
+ CLR_SIGNED(*flags);
+ break;
+
+ default:
+ break;
}
-
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
}
-static void utobin(char **pp, unsigned int n)
+/************************************************************
+ * Name: getusize
+ ************************************************************/
+
+static int getusize(ubyte fmt, ubyte flags, unsigned int n)
{
- _utobin(pp, n);
- **pp = 0;
+ struct lib_stream_s nullstream;
+ lib_nullstream(&nullstream);
+
+ utoascii(&nullstream, fmt, flags, n);
+ return nullstream.nput;
}
+#endif /* CONFIG_NOPRINTF_FIELDWIDTH */
+
+#ifdef CONFIG_LONG_IS_NOT_INT
+/************************************************************
+ * Name: lutodec
+ ************************************************************/
-static void _utobin(char **pp, unsigned int n)
+static void lutodec(struct lib_stream_s *obj, unsigned long n)
{
- unsigned int remainder = n & 1;
- unsigned int dividend = n >> 1;
+ unsigned int remainder = n % 10;
+ unsigned long dividend = n / 10;
if (dividend)
{
- _utobin(pp, dividend);
+ lutodec(obj, dividend);
}
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-#ifdef CONFIG_HAVE_LONG_LONG
-static void llutodec(char **pp, unsigned long long n)
+/************************************************************
+ * Name: lutohex
+ ************************************************************/
+
+static void lutohex(struct lib_stream_s *obj, unsigned long n, ubyte a)
{
- _llutodec(pp, n);
- **pp = 0;
+ boolean nonleading = FALSE;
+ ubyte bits;
+
+ for (bits = 8*sizeof(unsigned long); bits > 0; bits -= 4)
+ {
+ ubyte nibble = (ubyte)((n >> (bits - 4)) & 0xf);
+ if (nibble || nonleading)
+ {
+ nonleading = TRUE;
+
+ if (nibble < 10)
+ {
+ obj->put(obj, nibble + '0');
+ }
+ else
+ {
+ obj->put(obj, nibble + a - 10);
+ }
+ }
+ }
}
-static void _llutodec(char **pp, unsigned long long n)
+/************************************************************
+ * Name: lutooct
+ ************************************************************/
+
+static void lutooct(struct lib_stream_s *obj, unsigned long n)
{
- unsigned int remainder = n % 10;
- unsigned long long dividend = n / 10;
+ unsigned int remainder = n & 0x7;
+ unsigned long dividend = n >> 3;
if (dividend)
{
- _llutodec(pp, dividend);
+ lutooct(obj, dividend);
}
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void llutohex(char **pp, unsigned long long n)
+/************************************************************
+ * Name: lutobin
+ ************************************************************/
+
+static void lutobin(struct lib_stream_s *obj, unsigned long n)
{
- _llutohex(pp, n);
- **pp = 0;
+ unsigned int remainder = n & 1;
+ unsigned long dividend = n >> 1;
+
+ if (dividend)
+ {
+ lutobin(obj, dividend);
+ }
+
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void _llutohex(char **pp, unsigned long long n)
+/************************************************************
+ * Name: lutoascii
+ ************************************************************/
+
+static void lutoascii(struct lib_stream_s *obj, ubyte fmt, ubyte flags, unsigned long ln)
{
- unsigned int remainder = n & 0xf;
- unsigned long long dividend = n >> 4;
- if (dividend)
+ /* Perform the integer conversion according to the format specifier */
+
+ switch (fmt)
{
- _llutohex(pp, dividend);
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if ((long)ln < 0)
+ {
+ obj->put(obj, '-');
+ ln = (unsigned long)(-(long)ln);
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ lutodec(obj, ln);
+ }
+ break;
+
+ case 'u':
+ /* Unigned base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ lutodec(obj, ln);
+ }
+ break;
+
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with "0x" */
+
+ obj->put(obj, '0');
+ obj->put(obj, 'x');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ if (fmt == 'X')
+ {
+ lutohex(obj, ln, 'A');
+ }
+ else
+ {
+ lutohex(obj, ln, 'a');
+ }
+ }
+ break;
+
+ case 'o':
+ /* Octal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with '0' */
+
+ obj->put(obj, '0');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ lutooct(obj, ln);
+ }
+ break;
+
+ case 'b':
+ /* Binary */
+ {
+ /* Convert the unsigned value to a string. */
+
+ lutobin(obj, ln);
+ }
+ break;
+
+ case 'p':
+ default:
+ break;
}
+}
- if (remainder < 10)
+/************************************************************
+ * Name: lfixup
+ ************************************************************/
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void lfixup(ubyte fmt, ubyte *flags, long *ln)
+{
+ /* Perform the integer conversion according to the format specifier */
+
+ switch (fmt)
{
- **pp = (char)(remainder + (unsigned int)'0');
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+
+ if (ln < 0)
+ {
+ SET_NEGATE(*flags);
+ CLR_SHOWPLUS(*flags);
+ *ln = -*ln;
+ }
+ break;
+
+ case 'u':
+ /* Unsigned base 10 */
+ break;
+
+ case 'p':
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ case 'o':
+ /* Octal */
+ case 'b':
+ /* Binary */
+ CLR_SIGNED(*flags);
+ break;
+
+ default:
+ break;
}
- else
+}
+
+/************************************************************
+ * Name: getlusize
+ ************************************************************/
+
+static int getlusize(ubyte fmt, ubyte flags, unsigned long ln)
+{
+ struct lib_stream_s nullstream;
+ lib_nullstream(&nullstream);
+
+ lutoascii(&nullstream, fmt, flags, ln);
+ return nullstream.nput;
+}
+
+#endif /* CONFIG_NOPRINTF_FIELDWIDTH */
+#endif /* CONFIG_LONG_IS_NOT_INT */
+
+#ifdef CONFIG_HAVE_LONG_LONG
+/************************************************************
+ * Name: llutodec
+ ************************************************************/
+
+static void llutodec(struct lib_stream_s *obj, unsigned long long n)
+{
+ unsigned int remainder = n % 10;
+ unsigned long long dividend = n / 10;
+
+ if (dividend)
{
- **pp = (char)(remainder + ((unsigned int)'a' - 10));
+ llutodec(obj, dividend);
}
- (*pp)++;
+
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void llutooct(char **pp, unsigned long long n)
+/************************************************************
+ * Name: llutohex
+ ************************************************************/
+
+static void llutohex(struct lib_stream_s *obj, unsigned long long n, ubyte a)
{
- _llutooct(pp, n);
- **pp = 0;
+ boolean nonleading = FALSE;
+ ubyte bits;
+
+ for (bits = 8*sizeof(unsigned long long); bits > 0; bits -= 4)
+ {
+ ubyte nibble = (ubyte)((n >> (bits - 4)) & 0xf);
+ if (nibble || nonleading)
+ {
+ nonleading = TRUE;
+
+ if (nibble < 10)
+ {
+ obj->put(obj, (nibble + '0'));
+ }
+ else
+ {
+ obj->put(obj, (nibble + a - 10));
+ }
+ }
+ }
}
-static void _llutooct(char **pp, unsigned long long n)
+/************************************************************
+ * Name: llutooct
+ ************************************************************/
+
+static void llutooct(struct lib_stream_s *obj, unsigned long long n)
{
unsigned int remainder = n & 0x7;
unsigned long long dividend = n >> 3;
if (dividend)
{
- _llutooct(pp, dividend);
+ llutooct(obj, dividend);
}
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
+ obj->put(obj, (remainder + (unsigned int)'0'));
}
-static void llutobin(char **pp, unsigned long long n)
-{
- _llutobin(pp, n);
- **pp = 0;
-}
+/************************************************************
+ * Name: llutobin
+ ************************************************************/
-static void _llutobin(char **pp, unsigned long long n)
+static void llutobin(struct lib_stream_s *obj, unsigned long long n)
{
unsigned int remainder = n & 1;
unsigned long long dividend = n >> 1;
if (dividend)
{
- _llutobin(pp, dividend);
+ llutobin(obj, dividend);
+ }
+
+ obj->put(obj, (remainder + (unsigned int)'0'));
+}
+
+/************************************************************
+ * Name: llutoascii
+ ************************************************************/
+
+static void llutoascii(struct lib_stream_s *obj, ubyte fmt, ubyte flags, unsigned long long lln)
+{
+ /* Perform the integer conversion according to the format specifier */
+
+ switch (fmt)
+ {
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if ((long long)lln < 0)
+ {
+ obj->put(obj, '-');
+ lln = (unsigned long long)(-(long long)*lln);
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ llutodec(obj, (unsigned long long)lln);
+ }
+ break;
+
+ case 'u':
+ /* Unigned base 10 */
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+#endif
+ /* Convert the unsigned value to a string. */
+
+ llutodec(obj, (unsigned long long)lln);
+ }
+ break;
+
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with "0x" */
+
+ obj->put(obj, '0');
+ obj->put(obj, 'x');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ if (fmt == 'X')
+ {
+ llutohex(obj, (unsigned long long)lln, 'A');
+ }
+ else
+ {
+ llutohex(obj, (unsigned long long)lln, 'a');
+ }
+ }
+ break;
+
+ case 'o':
+ /* Octal */
+ {
+ /* Check for alternate form */
+
+ if (IS_ALTFORM(flags))
+ {
+ /* Prefix the number with '0' */
+
+ obj->put(obj, '0');
+ }
+
+ /* Convert the unsigned value to a string. */
+
+ llutooct(obj, (unsigned long long)lln);
+ }
+ break;
+
+ case 'b':
+ /* Binary */
+ {
+ /* Convert the unsigned value to a string. */
+
+ llutobin(obj, (unsigned long long)lln);
+ }
+ break;
+
+ case 'p':
+ default:
+ break;
+ }
+}
+
+/************************************************************
+ * Name: llfixup
+ ************************************************************/
+
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+static void llfixup(ubyte fmt, ubyte *flags, long long *lln)
+{
+ /* Perform the integer conversion according to the format specifier */
+
+ switch (fmt)
+ {
+ case 'd':
+ case 'i':
+ /* Signed base 10 */
+
+ if (lln < 0)
+ {
+ SET_NEGATE(*flags);
+ CLR_SHOWPLUS(*flags);
+ *lln = -*lln;
+ }
+ break;
+
+ case 'u':
+ /* Unsigned base 10 */
+ break;
+
+ case 'p':
+ case 'x':
+ case 'X':
+ /* Hexadecimal */
+ case 'o':
+ /* Octal */
+ case 'b':
+ /* Binary */
+ CLR_SIGNED(*flags);
+ break;
+
+ default:
+ break;
}
+}
- **pp = (char)(remainder + (unsigned int)'0');
- (*pp)++;
+/************************************************************
+ * Name: getllusize
+ ************************************************************/
+
+static int getllusize(ubyte fmt, ubyte flags, unsigned long long lln)
+{
+ struct lib_stream_s nullstream;
+ lib_nullstream(&nullstream);
+
+
+ llutoascii(&nullstream, fmt, flags, lln);
+ return nullstream.nput;
}
+
+#endif /* CONFIG_NOPRINTF_FIELDWIDTH */
#endif /* CONFIG_HAVE_LONG_LONG */
/************************************************************
+ * Name: prejustify
+ ************************************************************/
+
+static void prejustify(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, int fieldwidth, int numwidth)
+{
+ int i;
+
+ switch (fmt)
+ {
+ default:
+ case FMT_RJUST:
+ if (IS_SIGNED(flags))
+ {
+ numwidth++;
+ }
+
+ for (i = fieldwidth - numwidth; i > 0; i--)
+ {
+ obj->put(obj, ' ');
+ }
+
+ if (IS_NEGATE(flags))
+ {
+ obj->put(obj, '-');
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+ break;
+
+ case FMT_RJUST0:
+ if (IS_NEGATE(flags))
+ {
+ obj->put(obj, '-');
+ numwidth++;
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ numwidth++;
+ }
+
+ for (i = fieldwidth - numwidth; i > 0; i--)
+ {
+ obj->put(obj, '0');
+ }
+ break;
+
+ case FMT_LJUST:
+ if (IS_NEGATE(flags))
+ {
+ obj->put(obj, '-');
+ }
+ else if (IS_SHOWPLUS(flags))
+ {
+ obj->put(obj, '+');
+ }
+ break;
+ }
+}
+
+/************************************************************
+ * Name: postjustify
+ ************************************************************/
+
+static void postjustify(struct lib_stream_s *obj, ubyte fmt,
+ ubyte flags, int fieldwidth, int numwidth)
+{
+ int i;
+
+ /* Apply field justification to the integer value. */
+
+ switch (fmt)
+ {
+ default:
+ case FMT_RJUST:
+ case FMT_RJUST0:
+ break;
+
+ case FMT_LJUST:
+ if (IS_SIGNED(flags))
+ {
+ numwidth++;
+ }
+
+ for (i = fieldwidth - numwidth; i > 0; i--)
+ {
+ obj->put(obj, ' ');
+ }
+ break;
+ }
+}
+/************************************************************
* Public Functions
************************************************************/
@@ -296,12 +1091,12 @@ static void _llutobin(char **pp, unsigned long long n)
int lib_vsprintf(struct lib_stream_s *obj, const char *src, va_list ap)
{
char *ptmp;
- char tmp[40];
- const char *pfmt;
- unsigned int n;
- int fmt, width, trunc, tmpwidth;
- int showplus, altform, longlong;
- int hasdot, hasasteriskwidth, hasasterisktrunc;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int width;
+ int trunc;
+ ubyte fmt;
+#endif
+ ubyte flags;
for (; *src; src++)
{
@@ -310,544 +1105,353 @@ int lib_vsprintf(struct lib_stream_s *obj, const char *src, va_list ap)
if (*src != '%')
{
obj->put(obj, *src);
+ continue;
}
- else
+
+ /* We have found a format specifier. Move past it. */
+
+ src++;
+
+ /* Assume defaults */
+
+ flags = 0;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ fmt = FMT_RJUST;
+ width = 0;
+ trunc = 0;
+#endif
+
+ /* Process each format qualifier. */
+
+ for (; *src; src++)
{
- /* We have found a format specifier. Move past it. */
+ /* Break out of the loop when the format is known. */
- pfmt = src;
- src++;
+ if (strchr("diuxXpobeEfgGlLsc%", *src))
+ {
+ break;
+ }
- fmt = FMT_RJUST; /* Assume right justification. */
- width = trunc = 0;
- showplus = altform = longlong = 0;
- hasdot = hasasteriskwidth = hasasterisktrunc = 0;
+ /* Check for left justification. */
- /* Process each format qualifier. */
+ else if (*src == '-')
+ {
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ fmt = FMT_LJUST;
+#endif
+ }
+
+ /* Check for leading zero fill right justification. */
+
+ else if (*src == '0')
+ {
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ fmt = FMT_RJUST0;
+#endif
+ }
+#if 0
+ /* Center justification. */
- for (; *src; src++)
+ else if (*src == '~')
{
- /* Break out of the loop when the format is known. */
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ fmt = FMT_CENTER;
+#endif
+ }
+#endif
- if (strchr("diuxXpobeEfgGlLsc%", *src))
+ else if (*src == '*')
+ {
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int value = va_arg(ap, int);
+ if (IS_HASDOT(flags))
{
- break;
+ trunc = value;
+ SET_HASASTERISKTRUNC(flags);
}
-
- /* Check for left justification. */
-
- else if (*src == '-')
+ else
{
- fmt = FMT_LJUST;
+ width = value;
+ SET_HASASTERISKWIDTH(flags);
}
+#endif
+ }
- /* Check for leading zero fill right justification. */
+ /* Check for field width */
- else if (*src == '0')
+ else if (*src >= '1' && *src <= '9')
+ {
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ for (src++; (*src >= '0' && *src <= '9'); src++);
+#else
+ /* Accumulate the field width integer. */
+
+ int n = ((int)(*src)) - (int)'0';
+ for (src++; (*src >= '0' && *src <= '9'); src++)
{
- fmt = FMT_RJUST0;
+ n = 10*n + (((int)(*src)) - (int)'0');
}
-#if 0
- /* Center justification. */
- else if (*src == '~')
+ if (IS_HASDOT(flags))
{
- fmt = FMT_CENTER;
+ trunc = n;
}
-#endif
-
- else if (*src == '*')
+ else
{
- int value = va_arg(ap, int);
- if (hasdot)
- {
- trunc = value;
- hasasterisktrunc = 1;
- }
- else
- {
- width = value;
- hasasteriskwidth = 1;
- }
+ width = n;
}
+#endif
+ /* Back up to the last digit. */
- /* Check for field width */
+ src--;
+ }
- else if (((*src) >= '1') && ((*src) <= '9'))
- {
- /* Accumulate the field width integer. */
+ /* Check for a decimal point. */
- n = ((int)(*src)) - (int)'0';
- for (src++; (((*src) >= '0') && ((*src) <= '9')); src++)
- {
- n = 10*n + (((int)(*src)) - (int)'0');
- }
+ else if (*src == '.')
+ {
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ SET_HASDOT(flags);
+#endif
+ }
- if (hasdot) trunc = n;
- else width = n;
+ /* Check for leading plus sign. */
- /* Back up to the last digit. */
+ else if (*src == '+')
+ {
+ SET_SHOWPLUS(flags);
+ }
- src--;
- }
+ /* Check for alternate form. */
- /* Check for a decimal point. */
+ else if (*src == '#')
+ {
+ SET_ALTFORM(flags);
+ }
+ }
- else if (*src == '.')
- {
- hasdot = 1;
- }
+ /* "%%" means that a literal '%' was intended (instead of a format
+ * specification).
+ */
- /* Check for leading plus sign. */
+ if (*src == '%')
+ {
+ obj->put(obj, '%');
+ continue;
+ }
- else if (*src == '+')
- {
- showplus = 1;
- }
+ /* Check for the string format. */
- /* Check for alternate form. */
+ if (*src == 's')
+ {
+ /* Just concatenate the string into the output */
- else if (*src == '#')
- {
- altform = 1;
- }
+ ptmp = va_arg(ap, char *);
+ if (!ptmp)
+ {
+ ptmp = (char*)g_nullstring;
}
- /* "%%" means that a literal '%' was intended (instead of a format
- * specification).
- */
+ while(*ptmp)
+ {
+ obj->put(obj, *ptmp);
+ ptmp++;
+ }
+ continue;
+ }
- if (*src == '%')
+ /* Check for the character output */
+
+ else if (*src == 'c')
+ {
+ /* Just copy the character into the output. */
+
+ int n = va_arg(ap, int);
+ obj->put(obj, n);
+ continue;
+ }
+
+ /* Check for the long long prefix. */
+
+ if (*src == 'L')
+ {
+ SET_LONGLONGPRECISION(flags);
+ ++src;
+ }
+ else if (*src == 'l')
+ {
+ SET_LONGPRECISION(flags);
+ if (*++src == 'l')
{
- obj->put(obj, '%');
+ SET_LONGLONGPRECISION(flags);
+ ++src;
}
+ }
- /* Check for the string format. */
+ /* Handle integer conversions */
- else if (*src == 's')
+ if (strchr("diuxXpob", *src))
+ {
+#ifdef CONFIG_HAVE_LONG_LONG
+ if (IS_LONGLONGPRECISION(flags) && *src != 'p')
{
- /* Just concatenate the string into the output */
+ long long lln;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int lluwidth;
+#endif
+ /* Extract the long long value. */
- ptmp = va_arg(ap, char *);
- if (!ptmp) ptmp = (char*)g_nullstring;
+ lln = va_arg(ap, long long);
- while(*ptmp)
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ /* Output the number */
+
+ llutoascii(obj, *src, flags, (unsigned long long)lln);
+#else
+ /* Resolve sign-ness and format issues */
+
+ llfixup(*src, &flags, &lln);
+
+ /* Get the width of the output */
+
+ lluwidth = getllusize(*src, flags, lln);
+
+ /* Perform left field justification actions */
+
+ prejustify(obj, fmt, flags, width, lluwidth);
+
+ /* Output the number */
+
+ llutoascii(obj, *src, flags, (unsigned long long)lln);
+
+ /* Perform right field justification actions */
+
+ postjustify(obj, fmt, flags, width, lluwidth);
+#endif
}
+ else
+#endif /* CONFIG_HAVE_LONG_LONG */
+#ifdef CONFIG_LONG_IS_NOT_INT
+ if (IS_LONGPRECISION(flags) && *src != 'p')
+ {
+ long ln;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int luwidth;
+#endif
+ /* Extract the long long value. */
+
+ ln = va_arg(ap, long);
+
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ /* Output the number */
+
+ lutoascii(obj, *src, flags, (unsigned long)ln);
+#else
+ /* Resolve sign-ness and format issues */
+
+ lfixup(*src, &flags, &ln);
+
+ /* Get the width of the output */
+
+ luwidth = getlusize(*src, flags, ln);
+
+ /* Perform left field justification actions */
- /* Check for the character output */
+ prejustify(obj, fmt, flags, width, luwidth);
- else if (*src == 'c')
+ /* Output the number */
+
+ lutoascii(obj, *src, flags, (unsigned long)ln);
+
+ /* Perform right field justification actions */
+
+ postjustify(obj, fmt, flags, width, luwidth);
+#endif
+ }
+ else
+#endif /* CONFIG_LONG_IS_NOT_INT */
+#ifdef CONFIG_PTR_IS_NOT_INT
+ if (*src == 'p')
{
- /* Just copy the character into the output. */
+ void *p;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int pwidth;
+#endif
+ /* Extract the long long value. */
- n = va_arg(ap, int);
- obj->put(obj, n);
+ p = va_arg(ap, void *);
+
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ /* Output the pointer value */
+
+ ptohex(obj, flags, p);
+#else
+ /* Resolve sign-ness and format issues */
+
+ lfixup(*src, &flags, &ln);
+
+ /* Get the width of the output */
+
+ luwidth = getpsize(*src, flags, p);
+
+ /* Perform left field justification actions */
+
+ prejustify(obj, fmt, flags, width, pwidth);
+
+ /* Output the pointer value */
+
+ ptohex(obj, flags, p);
+
+ /* Perform right field justification actions */
+
+ postjustify(obj, fmt, flags, width, pwidth);
+#endif
}
else
+#endif
{
- /* Check for the long long prefix. */
+ int n;
+#ifndef CONFIG_NOPRINTF_FIELDWIDTH
+ int uwidth;
+#endif
+ /* Extract the long long value. */
- if (*src == 'L')
- {
- longlong = 1;
- ++src;
- }
- else if (*src == 'l')
- {
- if (*++src == 'l')
- {
- longlong = 1;
- ++src;
- }
- }
+ n = va_arg(ap, int);
- /* Get the ascii format into the tmp[] buffer. */
+#ifdef CONFIG_NOPRINTF_FIELDWIDTH
+ /* Output the number */
- ptmp = tmp;
+ utoascii(obj, *src, flags, (unsigned int)n);
+#else
+ /* Resolve sign-ness and format issues */
- /* Handle integer conversions */
+ fixup(*src, &flags, &n);
- if (strchr("diuxXpob", *src))
- {
-#ifdef CONFIG_HAVE_LONG_LONG
- if ((longlong) && (*src != 'p'))
- {
- /* Extract the long long value. */
-
- long long lln = va_arg(ap, long long);
-
- /* Perform the integer conversion according to the
- * format specifier
- */
-
- switch (*src)
- {
- case 'd':
- case 'i':
- /* Signed base 10 */
- {
- /* Check for leading +/- */
-
- if (lln < 0)
- {
- *ptmp++ = '-';
- *ptmp = 0;
- lln = -lln;
- }
- else if (showplus)
- {
- *ptmp++ = '+';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- llutodec(&ptmp, (unsigned long long)lln);
- }
- break;
-
- case 'u':
- /* Unigned base 10 */
- {
- /* Check for leading + */
-
- if (showplus)
- {
- *ptmp++ = '+';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- llutodec(&ptmp, (unsigned long long)lln);
- }
- break;
-
- case 'p':
- case 'x':
- case 'X':
- /* Hexadecimal */
- {
- /* Check for alternate form */
-
- if (altform)
- {
- /* Prefix the number with "0x" */
-
- *ptmp++ = '0';
- *ptmp++ = 'x';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- llutohex(&ptmp, (unsigned long long)lln);
-
- /* Check for upper case conversion. */
-
- if ((*src) == 'X')
- {
- for (ptmp = tmp; *ptmp; ptmp++)
- {
- if (((*ptmp) >= 'a') && ((*ptmp) <= 'z'))
- {
- /* Convert to upper case. */
-
- *ptmp += (char)((int)'A' - (int)'a');
- }
- }
- }
- }
- break;
-
- case 'o':
- /* Octal */
- {
- /* Check for alternate form */
-
- if (altform)
- {
- /* Prefix the number with '0' */
-
- *ptmp++ = '0';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- llutooct(&ptmp, (unsigned long long)lln);
- }
- break;
-
- case 'b':
- /* Binary */
- {
- /* Convert the unsigned value to a string. */
-
- llutobin(&ptmp, (unsigned long long)lln);
- }
- break;
-
- default:
- break;
- }
- }
- else
- {
-#endif /* CONFIG_HAVE_LONG_LONG */
- /* Extract the integer value */
-
- n = va_arg(ap, int);
-
- /* Perform the integer conversion according to the
- * format specifier
- */
-
- switch (*src)
- {
- case 'd':
- case 'i':
- /* Signed base 10 */
- {
- /* Check for leading +/- */
-
- if ((int)n < 0)
- {
- *ptmp++ = '-';
- *ptmp = 0;
- n = -n;
- }
- else if (showplus)
- {
- *ptmp++ = '+';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- utodec(&ptmp, (unsigned int)n);
- }
- break;
-
- case 'u':
- /* Unigned base 10 */
- {
- /* Check for leading + */
-
- if (showplus)
- {
- *ptmp++ = '+';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- utodec(&ptmp, (unsigned int)n);
- }
- break;
-
- case 'x':
- case 'X':
- case 'p':
- /* Hexadecimal */
- {
- /* Check for alternate form */
-
- if (altform)
- {
- /* Prefix the number with "0x" */
-
- *ptmp++ = '0';
- *ptmp++ = 'x';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- utohex(&ptmp, (unsigned int)n);
-
- /* Check for upper case conversion. */
-
- if ((*src) == 'X')
- {
- for (ptmp = tmp; *ptmp; ptmp++)
- {
- if (((*ptmp) >= 'a') && ((*ptmp) <= 'z'))
- {
- /* Convert to upper case. */
-
- *ptmp += (char)((int)'A' - (int)'a');
- }
- }
- }
- else if ((*src) == 'p')
- {
- if ((!width) && (fmt == FMT_RJUST))
- {
- if (altform) width = 10;
- else width = 8;
-
- fmt = FMT_RJUST0;
- }
- }
- }
- break;
-
- case 'o':
- /* Octal */
- {
- /* Check for alternate form */
-
- if (altform)
- {
- /* Prefix the number with '0' */
-
- *ptmp++ = '0';
- *ptmp = 0;
- }
-
- /* Convert the unsigned value to a string. */
-
- utooct(&ptmp, (unsigned int)n);
- }
- break;
-
- case 'b':
- /* Binary */
- {
- /* Convert the unsigned value to a string. */
-
- utobin(&ptmp, (unsigned int)n);
- }
- break;
-
- default:
- break;
- }
-#ifdef CONFIG_HAVE_LONG_LONG
- }
-#endif /* CONFIG_HAVE_LONG_LONG */
+ /* Get the width of the output */
- /* Now, get the "real" field width of the integer value*/
-
- tmpwidth = strlen(tmp);
- if (width <= tmpwidth)
- {
- /* Just copy the string. */
-
- for (ptmp = tmp; *ptmp; )
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
- }
- else
- {
- /* Apply field justification to the integer value. */
-
- switch (fmt)
- {
- default:
- case FMT_RJUST:
- for (n = width - tmpwidth; n; n--)
- {
- obj->put(obj, ' ');
- }
-
- for (ptmp = tmp; *ptmp; )
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
- break;
-
- case FMT_RJUST0:
- ptmp = tmp;
- if (((*ptmp) == '-') || ((*ptmp) == '+'))
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
-
- for (n = width - tmpwidth; n; n--)
- {
- obj->put(obj, '0');
- }
-
- while (*ptmp)
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
- break;
-
- case FMT_LJUST:
- for (ptmp = tmp; *ptmp; )
- {
- obj->put(obj, *ptmp);
- ptmp++;
- }
-
- for (n = width - tmpwidth; n; n--)
- {
- obj->put(obj, ' ');
- }
- break;
- }
- }
- }
-
- /* Handle floating point conversions */
-
- else if (strchr("eEfgG", *src))
- {
- char tmpfmt[40];
- const char *psrc;
- char *pdst;
- double_t dbl;
-
- /* Reconstruct the floating point format. */
-
- psrc = pfmt;
- pdst = tmpfmt;
- while (psrc <= src) *pdst++ = *psrc++;
- *pdst = 0;
-
- /* Extract the floating point number. */
-
- dbl = va_arg(ap, double_t);
-
- /* Then let the lib_sprintf do the work. */
-
- if (hasasteriskwidth)
- {
- if (hasasterisktrunc)
- {
- lib_sprintf(obj, tmpfmt, width, trunc, dbl);
- }
- else
- {
- lib_sprintf(obj, tmpfmt, width, dbl);
- }
- }
- else
- {
- if (hasasterisktrunc)
- {
- lib_sprintf(obj, tmpfmt, trunc, dbl);
- }
- else
- {
- lib_sprintf(obj, tmpfmt, dbl);
- }
- }
- }
+ uwidth = getusize(*src, flags, n);
+
+ /* Perform left field justification actions */
+
+ prejustify(obj, fmt, flags, width, uwidth);
+
+ /* Output the number */
+
+ utoascii(obj, *src, flags, (unsigned int)n);
+
+ /* Perform right field justification actions */
+
+ postjustify(obj, fmt, flags, width, uwidth);
+#endif
}
}
+
+ /* Handle floating point conversions */
+
+ else if (strchr("eEfgG", *src))
+ {
+#warning "No floating point support"
+ }
}
return obj->nput;
diff --git a/nuttx/lib/lib_nullstream.c b/nuttx/lib/lib_nullstream.c
new file mode 100644
index 000000000..f4c1ceb88
--- /dev/null
+++ b/nuttx/lib/lib_nullstream.c
@@ -0,0 +1,62 @@
+/************************************************************
+ * lib_nullstream.c
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name Gregory Nutt nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************/
+
+/************************************************************
+ * Included Files
+ ************************************************************/
+
+#include <stdio.h>
+#include <errno.h>
+#include "lib_internal.h"
+
+/************************************************************
+ * Private Functions
+ ************************************************************/
+
+static void nullstream_putc(struct lib_stream_s *this, int ch)
+{
+ this->nput++;
+}
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+void lib_nullstream(struct lib_stream_s *nullstream)
+{
+ nullstream->put = nullstream_putc;
+ nullstream->nput = 0;
+}
+