[PATCH 3/4] vsprintf: implement %pJP for printing JSONPaths
Ahmad Fatoum
a.fatoum at pengutronix.de
Tue Jan 10 00:49:29 PST 2023
We use an array of strings to represnt a JSONPath. Add a new %pJP format
specifier that can be used to print them. This is useful for error
messages when the lookup fails.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
lib/vsprintf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
test/self/printf.c | 17 +++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 693f3c0cc0c8..cdb3906ea2ff 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -197,6 +197,27 @@ static char *string(char *buf, const char *end, const char *s, int field_width,
return trailing_spaces(buf, end, len, &field_width, flags);
}
+static __maybe_unused char *string_array(char *buf, const char *end, char *const *s,
+ int field_width, int precision, int flags,
+ const char *separator)
+{
+ size_t i, len = strlen(separator);
+
+ while (*s) {
+ buf = string(buf, end, *s, field_width, precision, flags);
+ if (!*++s)
+ break;
+
+ for (i = 0; i < len; ++i) {
+ if (buf < end)
+ *buf = separator[i];
+ ++buf;
+ }
+ }
+
+ return buf;
+}
+
static char *wstring(char *buf, const char *end, const wchar_t *s, int field_width,
int precision, int flags)
{
@@ -368,6 +389,26 @@ char *hex_string(char *buf, const char *end, const u8 *addr, int field_width,
return buf;
}
+static noinline_for_stack
+char *jsonpath_string(char *buf, const char *end, char *const *path, int field_width,
+ int precision, int flags, const char *fmt)
+{
+ if ((unsigned long)path < PAGE_SIZE)
+ return string(buf, end, "<NULL>", field_width, precision, flags);
+
+ if (buf < end)
+ *buf = '$';
+ ++buf;
+
+ if (*path) {
+ if (buf < end)
+ *buf = '.';
+ ++buf;
+ }
+
+ return string_array(buf, end, path, field_width, precision, flags, ".");
+}
+
static noinline_for_stack
char *address_val(char *buf, const char *end, const void *addr,
int field_width, int precision, int flags, const char *fmt)
@@ -458,6 +499,9 @@ static char *pointer(const char *fmt, char *buf, const char *end, const void *pt
if (IS_ENABLED(CONFIG_PRINTF_HEXSTR))
return hex_string(buf, end, ptr, field_width, precision, flags, fmt);
break;
+ case 'J':
+ if (fmt[1] == 'P' && IS_ENABLED(CONFIG_JSMN))
+ return jsonpath_string(buf, end, ptr, field_width, precision, flags, fmt);
}
return raw_pointer(buf, end, ptr, field_width, precision, flags);
diff --git a/test/self/printf.c b/test/self/printf.c
index 7a74660868c2..eae40ed242c1 100644
--- a/test/self/printf.c
+++ b/test/self/printf.c
@@ -305,6 +305,22 @@ test_pointer(void)
errptr();
}
+static void __init
+test_jsonpath(void)
+{
+ if (!IS_ENABLED(CONFIG_JSMN)) {
+ pr_info("skipping jsonpath tests: CONFIG_JSMN disabled in config\n");
+ skipped_tests += 5;
+ return;
+ }
+
+ test("<NULL>", "%pJP", NULL);
+ test("$", "%pJP", &(char *[]){ NULL });
+ test("$.1", "%pJP", &(char *[]){ "1", NULL });
+ test("$.1.23", "%pJP", &(char *[]){ "1", "23", NULL });
+ test("$.1.23.456", "%pJP", &(char *[]){ "1", "23", "456", NULL });
+}
+
static void __init test_printf(void)
{
alloced_buffer = malloc(BUF_SIZE + 2*PAD_SIZE);
@@ -317,6 +333,7 @@ static void __init test_printf(void)
test_string();
test_pointer();
test_hexstr();
+ test_jsonpath();
free(alloced_buffer);
}
--
2.30.2
More information about the barebox
mailing list