summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-01 19:08:04 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-01 19:08:04 +0000
commit00b2545e9e3cc760255aa7b4fc953ad5ab97ba62 (patch)
tree90f908d15691555fdf19c21eeae7b55187b73803
parent6e09d7aab47a47e36f56d9b33bd6e87e96e2af2c (diff)
downloadnuttx-00b2545e9e3cc760255aa7b4fc953ad5ab97ba62.tar.gz
nuttx-00b2545e9e3cc760255aa7b4fc953ad5ab97ba62.tar.bz2
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
-rw-r--r--nuttx/ChangeLog8
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html57
-rw-r--r--nuttx/arch/avr/include/avr/types.h7
-rw-r--r--nuttx/arch/avr/src/at90usb/Make.defs4
-rw-r--r--nuttx/arch/avr/src/atmega/Make.defs4
-rw-r--r--nuttx/arch/sim/src/Makefile6
-rw-r--r--nuttx/configs/README.txt34
-rw-r--r--nuttx/include/nuttx/arch.h39
-rw-r--r--nuttx/include/nuttx/compiler.h21
-rwxr-xr-xnuttx/include/stdint.h9
-rw-r--r--nuttx/lib/lib_internal.h2
-rw-r--r--nuttx/lib/stdio/lib_fputs.c53
-rw-r--r--nuttx/lib/stdio/lib_libvsprintf.c145
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 &quot;external&quot; 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 &quot;one-size-fits-all&quot; 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
}