[PATCH v3 11/11] cmd: printf: forward '%p' format string specifier
lukas.funke-oss at weidmueller.com
lukas.funke-oss at weidmueller.com
Wed Jan 10 10:10:37 CET 2024
From: Lukas Funke <lukas.funke at weidmueller.com>
Forward '%p' format specifier to the underlying format logic in order
to print pointers, especially bitmaps.
Signed-off-by: Lukas Funke <lukas.funke at weidmueller.com>
---
Changes in v3:
- Dereference pointer argument (i.e. *value) in the
'setexpr name fmt <format> value' case. This is currently only
supported in the 'setexptr <name> [*]<value>' and
'setexptr <name> [*]<value> <op> [*]<value2>' case
cmd/printf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/cmd/printf.c b/cmd/printf.c
index f56543b79e..2e54faf339 100644
--- a/cmd/printf.c
+++ b/cmd/printf.c
@@ -85,11 +85,13 @@
*/
#include <common.h>
+#include <command.h>
#include <ctype.h>
#include <errno.h>
#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 +478,38 @@ 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, int field_width,
+ int precision, const char *argument)
+{
+ struct expr_arg aval;
+
+ if (setexpr_get_arg(skip_whitespace(argument), field_width >> 3, &aval))
+ return CMD_RET_FAILURE;
+
+ if (field_width > BITS_PER_LONG) {
+ printf_str(inf, format, aval.bmap);
+ free(aval.bmap);
+ } else {
+ printf_str(inf, format, &aval.ival);
+ }
+
+ switch (inf->error) {
+ case 0:
+ return 0;
+ case PRINT_SIZE_ERROR:
+ printf("printf: size error\n"); break;
+ case PRINT_CONVERSION_ERROR:
+ printf("printf: conversion error\n"); break;
+ case PRINT_TRUNCATED_ERROR:
+ printf("printf: output truncated\n"); break;
+ default:
+ printf("printf: unknown error\n");
+ }
+
+ return -1;
+}
+
/* Print the text in FORMAT, using ARGV for arguments to any '%' directives.
* Return advanced ARGV.
*/
@@ -536,6 +570,23 @@ 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,
+ field_width, precision, *argv++)) {
+ return saved_argv - 1;
+ }
+ f--;
+ break;
+ }
/* Remove "lLhz" size modifiers, repeatedly.
* bash does not like "%lld", but coreutils
--
2.30.2
More information about the U-Boot
mailing list