diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-01 19:08:04 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-01 19:08:04 +0000 |
commit | 00b2545e9e3cc760255aa7b4fc953ad5ab97ba62 (patch) | |
tree | 90f908d15691555fdf19c21eeae7b55187b73803 /nuttx | |
parent | 6e09d7aab47a47e36f56d9b33bd6e87e96e2af2c (diff) | |
download | px4-nuttx-00b2545e9e3cc760255aa7b4fc953ad5ab97ba62.tar.gz px4-nuttx-00b2545e9e3cc760255aa7b4fc953ad5ab97ba62.tar.bz2 px4-nuttx-00b2545e9e3cc760255aa7b4fc953ad5ab97ba62.zip |
Add support for accessing printf, sprintf, puts, etc. strings that do not lie in the MCU data space
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3738 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 8 | ||||
-rw-r--r-- | nuttx/Documentation/NuttxPortingGuide.html | 57 | ||||
-rw-r--r-- | nuttx/arch/avr/include/avr/types.h | 7 | ||||
-rw-r--r-- | nuttx/arch/avr/src/at90usb/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/arch/avr/src/atmega/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/arch/sim/src/Makefile | 6 | ||||
-rw-r--r-- | nuttx/configs/README.txt | 34 | ||||
-rw-r--r-- | nuttx/include/nuttx/arch.h | 39 | ||||
-rw-r--r-- | nuttx/include/nuttx/compiler.h | 21 | ||||
-rwxr-xr-x | nuttx/include/stdint.h | 9 | ||||
-rw-r--r-- | nuttx/lib/lib_internal.h | 2 | ||||
-rw-r--r-- | nuttx/lib/stdio/lib_fputs.c | 53 | ||||
-rw-r--r-- | nuttx/lib/stdio/lib_libvsprintf.c | 145 |
13 files changed, 316 insertions, 73 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 51b317e0a..7e210c8d7 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1839,5 +1839,13 @@ and was, therefore, off by one, and (2) Some devices stall of get Max LUN request if they support only a single LUN. Logic now assumes a single LUN if the get Max LUN request fails. + * include/nuttx/arch.h, lib/stdio/lib_libvsprintf.c, lib/stdio/lib_fputs.c: Add + a new configuration option to support extracting strings from FLASH or EEPROM + or other memories where the string data cannot be accessed by simply de-referencing + a string pointer. + * arch/sim/src/up_romgetc.c: Used to test the basic logic to access strings + without directly de-referencing a string pointer. + * arch/avr/src/avr/up_romget.c: Used to access strings that lie in the first + 64Kb of FLASH. diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index e4bcc5d64..f0bc05161 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@ <h1><big><font color="#3c34ec"> <i>NuttX RTOS Porting Guide</i> </font></big></h1> - <p>Last Updated: June 18, 2011</p> + <p>Last Updated: July 1, 2011</p> </td> </tr> </table> @@ -3628,34 +3628,65 @@ build <ul> <li> - <code>CONFIG_NOPRINTF_FIELDWIDTH</code>: sprintf-related logic is a + <code>CONFIG_NOPRINTF_FIELDWIDTH</code>: <code>sprintf</code>-related logic is a little smaller if we do not support fieldwidthes </li> <li> <code>CONFIG_LIBC_FLOATINGPOINT</code>: By default, floating point - support in printf, sscanf, etc. is disabled. + support in <code>printf</code>, <code>sscanf</code>, etc. is disabled. </li> </ul> <h2>Allow for architecture optimized implementations</h2> -<p> - The architecture can provide optimized versions of the following to improve system performance. -</p> - <ul> -<p> +<li> + The architecture can provide optimized versions of the following to improve system performance. +</li> +<ul><p> <code>CONFIG_ARCH_MEMCPY</code>, <code>CONFIG_ARCH_MEMCMP</code>, <code>CONFIG_ARCH_MEMMOVE</code>, <code>CONFIG_ARCH_MEMSET</code>, <code>CONFIG_ARCH_STRCMP</code>, <code>CONFIG_ARCH_STRCPY</code>, <code>CONFIG_ARCH_STRNCPY</code>, <code>CONFIG_ARCH_STRLEN</code>, <code>CONFIG_ARCH_STRNLEN</code>, <code>CONFIG_ARCH_BZERO</code> -</p> -<p> +</p></ul> + +<li> The architecture may provide custom versions of certain standard header files: -</p> -<p> +</li> +<ul><p> <code>CONFIG_ARCH_MATH_H</code>, <code>CONFIG_ARCH_STDBOOL_H</code>, <code>CONFIG_ARCH_STDINT_H</code> -</p> +</p></ul> + +<li> + <p><code>CONFIG_ARCH_ROMGETC</code>: + There are cases where string data cannot be cannot be accessed by simply de-referencing a string pointer. + As examples: + </p> + <ul> + <li> + In Harvard architectures, data accesses and instruction accesses occur on different busses, perhaps concurrently. + All data accesses are performed on the data bus unless special machine instructions are used to read data from the instruction address space. + Also, in the typical MCU, the available SRAM data memory is much smaller that the non-volatile FLASH instruction memory. + So if the application requires many constant strings, the only practical solution may be to store those constant strings in FLASH memory where they can only be accessed using architecture-specific machine instructions. + </li> + <li> + A similar case is where strings are retained in "external" memory such as EEPROM or serial FLASH. + This case is similar only in that again special operations are required to obtain the string data; + it cannot be accessed directly from a string pointer. + </li> + </ul> + <p> + If <code>CONFIG_ARCH_ROMGETC</code> is defined, then the architecture-specific logic must export the function <code>up_romgetc()</code>. + <code>up_romgetc()</code> will simply read one byte of data from the instruction space. + </p> + <p> + If <code>CONFIG_ARCH_ROMGETC</code>, certain C stdio functions are effected: + (1) All format strings in <code>printf</code>, <code>fprintf</code>, <code>sprintf</code>, etc. are assumed to lie in FLASH + (string arguments for <code>%s</code> are still assumed to reside in SRAM). + And (2), the string argument to <code>puts</code> and <code>fputs</code> is assumed to reside in FLASH. + Clearly, these assumptions may have to modified for the particular needs of your environment. + There is no "one-size-fits-all" solution for this problem. + </p> </ul> <h2>Sizes of configurable things (0 disables)</h2> diff --git a/nuttx/arch/avr/include/avr/types.h b/nuttx/arch/avr/include/avr/types.h index 2dd35a5cb..e0a70fb7f 100644 --- a/nuttx/arch/avr/include/avr/types.h +++ b/nuttx/arch/avr/include/avr/types.h @@ -76,11 +76,16 @@ typedef signed long long _int64_t; /* long long is 64-bits */ typedef unsigned long long _uint64_t; #define __INT64_DEFINED -/* A pointer is 2 bytes */ +/* A (near) pointer is 2 bytes */ typedef signed int _intptr_t; typedef unsigned int _uintptr_t; +/* A FAR pointer is 4 bytes */ + +typedef signed long _int_farptr_t; +typedef unsigned long _uint_farptr_t; + /* This is the size of the interrupt state save returned by irqsave(). */ typedef unsigned char irqstate_t; diff --git a/nuttx/arch/avr/src/at90usb/Make.defs b/nuttx/arch/avr/src/at90usb/Make.defs index 5b939f5af..0497acd95 100644 --- a/nuttx/arch/avr/src/at90usb/Make.defs +++ b/nuttx/arch/avr/src/at90usb/Make.defs @@ -62,6 +62,10 @@ ifeq ($(CONFIG_DEBUG_STACK),y) CMN_CSRCS += up_checkstack.c endif +ifeq ($(CONFIG_ARCH_ROMGETC),y) +CMN_CSRCS += up_romgetc.c +endif + # Required AT90USB files CHIP_ASRCS = at90usb_exceptions.S diff --git a/nuttx/arch/avr/src/atmega/Make.defs b/nuttx/arch/avr/src/atmega/Make.defs index 47683fcd0..b3451aaa1 100644 --- a/nuttx/arch/avr/src/atmega/Make.defs +++ b/nuttx/arch/avr/src/atmega/Make.defs @@ -62,6 +62,10 @@ ifeq ($(CONFIG_DEBUG_STACK),y) CMN_CSRCS += up_checkstack.c endif +ifeq ($(CONFIG_ARCH_ROMGETC),y) +CMN_CSRCS += up_romgetc.c +endif + # Required ATMEGA files CHIP_ASRCS = atmega_exceptions.S diff --git a/nuttx/arch/sim/src/Makefile b/nuttx/arch/sim/src/Makefile index 8e2fc56de..f32f17b01 100644 --- a/nuttx/arch/sim/src/Makefile +++ b/nuttx/arch/sim/src/Makefile @@ -64,9 +64,15 @@ HOSTSRCS = up_stdio.c up_hostusleep.c ifeq ($(USEX),y) HOSTSRCS += up_x11framebuffer.c endif + ifeq ($(CONFIG_FS_FAT),y) CSRCS += up_blockdevice.c up_deviceimage.c endif + +ifeq ($(CONFIG_ARCH_ROMGETC),y) +CSRCS += up_romgetc.c +endif + ifeq ($(CONFIG_NET),y) CSRCS += up_uipdriver.c HOSTCFLAGS += -DNETDEV_BUFSIZE=$(CONFIG_NET_BUFSIZE) diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index 6c3a0b74a..21426362f 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -489,15 +489,39 @@ defconfig -- This is a configuration file similar to the Linux The architecture can provide optimized versions of the following to improve system performance - CONFIG_ARCH_MEMCPY, CONFIG_ARCH_MEMCMP, CONFIG_ARCH_MEMMOVE - CONFIG_ARCH_MEMSET, CONFIG_ARCH_STRCMP, CONFIG_ARCH_STRCPY - CONFIG_ARCH_STRNCPY, CONFIG_ARCH_STRLEN, CONFIG_ARCH_STRNLEN - CONFIG_ARCH_BZERO + CONFIG_ARCH_MEMCPY, CONFIG_ARCH_MEMCMP, CONFIG_ARCH_MEMMOVE + CONFIG_ARCH_MEMSET, CONFIG_ARCH_STRCMP, CONFIG_ARCH_STRCPY + CONFIG_ARCH_STRNCPY, CONFIG_ARCH_STRLEN, CONFIG_ARCH_STRNLEN + CONFIG_ARCH_BZERO The architecture may provide custom versions of certain standard header files: - CONFIG_ARCH_MATH_H, CONFIG_ARCH_STDBOOL_H, CONFIG_ARCH_STDINT_H + CONFIG_ARCH_MATH_H, CONFIG_ARCH_STDBOOL_H, CONFIG_ARCH_STDINT_H + + CONFIG_ARCH_ROMGETC - In Harvard architectures, data accesses and + instruction accesses occur on different busses, perhaps + concurrently. All data accesses are performed on the data bus + unless special machine instructions are used to read data + from the instruction address space. Also, in the typical + MCU, the available SRAM data memory is much smaller that the + non-volatile FLASH instruction memory. So if the application + requires many constant strings, the only practical solution may + be to store those constant strings in FLASH memory where they + can only be accessed using architecture-specific machine + instructions. + + If CONFIG_ARCH_ROMGETC is defined, then the architecture logic + must export the function up_romgetc(). up_romgetc() will simply + read one byte of data from the instruction space. + + If CONFIG_ARCH_ROMGETC, certain C stdio functions are effected: + (1) All format strings in printf, fprintf, sprintf, etc. are + assumed to lie in FLASH (string arguments for %s are still assumed + to reside in SRAM). And (2), the string argument to puts and fputs + is assumed to reside in FLASH. Clearly, these assumptions may have + to modified for the particular needs of your environment. There + is no "one-size-fits-all" solution for this problem. Sizes of configurable things (0 disables) diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h index df9f1e9ab..448af1105 100644 --- a/nuttx/include/nuttx/arch.h +++ b/nuttx/include/nuttx/arch.h @@ -450,6 +450,45 @@ EXTERN int up_prioritize_irq(int irq, int priority); #endif /**************************************************************************** + * Name: up_romgetc + * + * Description: + * In Harvard architectures, data accesses and instruction accesses occur + * on different busses, perhaps concurrently. All data accesses are + * performed on the data bus unless special machine instructions are + * used to read data from the instruction address space. Also, in the + * typical MCU, the available SRAM data memory is much smaller that the + * non-volatile FLASH instruction memory. So if the application requires + * many constant strings, the only practical solution may be to store + * those constant strings in FLASH memory where they can only be accessed + * using architecture-specific machine instructions. + * + * A similar case is where strings are retained in "external" memory such + * as EEPROM or serial FLASH. This case is similar only in that again + * special operations are required to obtain the string data; it cannot + * be accessed directly from a string pointer. + * + * If CONFIG_ARCH_ROMGETC is defined, then the architecture logic must + * export the function up_romgetc(). up_romgetc() will simply read one + * byte of data from the instruction space. + * + * If CONFIG_ARCH_ROMGETC, certain C stdio functions are effected: (1) + * All format strings in printf, fprintf, sprintf, etc. are assumed to + * lie in FLASH (string arguments for %s are still assumed to reside in + * SRAM). And (2), the string argument to puts and fputs is assumed to + * reside in FLASH. Clearly, these assumptions may have to modified for + * the particular needs of your environment. There is no "one-size-fits-all" + * solution for this problem. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_ROMGETC +EXTERN char up_romgetc(FAR const char *ptr); +#else +# define up_romgetc(ptr) (*ptr) +#endif + +/**************************************************************************** * Name: up_mdelay and up_udelay * * Description: diff --git a/nuttx/include/nuttx/compiler.h b/nuttx/include/nuttx/compiler.h index c44ff329e..c672054dd 100644 --- a/nuttx/include/nuttx/compiler.h +++ b/nuttx/include/nuttx/compiler.h @@ -103,7 +103,7 @@ * pointers are 16-bits. */ -#if defined(__m32c__) || defined(__AVR__) +#if defined(__m32c__) /* Select the small, 16-bit addressing model */ # define CONFIG_SMALL_MEMORY 1 @@ -116,7 +116,24 @@ # undef CONFIG_PTR_IS_NOT_INT -/* Handle cases where sizeof(int) may or may not be 16-bits */ +#elif defined(__AVR__) +/* Select the small, 16-bit addressing model */ + +# define CONFIG_SMALL_MEMORY 1 + +/* Long and int are not the same size */ + +# define CONFIG_LONG_IS_NOT_INT 1 + +/* Pointers and int are the same size */ + +# undef CONFIG_PTR_IS_NOT_INT + +/* Uses a 32-bit FAR pointer only from accessing data outside of the 16-bit + * data space. + */ + +# define CONFIG_HAVE_FARPOINTER 1 #elif defined(__mc68hc1x__) /* Select the small, 16-bit addressing model */ diff --git a/nuttx/include/stdint.h b/nuttx/include/stdint.h index f6d2fcfcd..26bcce4db 100755 --- a/nuttx/include/stdint.h +++ b/nuttx/include/stdint.h @@ -282,6 +282,15 @@ typedef _uint64_t uint_fast64_t; typedef _intptr_t intptr_t; typedef _uintptr_t uintptr_t; +/* Some architectures support a FAR pointer which is larger then the normal + * (near) pointer + */ + +#ifdef CONFIG_HAVE_FARPOINTER +typedef _int_farptr_t int_farptr_t; +typedef _uint_farptr_t uint_farptr_t; +#endif + /* Greatest-width integer types */ #ifdef __INT64_DEFINED diff --git a/nuttx/lib/lib_internal.h b/nuttx/lib/lib_internal.h index 6c9b9c14c..d960d6cf3 100644 --- a/nuttx/lib/lib_internal.h +++ b/nuttx/lib/lib_internal.h @@ -124,7 +124,7 @@ extern int lib_sprintf(FAR struct lib_outstream_s *obj, /* Defined lib_libvsprintf.c */ extern int lib_vsprintf(FAR struct lib_outstream_s *obj, - const char *src, va_list ap); + FAR const char *src, va_list ap); /* Defined lib_rawprintf.c */ diff --git a/nuttx/lib/stdio/lib_fputs.c b/nuttx/lib/stdio/lib_fputs.c index a2b132f2f..34d12c15e 100644 --- a/nuttx/lib/stdio/lib_fputs.c +++ b/nuttx/lib/stdio/lib_fputs.c @@ -41,9 +41,14 @@ * Included Files ****************************************************************************/ +#include <nuttx/config.h> + #include <stdio.h> #include <string.h> #include <errno.h> + +#include <nuttx/arch.h> + #include "lib_internal.h" /**************************************************************************** @@ -90,7 +95,53 @@ * ****************************************************************************/ +#if defined(CONFIG_ARCH_ROMGETC) +int fputs(FAR const char *s, FAR FILE *stream) +{ + int nput; + int ret; + char ch; + + /* Make sure that a string was provided. */ + +#ifdef CONFIG_DEBUG /* Most parameter checking is disabled if DEBUG is off */ + if (!s) + { + set_errno(EINVAL); + return EOF; + } +#endif + + /* Write the string. Loop until the null terminator is encountered */ + + for (nput = 0, ch = up_romgetc(s); ch; nput++, s++, ch = up_romgetc(s)) + { + /* Write the next character to the stream buffer */ + + ret = lib_fwrite(&ch, 1, stream); + if (ret <= 0) + { + return EOF; + } + + /* Flush the buffer if a newline was written to the buffer */ + #ifdef CONFIG_STDIO_LINEBUFFER + if (ch == '\n') + { + ret = lib_fflush(stream, true); + if (ret < 0) + { + return EOF; + } + } +#endif + } + + return nput; +} + +#elif defined(CONFIG_STDIO_LINEBUFFER) int fputs(FAR const char *s, FAR FILE *stream) { int nput; @@ -118,7 +169,7 @@ int fputs(FAR const char *s, FAR FILE *stream) return EOF; } - /* Flush the buffer if a newline was writen to the buffer */ + /* Flush the buffer if a newline was written to the buffer */ if (*s == '\n') { diff --git a/nuttx/lib/stdio/lib_libvsprintf.c b/nuttx/lib/stdio/lib_libvsprintf.c index 34a27ea4e..3bc112e92 100644 --- a/nuttx/lib/stdio/lib_libvsprintf.c +++ b/nuttx/lib/stdio/lib_libvsprintf.c @@ -44,6 +44,8 @@ #include <stdio.h> #include <string.h> +#include <nuttx/arch.h> + #include "lib_internal.h" /**************************************************************************** @@ -96,6 +98,33 @@ enum #define IS_NEGATE(f) (((f) & FLAG_NEGATE) != 0) #define IS_SIGNED(f) (((f) & (FLAG_SHOWPLUS|FLAG_NEGATE)) != 0) +/* If CONFIG_ARCH_ROMGETC is defined, then it is assumed that the format + * string data cannot be accessed by simply de-referencing the format string + * pointer. This might be in the case in Harvard architectures where string + * data might be stored in instruction space or if string data were stored + * on some media like EEPROM or external serial FLASH. In all of these cases, + * string data has to be accessed indirectly using the architecture-supplied + * up_romgetc(). The following mechanisms attempt to make these different + * access methods indistinguishable in the following code. + * + * NOTE: It is assumed that string arguments for %s still reside in memory + * that can be directly accessed by de-referencing the string pointer. + */ + +#ifdef CONFIG_ARCH_ROMGETC +# define FMT_TOP ch = up_romgetc(src) /* Loop initialization */ +# define FMT_BOTTOM src++, ch = up_romgetc(src) /* Bottom of a loop */ +# define FMT_CHAR ch /* Access a character */ +# define FMT_NEXT src++; ch = up_romgetc(src) /* Advance to the next character */ +# define FMT_PREV src--; ch = up_romgetc(src) /* Backup to the previous character */ +#else +# define FMT_TOP /* Loop initialization */ +# define FMT_BOTTOM src++ /* Bottom of a loop */ +# define FMT_CHAR *src /* Access a character */ +# define FMT_NEXT src++ /* Advance to the next character */ +# define FMT_PREV src-- /* Backup to the previous character */ +#endif + /**************************************************************************** * Private Type Declarations ****************************************************************************/ @@ -1111,30 +1140,33 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, * lib/stdio/lib_vsprintf ****************************************************************************/ -int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) +int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list ap) { - char *ptmp; + FAR char *ptmp; #ifndef CONFIG_NOPRINTF_FIELDWIDTH int width; int trunc; uint8_t fmt; #endif uint8_t flags; +#ifdef CONFIG_ARCH_ROMGETC + char ch; +#endif - for (; *src; src++) + for (FMT_TOP; FMT_CHAR; FMT_BOTTOM) { /* Just copy regular characters */ - if (*src != '%') + if (FMT_CHAR != '%') { /* Output the character */ - obj->put(obj, *src); + obj->put(obj, FMT_CHAR); /* Flush the buffer if a newline is encountered */ #ifdef CONFIG_STDIO_LINEBUFFER - if (*src == '\n') + if (FMT_CHAR == '\n') { /* Should return an error on a failure to flush */ @@ -1148,7 +1180,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* We have found a format specifier. Move past it. */ - src++; + FMT_NEXT; /* Assume defaults */ @@ -1161,18 +1193,18 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Process each format qualifier. */ - for (; *src; src++) + for (; FMT_CHAR; FMT_BOTTOM) { /* Break out of the loop when the format is known. */ - if (strchr("diuxXpobeEfgGlLsc%", *src)) + if (strchr("diuxXpobeEfgGlLsc%", FMT_CHAR)) { break; } /* Check for left justification. */ - else if (*src == '-') + else if (FMT_CHAR == '-') { #ifndef CONFIG_NOPRINTF_FIELDWIDTH fmt = FMT_LJUST; @@ -1181,7 +1213,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for leading zero fill right justification. */ - else if (*src == '0') + else if (FMT_CHAR == '0') { #ifndef CONFIG_NOPRINTF_FIELDWIDTH fmt = FMT_RJUST0; @@ -1190,7 +1222,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #if 0 /* Center justification. */ - else if (*src == '~') + else if (FMT_CHAR == '~') { #ifndef CONFIG_NOPRINTF_FIELDWIDTH fmt = FMT_CENTER; @@ -1198,7 +1230,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) } #endif - else if (*src == '*') + else if (FMT_CHAR == '*') { #ifndef CONFIG_NOPRINTF_FIELDWIDTH int value = va_arg(ap, int); @@ -1217,17 +1249,29 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for field width */ - else if (*src >= '1' && *src <= '9') + else if (FMT_CHAR >= '1' && FMT_CHAR <= '9') { #ifdef CONFIG_NOPRINTF_FIELDWIDTH - for (src++; (*src >= '0' && *src <= '9'); src++); + do + { + FMT_NEXT; + } + while (FMT_CHAR >= '0' && FMT_CHAR <= '9'); #else /* Accumulate the field width integer. */ - int n = ((int)(*src)) - (int)'0'; - for (src++; (*src >= '0' && *src <= '9'); src++) + int n = ((int)(FMT_CHAR)) - (int)'0'; + for (;;) { - n = 10*n + (((int)(*src)) - (int)'0'); + FMT_NEXT; + if (FMT_CHAR >= '0' && FMT_CHAR <= '9') + { + n = 10*n + (((int)(FMT_CHAR)) - (int)'0'); + } + else + { + break; + } } if (IS_HASDOT(flags)) @@ -1241,12 +1285,12 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #endif /* Back up to the last digit. */ - src--; + FMT_PREV; } /* Check for a decimal point. */ - else if (*src == '.') + else if (FMT_CHAR == '.') { #ifndef CONFIG_NOPRINTF_FIELDWIDTH SET_HASDOT(flags); @@ -1255,14 +1299,14 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for leading plus sign. */ - else if (*src == '+') + else if (FMT_CHAR == '+') { SET_SHOWPLUS(flags); } /* Check for alternate form. */ - else if (*src == '#') + else if (FMT_CHAR == '#') { SET_ALTFORM(flags); } @@ -1272,7 +1316,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) * specification). */ - if (*src == '%') + if (FMT_CHAR == '%') { obj->put(obj, '%'); continue; @@ -1280,7 +1324,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for the string format. */ - if (*src == 's') + if (FMT_CHAR == 's') { /* Just concatenate the string into the output */ @@ -1300,7 +1344,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for the character output */ - else if (*src == 'c') + else if (FMT_CHAR == 'c') { /* Just copy the character into the output. */ @@ -1311,27 +1355,28 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Check for the long long prefix. */ - if (*src == 'L') + if (FMT_CHAR == 'L') { SET_LONGLONGPRECISION(flags); - ++src; + FMT_NEXT; } - else if (*src == 'l') + else if (FMT_CHAR == 'l') { SET_LONGPRECISION(flags); - if (*++src == 'l') + FMT_NEXT; + if (FMT_CHAR == 'l') { SET_LONGLONGPRECISION(flags); - ++src; + FMT_NEXT; } } /* Handle integer conversions */ - if (strchr("diuxXpob", *src)) + if (strchr("diuxXpob", FMT_CHAR)) { #ifdef CONFIG_HAVE_LONG_LONG - if (IS_LONGLONGPRECISION(flags) && *src != 'p') + if (IS_LONGLONGPRECISION(flags) && FMT_CHAR != 'p') { long long lln; #ifndef CONFIG_NOPRINTF_FIELDWIDTH @@ -1344,15 +1389,15 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #ifdef CONFIG_NOPRINTF_FIELDWIDTH /* Output the number */ - llutoascii(obj, *src, flags, (unsigned long long)lln); + llutoascii(obj, FMT_CHAR, flags, (unsigned long long)lln); #else /* Resolve sign-ness and format issues */ - llfixup(*src, &flags, &lln); + llfixup(FMT_CHAR, &flags, &lln); /* Get the width of the output */ - lluwidth = getllusize(*src, flags, lln); + lluwidth = getllusize(FMT_CHAR, flags, lln); /* Perform left field justification actions */ @@ -1360,7 +1405,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Output the number */ - llutoascii(obj, *src, flags, (unsigned long long)lln); + llutoascii(obj, FMT_CHAR, flags, (unsigned long long)lln); /* Perform right field justification actions */ @@ -1370,7 +1415,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) else #endif /* CONFIG_HAVE_LONG_LONG */ #ifdef CONFIG_LONG_IS_NOT_INT - if (IS_LONGPRECISION(flags) && *src != 'p') + if (IS_LONGPRECISION(flags) && FMT_CHAR != 'p') { long ln; #ifndef CONFIG_NOPRINTF_FIELDWIDTH @@ -1383,15 +1428,15 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #ifdef CONFIG_NOPRINTF_FIELDWIDTH /* Output the number */ - lutoascii(obj, *src, flags, (unsigned long)ln); + lutoascii(obj, FMT_CHAR, flags, (unsigned long)ln); #else /* Resolve sign-ness and format issues */ - lfixup(*src, &flags, &ln); + lfixup(FMT_CHAR, &flags, &ln); /* Get the width of the output */ - luwidth = getlusize(*src, flags, ln); + luwidth = getlusize(FMT_CHAR, flags, ln); /* Perform left field justification actions */ @@ -1399,7 +1444,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Output the number */ - lutoascii(obj, *src, flags, (unsigned long)ln); + lutoascii(obj, FMT_CHAR, flags, (unsigned long)ln); /* Perform right field justification actions */ @@ -1409,7 +1454,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) else #endif /* CONFIG_LONG_IS_NOT_INT */ #ifdef CONFIG_PTR_IS_NOT_INT - if (*src == 'p') + if (FMT_CHAR == 'p') { void *p; #ifndef CONFIG_NOPRINTF_FIELDWIDTH @@ -1426,11 +1471,11 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #else /* Resolve sign-ness and format issues */ - lfixup(*src, &flags, &ln); + lfixup(FMT_CHAR, &flags, &ln); /* Get the width of the output */ - luwidth = getpsize(*src, flags, p); + luwidth = getpsize(FMT_CHAR, flags, p); /* Perform left field justification actions */ @@ -1459,15 +1504,15 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) #ifdef CONFIG_NOPRINTF_FIELDWIDTH /* Output the number */ - utoascii(obj, *src, flags, (unsigned int)n); + utoascii(obj, FMT_CHAR, flags, (unsigned int)n); #else /* Resolve sign-ness and format issues */ - fixup(*src, &flags, &n); + fixup(FMT_CHAR, &flags, &n); /* Get the width of the output */ - uwidth = getusize(*src, flags, n); + uwidth = getusize(FMT_CHAR, flags, n); /* Perform left field justification actions */ @@ -1475,7 +1520,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Output the number */ - utoascii(obj, *src, flags, (unsigned int)n); + utoascii(obj, FMT_CHAR, flags, (unsigned int)n); /* Perform right field justification actions */ @@ -1487,10 +1532,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) /* Handle floating point conversions */ #ifdef CONFIG_LIBC_FLOATINGPOINT - else if (strchr("eEfgG", *src)) + else if (strchr("eEfgG", FMT_CHAR)) { double dblval = va_arg(ap, double); - lib_dtoa(obj, *src, trunc, flags, dblval); + lib_dtoa(obj, FMT_CHAR, trunc, flags, dblval); } #endif } |