anchao commented on code in PR #21340:
URL: https://github.com/apache/nuttx/pull/21340#discussion_r4455609405


##########
libs/libc/stream/lib_libvsprintf.c:
##########
@@ -170,6 +202,1169 @@ static int vsprintf_repeat(FAR struct lib_outstream_s 
*stream, int ch,
   return total_len;
 }
 
+static int vsprintf_putnum(FAR struct lib_outstream_s *stream,
+                           FAR char *buf, int len)
+{
+  int i;
+  int j;
+
+  for (i = 0, j = len - 1; i < j; i++, j--)
+    {
+      char tmp = buf[i];
+
+      buf[i] = buf[j];
+      buf[j] = tmp;
+    }
+
+  if (len > 0)
+    {
+      lib_stream_puts(stream, buf, len);
+    }
+
+  return len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_scan_literal
+ *
+ * Description:
+ *   Scan and emit ordinary literal text until the next conversion specifier.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_scan_literal(FAR struct lib_outstream_s *stream,
+                      FAR const IPTR char **fmtp,
+                      FAR unsigned char *conv)
+{
+  FAR const IPTR char *fmt = *fmtp;
+  unsigned char c;
+  int total_len = 0;
+
+#ifndef CONFIG_ARCH_ROMGETC
+  FAR const char *start = fmt;
+
+  for (; ; )
+    {
+      c = fmt_char(fmt);
+      if (c == '\0')
+        {
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+          if (stream != NULL)
+#  endif
+            {
+              size_t litlen = (fmt - start) - 1;
+
+              if (litlen > 0)
+                {
+                  total_len += litlen;
+                  lib_stream_puts(stream, start, litlen);
+                }
+            }
+
+          break;
+        }
+
+      if (c == '%')
+        {
+          size_t litlen = (fmt - start) - 1;
+
+          c = fmt_char(fmt);
+          if (c != '%')
+            {
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+              if (stream != NULL)
+#  endif
+                {
+                  if (litlen > 0)
+                    {
+                      total_len += litlen;
+                      lib_stream_puts(stream, start, litlen);
+                    }
+                }
+
+              break;
+            }
+
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+          if (stream != NULL)
+#  endif
+            {
+              total_len += litlen + 1;
+              lib_stream_puts(stream, start, litlen + 1);
+            }
+
+          start = fmt;
+        }
+    }
+#else
+  for (; ; )
+    {
+      c = fmt_char(fmt);
+      if (c == '\0')
+        {
+          break;
+        }
+
+      if (c == '%')
+        {
+          c = fmt_char(fmt);
+          if (c != '%')
+            {
+              break;
+            }
+        }
+
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+      if (stream != NULL)
+#  endif
+        {
+          total_len++;
+          lib_stream_putc(stream, c);
+        }
+    }
+#endif
+
+  *fmtp = fmt;
+  *conv = c;
+
+  return total_len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_put_field
+ *
+ * Description:
+ *   Emit a field with leading padding and update the remaining width.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_field(FAR struct lib_outstream_s *stream,
+                   FAR const char *pnt, size_t size,
+                   FAR int *width, uint16_t flags)
+{
+  int total_len = 0;
+  int w = *width;
+
+  if ((flags & FL_LPAD) == 0)
+    {
+      if (w > 0 && size < w)
+        {
+          int pad = w - size;
+
+          total_len += vsprintf_repeat(stream, ' ', pad);
+          w -= pad;
+        }
+    }
+
+  total_len += size;
+  lib_stream_puts(stream, pnt, size);
+  *width = w >= size ? w - size : 0;
+
+  return total_len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_put_char
+ *
+ * Description:
+ *   Emit a character conversion, including wide-character handling.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_char(FAR struct lib_outstream_s *stream,
+                  uint16_t flags, int ch, FAR int *width,
+                  FAR char *buf)
+{
+  FAR const char *pnt;
+  size_t size;
+
+#ifdef CONFIG_LIBC_LOCALE
+  if ((flags & FL_LONG) != 0)
+    {
+      mbstate_t ps;
+
+      /* %lc: a wide character, written as its multibyte sequence. */
+
+      memset(&ps, 0, sizeof(ps));
+      size = wcrtomb(buf, (wchar_t)ch, &ps);
+      if (size == (size_t)-1)
+        {
+          return -1;
+        }
+    }
+  else
+#endif
+    {
+      buf[0] = ch;
+      size = 1;
+    }
+
+  pnt = buf;
+
+  /* Share normal field padding/output with string conversions. */
+
+  return vsprintf_put_field(stream, pnt, size, width, flags);
+}
+
+#ifdef CONFIG_LIBC_LOCALE
+/****************************************************************************
+ * Name: vsprintf_put_wstring
+ *
+ * Description:
+ *   Emit a wide string conversion as multibyte characters.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_wstring(FAR struct lib_outstream_s *stream,
+                     FAR const wchar_t *ws, uint16_t flags,
+                     FAR int *width, int prec)
+{
+  char mb[MB_LEN_MAX];
+  mbstate_t ps;
+  size_t size;
+  size_t n;
+  int total_len = 0;
+  int i;
+
+  /* %ls: a wide string, written as multibyte characters.  The precision
+   * limits the bytes, and a character that does not fit is not written in
+   * part.  First count the bytes.
+   */
+
+  memset(&ps, 0, sizeof(ps));
+  for (size = 0, i = 0; ws[i] != L'\0'; i++)
+    {
+      n = wcrtomb(mb, ws[i], &ps);
+      if (n == (size_t)-1)
+        {
+          return -1;
+        }
+
+      if ((flags & FL_PREC) != 0 && size + n > (size_t)prec)
+        {
+          break;
+        }
+
+      size += n;
+    }
+
+  if ((flags & FL_LPAD) == 0)
+    {
+      if (*width > 0 && size < *width)
+        {
+          int pad = *width - size;
+
+          total_len += vsprintf_repeat(stream, ' ', pad);
+          *width -= pad;
+        }
+    }
+
+  memset(&ps, 0, sizeof(ps));
+  for (n = 0, i = 0; n < size; i++)
+    {
+      size_t m = wcrtomb(mb, ws[i], &ps);
+
+      total_len += m;
+      lib_stream_puts(stream, mb, m);
+      n += m;
+    }
+
+  *width = *width >= size ? *width - size : 0;
+
+  return total_len;
+}
+#endif
+
+#ifdef CONFIG_LIBC_NUMBERED_ARGS
+/****************************************************************************
+ * Name: vsprintf_check_arg
+ *
+ * Description:
+ *   Validate numbered arguments and record their type during the parse pass.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_check_arg(FAR struct lib_outstream_s *stream,
+                   FAR struct arg_s *arglist, int numargs,
+                   int argnumber, uint16_t flags,
+                   unsigned char c, FAR int *total_len)
+{
+  if ((flags & FL_ARGNUMBER) != 0)
+    {
+      if (argnumber <= 0 || argnumber > numargs)
+        {
+          return -1;
+        }
+
+      if (stream == NULL)
+        {
+          if ((c >= 'E' && c <= 'G') || (c >= 'e' && c <= 'g'))
+            {
+              arglist->type[argnumber - 1] = TYPE_DOUBLE;
+            }
+          else if (c == 'i' || c == 'd' || c == 'u' || c == 'p')
+            {
+              if ((flags & FL_LONG) == 0)
+                {
+                  arglist->type[argnumber - 1] = TYPE_INT;
+                }
+              else if ((flags & FL_REPD_TYPE) == 0)
+                {
+                  arglist->type[argnumber - 1] = TYPE_LONG;
+                }
+              else
+                {
+                  arglist->type[argnumber - 1] = TYPE_LONG_LONG;
+                }
+            }
+          else if (c == 'c')
+            {
+              arglist->type[argnumber - 1] = TYPE_INT;
+            }
+          else if (c == 's')
+            {
+              arglist->type[argnumber - 1] = TYPE_CHAR_POINTER;
+            }
+
+          if (argnumber > *total_len)
+            {
+              *total_len = argnumber;
+            }
+
+          return 1; /* We do only parsing */
+        }
+    }
+  else if (stream == NULL)
+    {
+      return 1; /* We do only parsing */
+    }
+
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: vsprintf_pointer_flags
+ *
+ * Description:
+ *   Select integer-size flags that match the platform pointer size.
+ *
+ ****************************************************************************/
+
+static inline_function void
+vsprintf_pointer_flags(FAR uint16_t *flags)
+{
+  /* Determine size of pointer and set flags accordingly */
+
+  *flags &= ~(FL_LONG | FL_REPD_TYPE);
+
+  if (sizeof(FAR void *) == sizeof(unsigned long long))
+    {
+      *flags |= FL_LONG | FL_REPD_TYPE;
+    }
+  else if (sizeof(FAR void *) == sizeof(unsigned long))
+    {
+      *flags |= FL_LONG;
+    }
+}
+
+#ifdef CONFIG_LIBC_PRINT_EXTENSION
+/****************************************************************************
+ * Name: vsprintf_pointer_extension
+ *
+ * Description:
+ *   Handle CONFIG_LIBC_PRINT_EXTENSION pointer conversion extensions.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_pointer_extension(FAR struct lib_outstream_s *stream,
+                           FAR const IPTR char **fmt,
+                           unsigned long long x, FAR int *total_len)
+{
+  unsigned char c = fmt_char(*fmt);
+
+  switch (c)
+    {
+      case 'B':
+        {
+          FAR struct va_format *vaf = (FAR void *)(uintptr_t)x;
+
+          lib_bsprintf(stream, vaf->fmt, vaf->va);
+          return 1;
+        }
+
+      case 'V':
+        {
+          FAR struct va_format *vaf = (FAR void *)(uintptr_t)x;
+#  ifdef va_copy
+          va_list copy;
+
+          va_copy(copy, *vaf->va);
+          lib_vsprintf(stream, vaf->fmt, copy);
+          va_end(copy);
+#  else
+          lib_vsprintf(stream, vaf->fmt, *vaf->va);
+#  endif
+          return 1;
+        }
+
+      case 'S':
+      case 's':
+        {
+#  ifdef CONFIG_ALLSYMS
+          FAR const struct symtab_s *symbol;
+          FAR void *addr = (FAR void *)(uintptr_t)x;
+          size_t symbolsize;
+          FAR const char *name;
+          size_t namelen;
+
+          symbol = allsyms_findbyvalue(addr, &symbolsize);
+          if (symbol != NULL)
+            {
+              name = symbol->sym_name;
+              namelen = strlen(name);
+
+              *total_len += namelen;
+              lib_stream_puts(stream, name, namelen);
+
+              if (c == 'S')
+                {
+                  *total_len +=
+                    lib_sprintf_internal(stream, "+%#tx/%#zx",
+                                         addr - symbol->sym_value,
+                                         symbolsize);
+                }
+
+              return 1;
+            }
+#  endif
+          break;
+        }
+
+      default:
+        fmt_ungetc(*fmt);
+        break;
+    }
+
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: vsprintf_get_integer_arg
+ *
+ * Description:
+ *   Fetch an integer conversion argument and apply any short-size narrowing.
+ *
+ ****************************************************************************/
+
+static inline_function void
+vsprintf_get_integer_arg(uint16_t flags, int is_signed,
+                         FAR long long *svalue,
+                         FAR unsigned long long *uvalue,
+#ifdef CONFIG_LIBC_NUMBERED_ARGS
+                         FAR struct arg_s *arglist, int argnumber,
+#endif
+                         va_list ap)

