mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 14:19:44 +00:00
lib: add %pVA
recursive printfrr
Analogous to Linux kernel `%pV` (but our mechanism expects 2 specifier chars and `%pVA` is clearer anyway.) Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
cb4928ce77
commit
9c4380daee
@ -65,6 +65,8 @@ Extensions
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
| ``%Ld`` | ``int64_t`` | ``-12345`` |
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
| ``%pVA`` | ``struct va_format *`` | (recursive printfrr) |
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
| ``%pI4`` | ``struct in_addr *`` | ``1.2.3.4`` |
|
||||
| | | |
|
||||
| | ``in_addr_t *`` | |
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -128,6 +128,21 @@ static int printchk(const char *ref, const char *fmt, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_va(const char *ref, const char *fmt, ...) PRINTFRR(2, 3);
|
||||
static void test_va(const char *ref, const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = ≈
|
||||
|
||||
printchk(ref, "VA [%pVA] %s", &vaf, "--");
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
size_t i;
|
||||
@ -168,6 +183,8 @@ int main(int argc, char **argv)
|
||||
|
||||
printcmp("%p", &ip);
|
||||
|
||||
test_va("VA [192.168.1.2 1234] --", "%pI4 %u", &ip, 1234);
|
||||
|
||||
snprintfrr(buf, sizeof(buf), "test%s", "#1");
|
||||
csnprintfrr(buf, sizeof(buf), "test%s", "#2");
|
||||
assert(strcmp(buf, "test#1test#2") == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user