From: Lukas Funke <lukas.fu...@weidmueller.com> Forward '%p' format specifier to the underlying format logic in order to print pointers, especially bitmaps.
Signed-off-by: Lukas Funke <lukas.fu...@weidmueller.com> --- cmd/printf.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cmd/printf.c b/cmd/printf.c index 0c6887e0d6..a90c923871 100644 --- a/cmd/printf.c +++ b/cmd/printf.c @@ -90,6 +90,7 @@ #include <stddef.h> #include <stdio.h> #include <stdlib.h> +#include <linux/bitmap.h> #define WANT_HEX_ESCAPES 0 #define PRINT_CONVERSION_ERROR 1 @@ -476,6 +477,16 @@ static int get_width_prec(const char *str) return (int)v; } +static int print_pointer(struct print_inf *inf, char *format, + unsigned int fmt_length, const char *argument) +{ + u64 value = simple_strtoull(argument, NULL, 0); + + printf_str(inf, format, &value); + + return inf->error; +} + /* Print the text in FORMAT, using ARGV for arguments to any '%' directives. * Return advanced ARGV. */ @@ -536,6 +547,24 @@ static char **print_formatted(struct print_inf *inf, char *f, char **argv, int * } } } + if (*f == 'p') { + static const char ptr_format_chars[] = "bl"; + ++f; + ++direc_length; + char *p = strchr(ptr_format_chars, *f); + /* consume whole format token */ + while (*f != '\0' && *(p++) == *f) { + ++f; + ++direc_length; + } + if (print_pointer(inf, direc_start, direc_length, *argv++)) { + printf("`%s': invalid format\n", direc_start); + /* causes main() to exit with error */ + return saved_argv - 1; + } + f--; + break; + } /* Remove "lLhz" size modifiers, repeatedly. * bash does not like "%lld", but coreutils -- 2.30.2