Review Comment:
   done



##########
libs/libc/stream/lib_libvsprintf.c:
##########
@@ -170,6 +202,1169 @@ static int vsprintf_repeat(FAR struct lib_outstream_s 
*stream, int ch,
   return total_len;
 }
 
+static int vsprintf_putnum(FAR struct lib_outstream_s *stream,
+                           FAR char *buf, int len)
+{
+  int i;
+  int j;
+
+  for (i = 0, j = len - 1; i < j; i++, j--)
+    {
+      char tmp = buf[i];
+
+      buf[i] = buf[j];
+      buf[j] = tmp;
+    }
+
+  if (len > 0)
+    {
+      lib_stream_puts(stream, buf, len);
+    }
+
+  return len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_scan_literal
+ *
+ * Description:
+ *   Scan and emit ordinary literal text until the next conversion specifier.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_scan_literal(FAR struct lib_outstream_s *stream,
+                      FAR const IPTR char **fmtp,
+                      FAR unsigned char *conv)
+{
+  FAR const IPTR char *fmt = *fmtp;
+  unsigned char c;
+  int total_len = 0;
+
+#ifndef CONFIG_ARCH_ROMGETC
+  FAR const char *start = fmt;
+
+  for (; ; )
+    {
+      c = fmt_char(fmt);
+      if (c == '\0')
+        {
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+          if (stream != NULL)
+#  endif
+            {
+              size_t litlen = (fmt - start) - 1;
+
+              if (litlen > 0)
+                {
+                  total_len += litlen;
+                  lib_stream_puts(stream, start, litlen);
+                }
+            }
+
+          break;
+        }
+
+      if (c == '%')
+        {
+          size_t litlen = (fmt - start) - 1;
+
+          c = fmt_char(fmt);
+          if (c != '%')
+            {
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+              if (stream != NULL)
+#  endif
+                {
+                  if (litlen > 0)
+                    {
+                      total_len += litlen;
+                      lib_stream_puts(stream, start, litlen);
+                    }
+                }
+
+              break;
+            }
+
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+          if (stream != NULL)
+#  endif
+            {
+              total_len += litlen + 1;
+              lib_stream_puts(stream, start, litlen + 1);
+            }
+
+          start = fmt;
+        }
+    }
+#else
+  for (; ; )
+    {
+      c = fmt_char(fmt);
+      if (c == '\0')
+        {
+          break;
+        }
+
+      if (c == '%')
+        {
+          c = fmt_char(fmt);
+          if (c != '%')
+            {
+              break;
+            }
+        }
+
+#  ifdef CONFIG_LIBC_NUMBERED_ARGS
+      if (stream != NULL)
+#  endif
+        {
+          total_len++;
+          lib_stream_putc(stream, c);
+        }
+    }
+#endif
+
+  *fmtp = fmt;
+  *conv = c;
+
+  return total_len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_put_field
+ *
+ * Description:
+ *   Emit a field with leading padding and update the remaining width.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_field(FAR struct lib_outstream_s *stream,
+                   FAR const char *pnt, size_t size,
+                   FAR int *width, uint16_t flags)
+{
+  int total_len = 0;
+  int w = *width;
+
+  if ((flags & FL_LPAD) == 0)
+    {
+      if (w > 0 && size < w)
+        {
+          int pad = w - size;
+
+          total_len += vsprintf_repeat(stream, ' ', pad);
+          w -= pad;
+        }
+    }
+
+  total_len += size;
+  lib_stream_puts(stream, pnt, size);
+  *width = w >= size ? w - size : 0;
+
+  return total_len;
+}
+
+/****************************************************************************
+ * Name: vsprintf_put_char
+ *
+ * Description:
+ *   Emit a character conversion, including wide-character handling.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_char(FAR struct lib_outstream_s *stream,
+                  uint16_t flags, int ch, FAR int *width,
+                  FAR char *buf)
+{
+  FAR const char *pnt;
+  size_t size;
+
+#ifdef CONFIG_LIBC_LOCALE
+  if ((flags & FL_LONG) != 0)
+    {
+      mbstate_t ps;
+
+      /* %lc: a wide character, written as its multibyte sequence. */
+
+      memset(&ps, 0, sizeof(ps));
+      size = wcrtomb(buf, (wchar_t)ch, &ps);
+      if (size == (size_t)-1)
+        {
+          return -1;
+        }
+    }
+  else
+#endif
+    {
+      buf[0] = ch;
+      size = 1;
+    }
+
+  pnt = buf;
+
+  /* Share normal field padding/output with string conversions. */
+
+  return vsprintf_put_field(stream, pnt, size, width, flags);
+}
+
+#ifdef CONFIG_LIBC_LOCALE
+/****************************************************************************
+ * Name: vsprintf_put_wstring
+ *
+ * Description:
+ *   Emit a wide string conversion as multibyte characters.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_put_wstring(FAR struct lib_outstream_s *stream,
+                     FAR const wchar_t *ws, uint16_t flags,
+                     FAR int *width, int prec)
+{
+  char mb[MB_LEN_MAX];
+  mbstate_t ps;
+  size_t size;
+  size_t n;
+  int total_len = 0;
+  int i;
+
+  /* %ls: a wide string, written as multibyte characters.  The precision
+   * limits the bytes, and a character that does not fit is not written in
+   * part.  First count the bytes.
+   */
+
+  memset(&ps, 0, sizeof(ps));
+  for (size = 0, i = 0; ws[i] != L'\0'; i++)
+    {
+      n = wcrtomb(mb, ws[i], &ps);
+      if (n == (size_t)-1)
+        {
+          return -1;
+        }
+
+      if ((flags & FL_PREC) != 0 && size + n > (size_t)prec)
+        {
+          break;
+        }
+
+      size += n;
+    }
+
+  if ((flags & FL_LPAD) == 0)
+    {
+      if (*width > 0 && size < *width)
+        {
+          int pad = *width - size;
+
+          total_len += vsprintf_repeat(stream, ' ', pad);
+          *width -= pad;
+        }
+    }
+
+  memset(&ps, 0, sizeof(ps));
+  for (n = 0, i = 0; n < size; i++)
+    {
+      size_t m = wcrtomb(mb, ws[i], &ps);
+
+      total_len += m;
+      lib_stream_puts(stream, mb, m);
+      n += m;
+    }
+
+  *width = *width >= size ? *width - size : 0;
+
+  return total_len;
+}
+#endif
+
+#ifdef CONFIG_LIBC_NUMBERED_ARGS
+/****************************************************************************
+ * Name: vsprintf_check_arg
+ *
+ * Description:
+ *   Validate numbered arguments and record their type during the parse pass.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_check_arg(FAR struct lib_outstream_s *stream,
+                   FAR struct arg_s *arglist, int numargs,
+                   int argnumber, uint16_t flags,
+                   unsigned char c, FAR int *total_len)
+{
+  if ((flags & FL_ARGNUMBER) != 0)
+    {
+      if (argnumber <= 0 || argnumber > numargs)
+        {
+          return -1;
+        }
+
+      if (stream == NULL)
+        {
+          if ((c >= 'E' && c <= 'G') || (c >= 'e' && c <= 'g'))
+            {
+              arglist->type[argnumber - 1] = TYPE_DOUBLE;
+            }
+          else if (c == 'i' || c == 'd' || c == 'u' || c == 'p')
+            {
+              if ((flags & FL_LONG) == 0)
+                {
+                  arglist->type[argnumber - 1] = TYPE_INT;
+                }
+              else if ((flags & FL_REPD_TYPE) == 0)
+                {
+                  arglist->type[argnumber - 1] = TYPE_LONG;
+                }
+              else
+                {
+                  arglist->type[argnumber - 1] = TYPE_LONG_LONG;
+                }
+            }
+          else if (c == 'c')
+            {
+              arglist->type[argnumber - 1] = TYPE_INT;
+            }
+          else if (c == 's')
+            {
+              arglist->type[argnumber - 1] = TYPE_CHAR_POINTER;
+            }
+
+          if (argnumber > *total_len)
+            {
+              *total_len = argnumber;
+            }
+
+          return 1; /* We do only parsing */
+        }
+    }
+  else if (stream == NULL)
+    {
+      return 1; /* We do only parsing */
+    }
+
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: vsprintf_pointer_flags
+ *
+ * Description:
+ *   Select integer-size flags that match the platform pointer size.
+ *
+ ****************************************************************************/
+
+static inline_function void
+vsprintf_pointer_flags(FAR uint16_t *flags)
+{
+  /* Determine size of pointer and set flags accordingly */
+
+  *flags &= ~(FL_LONG | FL_REPD_TYPE);
+
+  if (sizeof(FAR void *) == sizeof(unsigned long long))
+    {
+      *flags |= FL_LONG | FL_REPD_TYPE;
+    }
+  else if (sizeof(FAR void *) == sizeof(unsigned long))
+    {
+      *flags |= FL_LONG;
+    }
+}
+
+#ifdef CONFIG_LIBC_PRINT_EXTENSION
+/****************************************************************************
+ * Name: vsprintf_pointer_extension
+ *
+ * Description:
+ *   Handle CONFIG_LIBC_PRINT_EXTENSION pointer conversion extensions.
+ *
+ ****************************************************************************/
+
+static inline_function int
+vsprintf_pointer_extension(FAR struct lib_outstream_s *stream,

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to