On Sat, Jul 5, 2008 at 1:33 PM, Jan Engelhardt <jengelh@xxxxxxxxxx> wrote: > > On Saturday 2008-07-05 00:01, Andrew Morton wrote: >> >>We don't know how much interest there would be in churning NIPQUAD from >>the net guys. Interestingly, there's also %C (wint_t) which is a >>32-bit quantity. So we could just go and say "%C prints an ipv4 >>address" and be done with it. But there's no way of doing that for >>ipv6 addresses so things would become asymmetrical there. > > struct in6_addr src; > printk("Source address: %p{ipv6}\n", &src); > > How about %p{feature}? Something like this? (It's hard on the stack, yes, I know. We should fix kallsyms.) Vegard From: Vegard Nossum <vegard.nossum@xxxxxxxxx> Date: Sat, 5 Jul 2008 14:01:00 +0200 Subject: [PATCH] printf: add %p{} extension Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxx> --- lib/vsprintf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 44 insertions(+), 0 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6021757..011cf3f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -17,6 +17,7 @@ */ #include <stdarg.h> +#include <linux/kallsyms.h> #include <linux/module.h> #include <linux/types.h> #include <linux/string.h> @@ -366,6 +367,30 @@ static noinline char* put_dec(char *buf, unsigned long long num) #define SMALL 32 /* Must be 32 == 0x20 */ #define SPECIAL 64 /* 0x */ +static char *custom_format(char *buf, char *end, + const char *fmt, unsigned int fmtlen, void *arg) +{ + if (!strncmp(fmt, "sym", fmtlen)) { + char name[KSYM_SYMBOL_LEN]; + int len; + int i; + + len = sprint_symbol(name, (unsigned long) arg); + if (len < 0) + return buf; + + i = 0; + while (i < len) { + if (buf < end) + *buf = name[i]; + ++buf; + ++i; + } + } + + return buf; +} + static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type) { /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ @@ -648,6 +673,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 'p': + if (fmt[1] == '{') { + const char *cfmt; + + /* Skip the '%{' */ + ++fmt; + ++fmt; + + cfmt = fmt; + + /* Skip everything up to the '}' */ + while (*fmt && *fmt != '}') + ++fmt; + + str = custom_format(str, end, + cfmt, fmt - cfmt, + va_arg(args, void *)); + continue; + } + flags |= SMALL; if (field_width == -1) { field_width = 2*sizeof(void *); -- 1.5.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |