summaryrefslogtreecommitdiff
path: root/lib/printf/glue.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2021-02-18 22:52:23 +0100
committerDavid Lamparter <equinox@diac24.net>2021-03-27 16:56:55 +0100
commit212e04e5a7f682594dab26cd8354bc4fa040b61f (patch)
tree59a09a812b868332f073985494ee0a61910da9fd /lib/printf/glue.c
parentbcf9d7d8aa77c66ac2e99f75ae11e276accecb1d (diff)
lib: rework printfrr extensions to output directly
Allowing printfrr extensions to directly write to the output buffer has a few advantages: - there is no arbitrary length limit imposed (previously 64) - the output doesn't need to be copied another time - the extension can directly use bprintfrr() to put together pieces The downside is that the theoretical length (regardless of available buffer space) must be computed correctly. Extended unit tests to test these paths a bit more thoroughly. Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'lib/printf/glue.c')
-rw-r--r--lib/printf/glue.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/printf/glue.c b/lib/printf/glue.c
index 29ca26ad5d..477fc0d384 100644
--- a/lib/printf/glue.c
+++ b/lib/printf/glue.c
@@ -210,15 +210,16 @@ void printfrr_ext_reg(const struct printfrr_ext *ext)
exts[i] = ext;
}
-ssize_t printfrr_extp(char *buf, size_t sz, const char *fmt, int prec,
+ssize_t printfrr_extp(struct fbuf *buf, const char **fmtp, int prec,
const void *ptr)
{
+ const char *fmt = *fmtp;
const struct printfrr_ext *ext;
size_t i;
for (i = ext_offsets[fmt[0] - 'A']; i < MAXEXT; i++) {
if (!entries[i].fmt[0] || entries[i].fmt[0] > fmt[0])
- return 0;
+ return -1;
if (entries[i].fmt[1] && entries[i].fmt[1] != fmt[1])
continue;
ext = exts[i];
@@ -226,20 +227,22 @@ ssize_t printfrr_extp(char *buf, size_t sz, const char *fmt, int prec,
continue;
if (strncmp(ext->match, fmt, strlen(ext->match)))
continue;
- return ext->print_ptr(buf, sz, fmt, prec, ptr);
+ *fmtp += strlen(ext->match);
+ return ext->print_ptr(buf, fmtp, prec, ptr);
}
- return 0;
+ return -1;
}
-ssize_t printfrr_exti(char *buf, size_t sz, const char *fmt, int prec,
+ssize_t printfrr_exti(struct fbuf *buf, const char **fmtp, int prec,
uintmax_t num)
{
+ const char *fmt = *fmtp;
const struct printfrr_ext *ext;
size_t i;
for (i = ext_offsets[fmt[0] - 'A']; i < MAXEXT; i++) {
if (!entries[i].fmt[0] || entries[i].fmt[0] > fmt[0])
- return 0;
+ return -1;
if (entries[i].fmt[1] && entries[i].fmt[1] != fmt[1])
continue;
ext = exts[i];
@@ -247,7 +250,8 @@ ssize_t printfrr_exti(char *buf, size_t sz, const char *fmt, int prec,
continue;
if (strncmp(ext->match, fmt, strlen(ext->match)))
continue;
- return ext->print_int(buf, sz, fmt, prec, num);
+ *fmtp += strlen(ext->match);
+ return ext->print_int(buf, fmtp, prec, num);
}
- return 0;
+ return -1;
}