OSDN Git Service

tools/nolibc/stdio: add support for '%p' to vfprintf()
authorWilly Tarreau <w@1wt.eu>
Mon, 21 Mar 2022 17:33:09 +0000 (18:33 +0100)
committerPaul E. McKenney <paulmck@kernel.org>
Thu, 21 Apr 2022 00:05:45 +0000 (17:05 -0700)
%p remains quite useful in test code, and the code path can easily be
merged with the existing "%x" thus only adds ~50 bytes, thus let's
add it.

Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
tools/include/nolibc/stdio.h

index 559ebe0..15dedf8 100644 (file)
@@ -163,7 +163,7 @@ char *fgets(char *s, int size, FILE *stream)
 
 
 /* minimal vfprintf(). It supports the following formats:
- *  - %[l*]{d,u,c,x}
+ *  - %[l*]{d,u,c,x,p}
  *  - %s
  *  - unknown modifiers are ignored.
  */
@@ -184,8 +184,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args)
                if (escape) {
                        /* we're in an escape sequence, ofs == 1 */
                        escape = 0;
-                       if (c == 'c' || c == 'd' || c == 'u' || c == 'x') {
-                               if (lpref) {
+                       if (c == 'c' || c == 'd' || c == 'u' || c == 'x' || c == 'p') {
+                               char *out = tmpbuf;
+
+                               if (c == 'p')
+                                       v = va_arg(args, unsigned long);
+                               else if (lpref) {
                                        if (lpref > 1)
                                                v = va_arg(args, unsigned long long);
                                        else
@@ -202,18 +206,22 @@ int vfprintf(FILE *stream, const char *fmt, va_list args)
                                }
 
                                switch (c) {
+                               case 'c':
+                                       out[0] = v;
+                                       out[1] = 0;
+                                       break;
                                case 'd':
-                                       i64toa_r(v, tmpbuf);
+                                       i64toa_r(v, out);
                                        break;
                                case 'u':
-                                       u64toa_r(v, tmpbuf);
-                                       break;
-                               case 'x':
-                                       u64toh_r(v, tmpbuf);
+                                       u64toa_r(v, out);
                                        break;
-                               default: /* 'c' */
-                                       tmpbuf[0] = v;
-                                       tmpbuf[1] = 0;
+                               case 'p':
+                                       *(out++) = '0';
+                                       *(out++) = 'x';
+                                       /* fall through */
+                               default: /* 'x' and 'p' above */
+                                       u64toh_r(v, out);
                                        break;
                                }
                                outstr = tmpbuf;