diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2023-01-10 09:49:29 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2023-01-10 16:10:18 +0100 |
commit | ef242750c534f91c13bac1d49b8ebcf701814dda (patch) | |
tree | bb5194c82e342728a738721667688ce3ffb60bd3 /lib | |
parent | 4c7524a84a40062cf9692819577bf0ca44a15aa6 (diff) | |
download | barebox-ef242750c534f91c13bac1d49b8ebcf701814dda.tar.gz barebox-ef242750c534f91c13bac1d49b8ebcf701814dda.tar.xz |
vsprintf: implement %pJP for printing JSONPaths
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@pengutronix.de>
Link: https://lore.barebox.org/20230110084930.3439001-4-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vsprintf.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 693f3c0cc0..cdb3906ea2 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) { @@ -369,6 +390,26 @@ char *hex_string(char *buf, const char *end, const u8 *addr, int field_width, } 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); |