diff options
-rw-r--r-- | nuttx/arch/README.txt | 6 | ||||
-rw-r--r-- | nuttx/arch/c5471/defconfig | 8 | ||||
-rw-r--r-- | nuttx/arch/pjrc-8051/defconfig | 8 | ||||
-rw-r--r-- | nuttx/arch/pjrc-8051/src/up_allocateheap.c | 2 | ||||
-rw-r--r-- | nuttx/arch/pjrc-8051/src/up_irq.c | 4 | ||||
-rw-r--r-- | nuttx/arch/sim/defconfig | 8 | ||||
-rw-r--r-- | nuttx/include/nuttx/compiler.h | 18 | ||||
-rw-r--r-- | nuttx/lib/Makefile | 3 | ||||
-rw-r--r-- | nuttx/lib/lib_internal.h | 4 | ||||
-rw-r--r-- | nuttx/lib/lib_libvsprintf.c | 1768 | ||||
-rw-r--r-- | nuttx/lib/lib_nullstream.c | 62 |
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; +} + |