summaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1291cf7dd9..7d943706dd 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -198,6 +198,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)
{
@@ -370,6 +391,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)
{
@@ -471,6 +512,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);