Skip to content

Commit

Permalink
lib: put printfrr extension args into struct
Browse files Browse the repository at this point in the history
... for easier extensibility.  Add width, # and - flags while at it.

Signed-off-by: David Lamparter <equinox@diac24.net>
  • Loading branch information
eqvinox committed Mar 30, 2021
1 parent 487eefc commit 3ea7943
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 49 deletions.
4 changes: 2 additions & 2 deletions bgpd/bgp_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ struct bgp_node *bgp_table_subtree_lookup(const struct bgp_table *table,
}

printfrr_ext_autoreg_p("BD", printfrr_bd)
static ssize_t printfrr_bd(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_bd(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct bgp_dest *dest = ptr;
const struct prefix *p = bgp_dest_get_prefix(dest);
Expand Down
14 changes: 7 additions & 7 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,22 +730,22 @@ int nexthop_str2backups(const char *str, int *num_backups,
* nexthop2str()
*/
printfrr_ext_autoreg_p("NH", printfrr_nh)
static ssize_t printfrr_nh(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct nexthop *nexthop = ptr;
bool do_ifi = false;
const char *v_is = "", *v_via = "", *v_viaif = "via ";
ssize_t ret = 0;

switch (**fmt) {
switch (*ea->fmt) {
case 'v':
(*fmt)++;
if (**fmt == 'v') {
ea->fmt++;
if (*ea->fmt == 'v') {
v_is = "is ";
v_via = "via ";
v_viaif = "";
(*fmt)++;
ea->fmt++;
}

if (!nexthop)
Expand Down Expand Up @@ -796,7 +796,7 @@ static ssize_t printfrr_nh(struct fbuf *buf, const char **fmt,

return ret;
case 's':
(*fmt)++;
ea->fmt++;

if (!nexthop)
return bputs(buf, "(null)");
Expand Down
24 changes: 12 additions & 12 deletions lib/prefix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,8 +1361,8 @@ char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len)
}

printfrr_ext_autoreg_p("EA", printfrr_ea)
static ssize_t printfrr_ea(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_ea(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct ethaddr *mac = ptr;
char cbuf[ETHER_ADDR_STRLEN];
Expand All @@ -1376,8 +1376,8 @@ static ssize_t printfrr_ea(struct fbuf *buf, const char **fmt,
}

printfrr_ext_autoreg_p("IA", printfrr_ia)
static ssize_t printfrr_ia(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_ia(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct ipaddr *ipa = ptr;
char cbuf[INET6_ADDRSTRLEN];
Expand All @@ -1390,8 +1390,8 @@ static ssize_t printfrr_ia(struct fbuf *buf, const char **fmt,
}

printfrr_ext_autoreg_p("I4", printfrr_i4)
static ssize_t printfrr_i4(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_i4(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
char cbuf[INET_ADDRSTRLEN];

Expand All @@ -1403,8 +1403,8 @@ static ssize_t printfrr_i4(struct fbuf *buf, const char **fmt,
}

printfrr_ext_autoreg_p("I6", printfrr_i6)
static ssize_t printfrr_i6(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_i6(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
char cbuf[INET6_ADDRSTRLEN];

Expand All @@ -1416,8 +1416,8 @@ static ssize_t printfrr_i6(struct fbuf *buf, const char **fmt,
}

printfrr_ext_autoreg_p("FX", printfrr_pfx)
static ssize_t printfrr_pfx(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_pfx(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
char cbuf[PREFIX_STRLEN];

Expand All @@ -1429,8 +1429,8 @@ static ssize_t printfrr_pfx(struct fbuf *buf, const char **fmt,
}

printfrr_ext_autoreg_p("SG4", printfrr_psg)
static ssize_t printfrr_psg(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_psg(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct prefix_sg *sg = ptr;
ssize_t ret = 0;
Expand Down
16 changes: 8 additions & 8 deletions lib/printf/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,10 @@ void printfrr_ext_reg(const struct printfrr_ext *ext)
exts[i] = ext;
}

ssize_t printfrr_extp(struct fbuf *buf, const char **fmtp, int prec,
ssize_t printfrr_extp(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const char *fmt = *fmtp;
const char *fmt = ea->fmt;
const struct printfrr_ext *ext;
size_t i;

Expand All @@ -227,16 +227,16 @@ ssize_t printfrr_extp(struct fbuf *buf, const char **fmtp, int prec,
continue;
if (strncmp(ext->match, fmt, strlen(ext->match)))
continue;
*fmtp += strlen(ext->match);
return ext->print_ptr(buf, fmtp, prec, ptr);
ea->fmt += strlen(ext->match);
return ext->print_ptr(buf, ea, ptr);
}
return -1;
}

ssize_t printfrr_exti(struct fbuf *buf, const char **fmtp, int prec,
ssize_t printfrr_exti(struct fbuf *buf, struct printfrr_eargs *ea,
uintmax_t num)
{
const char *fmt = *fmtp;
const char *fmt = ea->fmt;
const struct printfrr_ext *ext;
size_t i;

Expand All @@ -250,8 +250,8 @@ ssize_t printfrr_exti(struct fbuf *buf, const char **fmtp, int prec,
continue;
if (strncmp(ext->match, fmt, strlen(ext->match)))
continue;
*fmtp += strlen(ext->match);
return ext->print_int(buf, fmtp, prec, num);
ea->fmt += strlen(ext->match);
return ext->print_int(buf, ea, num);
}
return -1;
}
5 changes: 3 additions & 2 deletions lib/printf/printflocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ int _frr_find_warguments(const wchar_t *, va_list, union arg **) DSO_LOCAL;
#endif

/* returns number of bytes needed for full output, or -1 */
ssize_t printfrr_extp(struct fbuf *, const char **, int, const void *)
ssize_t printfrr_extp(struct fbuf *, struct printfrr_eargs *ea, const void *)
DSO_LOCAL;
ssize_t printfrr_exti(struct fbuf *, struct printfrr_eargs *ea, uintmax_t)
DSO_LOCAL;
ssize_t printfrr_exti(struct fbuf *, const char **, int, uintmax_t) DSO_LOCAL;
30 changes: 26 additions & 4 deletions lib/printf/vfprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,25 @@ reswitch: switch (ch) {
ulval = SARG();

if (printfrr_ext_char(fmt[0])) {
struct printfrr_eargs ea = {
.fmt = fmt,
.precision = prec,
.width = width,
.alt_repr = !!(flags & ALT),
.leftadj = !!(flags & LADJUST),
};

if (cb)
extstart = cb->pos;

size = printfrr_exti(cb, &fmt, prec,
size = printfrr_exti(cb, &ea,
(flags & INTMAX_SIZE) ? ujval
: (uintmax_t)ulval);
if (size >= 0)
if (size >= 0) {
fmt = ea.fmt;
width = ea.width;
goto ext_printed;
}
}
if (flags & INTMAX_SIZE) {
if ((intmax_t)ujval < 0) {
Expand Down Expand Up @@ -539,12 +550,23 @@ reswitch: switch (ch) {
*/
ptrval = GETARG(void *);
if (printfrr_ext_char(fmt[0])) {
struct printfrr_eargs ea = {
.fmt = fmt,
.precision = prec,
.width = width,
.alt_repr = !!(flags & ALT),
.leftadj = !!(flags & LADJUST),
};

if (cb)
extstart = cb->pos;

size = printfrr_extp(cb, &fmt, prec, ptrval);
if (size >= 0)
size = printfrr_extp(cb, &ea, ptrval);
if (size >= 0) {
fmt = ea.fmt;
width = ea.width;
goto ext_printed;
}
}
ujval = (uintmax_t)(uintptr_t)ptrval;
base = 16;
Expand Down
58 changes: 50 additions & 8 deletions lib/printfrr.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ char *asnprintfrr(struct memtype *mt, char *out, size_t sz,
*/
#define printfrr_ext_char(ch) ((ch) >= 'A' && (ch) <= 'Z')

struct printfrr_eargs;

struct printfrr_ext {
/* embedded string to minimize cache line pollution */
char match[8];
Expand All @@ -127,14 +129,53 @@ struct printfrr_ext {
* to consume extra input flags after %pXY, increment *fmt. It points
* at the first character after %pXY at entry. Convention is to make
* those flags lowercase letters or numbers.
*/
ssize_t (*print_ptr)(struct fbuf *buf, struct printfrr_eargs *info,
const void *);
ssize_t (*print_int)(struct fbuf *buf, struct printfrr_eargs *info,
uintmax_t);
};

/* additional information passed to extended formatters */

struct printfrr_eargs {
/* position in the format string. Points to directly after the
* extension specifier. Increment when consuming extra "flag
* characters".
*/
const char *fmt;

/* %.1234x / %.*x
* not POSIX compatible when used with %p, will cause warnings from
* GCC & clang. Usable with %d. Not used by the printfrr() itself
* for extension specifiers, so essentially available as a "free"
* parameter. -1 if not specified. Value in the format string
* cannot be negative, but negative values can be passed with %.*x
*/
int precision;

/* %1234x / %*x
* regular width specification. Internally handled by printfrr(), set
* to 0 if consumed by the extension in order to suppress standard
* width/padding behavior. 0 if not specified.
*
* prec is the precision specifier (the 999 in "%.999p") -1 means
* none given (value in the format string cannot be negative)
* NB: always positive, even if a negative value is passed in with
* %*x. (The sign is used for the - flag.)
*/
int width;

/* %#x
* "alternate representation" flag, not POSIX compatible when used
* with %p or %d, will cause warnings from GCC & clang. Not used by
* printfrr() itself for extension specifiers.
*/
bool alt_repr;

/* %-x
* left-pad flag. Internally handled by printfrr() if width is
* nonzero. Only use if the extension sets width to 0.
*/
ssize_t (*print_ptr)(struct fbuf *buf, const char **fmt, int prec,
const void *);
ssize_t (*print_int)(struct fbuf *buf, const char **fmt, int prec,
uintmax_t);
bool leftadj;
};

/* no locking - must be called when single threaded (e.g. at startup.)
Expand All @@ -144,7 +185,7 @@ struct printfrr_ext {
void printfrr_ext_reg(const struct printfrr_ext *);

#define printfrr_ext_autoreg_p(matchs, print_fn) \
static ssize_t print_fn(struct fbuf *, const char **, int, \
static ssize_t print_fn(struct fbuf *, struct printfrr_eargs *, \
const void *); \
static const struct printfrr_ext _printext_##print_fn = { \
.match = matchs, \
Expand All @@ -157,7 +198,8 @@ void printfrr_ext_reg(const struct printfrr_ext *);
/* end */

#define printfrr_ext_autoreg_i(matchs, print_fn) \
static ssize_t print_fn(struct fbuf *, const char **, int, uintmax_t); \
static ssize_t print_fn(struct fbuf *, struct printfrr_eargs *, \
uintmax_t); \
static const struct printfrr_ext _printext_##print_fn = { \
.match = matchs, \
.print_int = print_fn, \
Expand Down
8 changes: 4 additions & 4 deletions lib/sockunion.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,8 +664,8 @@ void sockunion_init(union sockunion *su)
}

printfrr_ext_autoreg_p("SU", printfrr_psu)
static ssize_t printfrr_psu(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_psu(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const union sockunion *su = ptr;
bool include_port = false;
Expand All @@ -677,9 +677,9 @@ static ssize_t printfrr_psu(struct fbuf *buf, const char **fmt,
return bputs(buf, "(null)");

while (!endflags) {
switch (**fmt) {
switch (*ea->fmt) {
case 'p':
(*fmt)++;
ea->fmt++;
include_port = true;
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions lib/srcdest_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ const char *srcdest_rnode2str(const struct route_node *rn, char *str, int size)
}

printfrr_ext_autoreg_p("RN", printfrr_rn)
static ssize_t printfrr_rn(struct fbuf *buf, const char **fmt,
int prec, const void *ptr)
static ssize_t printfrr_rn(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
{
const struct route_node *rn = ptr;
const struct prefix *dst_p, *src_p;
Expand Down

0 comments on commit 3ea7943

Please sign in to comment.