]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: put printfrr extension args into struct
authorDavid Lamparter <equinox@diac24.net>
Sat, 20 Mar 2021 08:02:04 +0000 (09:02 +0100)
committerDavid Lamparter <equinox@diac24.net>
Tue, 30 Mar 2021 20:32:55 +0000 (22:32 +0200)
... for easier extensibility.  Add width, # and - flags while at it.

Signed-off-by: David Lamparter <equinox@diac24.net>
bgpd/bgp_table.c
lib/nexthop.c
lib/prefix.c
lib/printf/glue.c
lib/printf/printflocal.h
lib/printf/vfprintf.c
lib/printfrr.h
lib/sockunion.c
lib/srcdest_table.c

index d6dd03e2ac7fc788e631ae901c0c226ce5765cfc..833bdec2ed998164da21dc444295bba1a10c8c1a 100644 (file)
@@ -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);
index 443df99445452fe7b7534bff09ce28abfa734692..84393981497894a27dd8647b50c2f7116f29937d 100644 (file)
@@ -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)
@@ -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)");
index fba26a5b63c999bd084830aec7a1bedb020242ce..141d5646062f696d2383005055ba1afcc2381a53 100644 (file)
@@ -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];
@@ -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];
@@ -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];
 
@@ -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];
 
@@ -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];
 
@@ -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;
index 477fc0d384459d003dab9f15200e2af8ba07f8d0..389f503c334facfbec43d3b470a391f1dd62b9fc 100644 (file)
@@ -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;
 
@@ -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;
 
@@ -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;
 }
index df962fc043ee48f01fad9314e2d731d7ff9f3eeb..bac80e801c7cf8865869cc261e6f8e100f1eef99 100644 (file)
@@ -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;
index 96675e3620dfaecfd52486b33e53e618b52ee820..7fafa89aa70e9d193ed215f4849a74e8b48099c5 100644 (file)
@@ -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) {
@@ -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;
index 49243248d6926519699842f494f3ebe483ac7113..754cb09598e9eb6060ee1d0eb6c8eaf1ad4a8250 100644 (file)
@@ -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];
@@ -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.)
@@ -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,                                               \
@@ -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,                                         \
index ecbb0fcf91a5684016cab7393275fea8fa60e9b0..2175ac33607315e613bc739435188e2b64b85a47 100644 (file)
@@ -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;
@@ -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:
index b2422ba460b21088cfdc5f4b0ee7006a8f0d931e..d2e0682e95c8cc2ca06cc4ad769d4c4b3a91455f 100644 (file)
@@ -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;