From dfb4b6e3d8be0f34bf190b51b098c0629c25d3a5 Mon Sep 17 00:00:00 2001 From: Jiuzhu Dong Date: Tue, 24 Aug 2021 22:14:23 +0800 Subject: [PATCH] lib_vsprintf: Add %pV format support test case: void test(const char *fmt, ...) { struct va_format vaf; va_list ap; va_start(ap, fmt); vaf.fmt = fmt; vaf.va = ≈ printf("func:%s, %pV, line:%d\n", __func__, &vaf, __LINE__); va_end(ap); } int main(int argc, FAR char *argv[]) { char str[] = "Hello Boy and Girl!"; int count = 10; test("%s %d", str, count); return 0; } >> test func:test, Hello Boy and Girl! 10, line:49 Signed-off-by: Jiuzhu Dong --- include/stdio.h | 6 ++++++ libs/libc/stdio/lib_libvsprintf.c | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/stdio.h b/include/stdio.h index a2a7e00713..0643b8a290 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -104,6 +104,12 @@ typedef struct file_struct FILE; +struct va_format +{ + FAR const char *fmt; + FAR va_list *va; +}; + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/libs/libc/stdio/lib_libvsprintf.c b/libs/libc/stdio/lib_libvsprintf.c index 5eb97425f8..5dc712182c 100644 --- a/libs/libc/stdio/lib_libvsprintf.c +++ b/libs/libc/stdio/lib_libvsprintf.c @@ -117,6 +117,8 @@ # define fmt_char(fmt) (*(fmt)++) #endif +#define fmt_ungetc(fmt) ((fmt)--) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -459,6 +461,17 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream, if (c == 'p') { + if (fmt_char(fmt) == 'V') + { + FAR struct va_format *vaf = va_arg(ap, void *); + vsprintf_internal(stream, NULL, 0, vaf->fmt, *vaf->va); + continue; + } + else + { + fmt_ungetc(fmt); + } + /* Determine size of pointer and set flags accordingly */ flags &= ~(FL_LONG | FL_REPD_TYPE);