diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/printf/glue.c | 18 | ||||
| -rw-r--r-- | lib/printfrr.h | 11 |
2 files changed, 29 insertions, 0 deletions
diff --git a/lib/printf/glue.c b/lib/printf/glue.c index 389f503c33..2c97dd639e 100644 --- a/lib/printf/glue.c +++ b/lib/printf/glue.c @@ -255,3 +255,21 @@ ssize_t printfrr_exti(struct fbuf *buf, struct printfrr_eargs *ea, } return -1; } + +printfrr_ext_autoreg_p("VA", printfrr_va) +static ssize_t printfrr_va(struct fbuf *buf, struct printfrr_eargs *ea, + const void *ptr) +{ + const struct va_format *vaf = ptr; + va_list ap; + + if (!vaf || !vaf->fmt || !vaf->va) + return bputs(buf, "NULL"); + + /* make sure we don't alter the data passed in - especially since + * bprintfrr (and thus this) might be called on the same format twice, + * when allocating a larger buffer in asnprintfrr() + */ + va_copy(ap, *vaf->va); + return vbprintfrr(buf, vaf->fmt, ap); +} diff --git a/lib/printfrr.h b/lib/printfrr.h index 8245a664b3..6ca4d963c4 100644 --- a/lib/printfrr.h +++ b/lib/printfrr.h @@ -251,6 +251,17 @@ static inline ssize_t bputch(struct fbuf *buf, char ch) return 1; } +/* %pVA extension, equivalent to Linux kernel %pV */ + +struct va_format { + const char *fmt; + va_list *va; +}; + +#ifdef _FRR_ATTRIBUTE_PRINTFRR +#pragma FRR printfrr_ext "%pVA" (struct va_format *) +#endif + /* when using non-ISO-C compatible extension specifiers... */ #ifdef _FRR_ATTRIBUTE_PRINTFRR |
