| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef _FRR_PRINTFRR_H |
| #define _FRR_PRINTFRR_H |
| |
| #include <stddef.h> |
| #include <stdarg.h> |
| #include <stdint.h> |
| |
| #include "compiler.h" |
| #include "memory.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| struct fbuf { |
| char *buf; |
| char *pos; |
| size_t len; |
| }; |
| |
| #define at(a, b) PRINTFRR(a, b) |
| #define atn(a, b) \ |
| at(a, b) __attribute__((nonnull(1) _RET_NONNULL)) |
| #define atm(a, b) \ |
| atn(a, b) __attribute__((malloc)) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ssize_t vbprintfrr(struct fbuf *out, const char *fmt, va_list) at(2, 0); |
| ssize_t bprintfrr(struct fbuf *out, const char *fmt, ...) at(2, 3); |
| |
| |
| ssize_t vsnprintfrr(char *out, size_t sz, const char *fmt, va_list) at(3, 0); |
| ssize_t snprintfrr(char *out, size_t sz, const char *fmt, ...) at(3, 4); |
| |
| |
| |
| |
| ssize_t vcsnprintfrr(char *out, size_t sz, const char *fmt, va_list) at(3, 0); |
| ssize_t csnprintfrr(char *out, size_t sz, const char *fmt, ...) at(3, 4); |
| |
| |
| |
| char *vasprintfrr(struct memtype *mt, const char *fmt, va_list) atm(2, 0); |
| char *asprintfrr(struct memtype *mt, const char *fmt, ...) atm(2, 3); |
| |
| |
| |
| |
| char *vasnprintfrr(struct memtype *mt, char *out, size_t sz, |
| const char *fmt, va_list) atn(4, 0); |
| char *asnprintfrr(struct memtype *mt, char *out, size_t sz, |
| const char *fmt, ...) atn(4, 5); |
| |
| #define printfrr(fmt, ...) \ |
| do { \ |
| char buf[256], *out; \ |
| out = asnprintfrr(MTYPE_TMP, buf, sizeof(buf), fmt, \ |
| ##__VA_ARGS__); \ |
| fputs(out, stdout); \ |
| if (out != buf) \ |
| XFREE(MTYPE_TMP, out); \ |
| } while (0) |
| |
| #undef at |
| #undef atm |
| #undef atn |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #define printfrr_ext_char(ch) ((ch) >= 'A' && (ch) <= 'Z') |
| |
| struct printfrr_ext { |
| |
| char match[8]; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ssize_t (*print_ptr)(char *buf, size_t bsz, const char *fmt, int prec, |
| const void *); |
| ssize_t (*print_int)(char *buf, size_t bsz, const char *fmt, int prec, |
| uintmax_t); |
| }; |
| |
| |
| |
| |
| |
| void printfrr_ext_reg(const struct printfrr_ext *); |
| |
| #define printfrr_ext_autoreg_p(matchs, print_fn) \ |
| static ssize_t print_fn(char *, size_t, const char *, int, \ |
| const void *); \ |
| static const struct printfrr_ext _printext_##print_fn = { \ |
| .match = matchs, \ |
| .print_ptr = print_fn, \ |
| }; \ |
| static void _printreg_##print_fn(void) __attribute__((constructor)); \ |
| static void _printreg_##print_fn(void) { \ |
| printfrr_ext_reg(&_printext_##print_fn); \ |
| } \ |
| |
| |
| #define printfrr_ext_autoreg_i(matchs, print_fn) \ |
| static ssize_t print_fn(char *, size_t, const char *, int, uintmax_t); \ |
| static const struct printfrr_ext _printext_##print_fn = { \ |
| .match = matchs, \ |
| .print_int = print_fn, \ |
| }; \ |
| static void _printreg_##print_fn(void) __attribute__((constructor)); \ |
| static void _printreg_##print_fn(void) { \ |
| printfrr_ext_reg(&_printext_##print_fn); \ |
| } \ |
| |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif |