Skip to content

Commit

Permalink
Merge pull request FRRouting#4509 from opensourcerouting/spanish-intq…
Browse files Browse the repository at this point in the history
…uisition

lib: make printfrr int64_t usable
  • Loading branch information
qlyoung authored Jun 13, 2019
2 parents 6a81b60 + 39c94f8 commit 096873b
Show file tree
Hide file tree
Showing 15 changed files with 134 additions and 93 deletions.
4 changes: 1 addition & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,7 @@ else
fi
if test "z$orig_cflags" = "z"; then
AC_C_FLAG([-g])
AC_C_FLAG([-Os], [
AC_C_FLAG([-O2])
])
AC_C_FLAG([-O2])
fi
fi
AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"])
Expand Down
42 changes: 9 additions & 33 deletions isisd/isis_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <zebra.h>

#include "printfrr.h"
#include "stream.h"
#include "vty.h"
#include "hash.h"
Expand Down Expand Up @@ -511,42 +512,14 @@ void zlog_dump_data(void *data, int len)
return;
}

static char *qasprintf(const char *format, va_list ap)
{
va_list aq;
va_copy(aq, ap);

int size = 0;
char *p = NULL;

size = vsnprintf(p, size, format, ap);

if (size < 0) {
va_end(aq);
return NULL;
}

size++;
p = XMALLOC(MTYPE_TMP, size);

size = vsnprintf(p, size, format, aq);
va_end(aq);

if (size < 0) {
XFREE(MTYPE_TMP, p);
return NULL;
}

return p;
}

void log_multiline(int priority, const char *prefix, const char *format, ...)
{
char shortbuf[256];
va_list ap;
char *p;

va_start(ap, format);
p = qasprintf(format, ap);
p = asnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap);
va_end(ap);

if (!p)
Expand All @@ -558,16 +531,18 @@ void log_multiline(int priority, const char *prefix, const char *format, ...)
zlog(priority, "%s%s", prefix, line);
}

XFREE(MTYPE_TMP, p);
if (p != shortbuf)
XFREE(MTYPE_TMP, p);
}

void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...)
{
char shortbuf[256];
va_list ap;
char *p;

va_start(ap, format);
p = qasprintf(format, ap);
p = asnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap);
va_end(ap);

if (!p)
Expand All @@ -579,7 +554,8 @@ void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...)
vty_out(vty, "%s%s\n", prefix, line);
}

XFREE(MTYPE_TMP, p);
if (p != shortbuf)
XFREE(MTYPE_TMP, p);
}

void vty_out_timestr(struct vty *vty, time_t uptime)
Expand Down
4 changes: 2 additions & 2 deletions isisd/isis_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ enum { ISIS_UI_LEVEL_BRIEF,

#include "lib/log.h"
void log_multiline(int priority, const char *prefix, const char *format, ...)
PRINTF_ATTRIBUTE(3, 4);
PRINTFRR(3, 4);
struct vty;
void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...)
PRINTF_ATTRIBUTE(3, 4);
PRINTFRR(3, 4);
void vty_out_timestr(struct vty *vty, time_t uptime);
#endif
62 changes: 62 additions & 0 deletions lib/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,68 @@ extern "C" {

#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))

/* sigh. this is so ugly, it overflows and wraps to being nice again.
*
* printfrr() supports "%Ld" for <int64_t>, whatever that is typedef'd to.
* However, gcc & clang think that "%Ld" is <long long>, which doesn't quite
* match up since int64_t is <long> on a lot of 64-bit systems.
*
* If we have _FRR_ATTRIBUTE_PRINTFRR, we loaded a compiler plugin that
* replaces the whole format checking bits with a custom version that
* understands "%Ld" (along with "%pI4" and co.), so we don't need to do
* anything.
*
* If we don't have that attribute... we still want -Wformat to work. So,
* this is the "f*ck it" approach and we just redefine int64_t to always be
* <long long>. This should work until such a time that <long long> is
* something else (e.g. 128-bit integer)... let's just guard against that
* with the _Static_assert below and work with the world we have right now,
* where <long long> is always 64-bit.
*/

/* these need to be included before any of the following, so we can
* "overwrite" things.
*/
#include <stdint.h>
#include <inttypes.h>

#ifdef _FRR_ATTRIBUTE_PRINTFRR
#define PRINTFRR(a, b) __attribute__((printfrr(a, b)))

#else /* !_FRR_ATTRIBUTE_PRINTFRR */
#define PRINTFRR(a, b) __attribute__((format(printf, a, b)))

/* these should be typedefs, but might also be #define */
#ifdef uint64_t
#undef uint64_t
#endif
#ifdef int64_t
#undef int64_t
#endif

/* can't overwrite the typedef, but we can replace int64_t with _int64_t */
typedef unsigned long long _uint64_t;
#define uint64_t _uint64_t
typedef signed long long _int64_t;
#define int64_t _int64_t

/* if this breaks, 128-bit machines may have entered reality (or <long long>
* is something weird)
*/
#if __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
"nobody expects the spanish intquisition");
#endif

/* since we redefined int64_t, we also need to redefine PRI*64 */
#undef PRIu64
#undef PRId64
#undef PRIx64
#define PRIu64 "llu"
#define PRId64 "lld"
#define PRIx64 "llx"
#endif /* !_FRR_ATTRIBUTE_PRINTFRR */

#ifdef __cplusplus
}
#endif
Expand Down
19 changes: 6 additions & 13 deletions lib/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,13 @@ extern void openzlog(const char *progname, const char *protoname,
/* Close zlog function. */
extern void closezlog(void);

/* GCC have printf type attribute check. */
#ifdef __GNUC__
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#else
#define PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */

/* Handy zlog functions. */
extern void zlog_err(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
extern void zlog_warn(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
extern void zlog_info(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
extern void zlog_notice(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
extern void zlog_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
extern void zlog(int priority, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
extern void zlog_err(const char *format, ...) PRINTFRR(1, 2);
extern void zlog_warn(const char *format, ...) PRINTFRR(1, 2);
extern void zlog_info(const char *format, ...) PRINTFRR(1, 2);
extern void zlog_notice(const char *format, ...) PRINTFRR(1, 2);
extern void zlog_debug(const char *format, ...) PRINTFRR(1, 2);
extern void zlog(int priority, const char *format, ...) PRINTFRR(2, 3);

/* For logs which have error codes associated with them */
#define flog_err(ferr_id, format, ...) \
Expand Down
7 changes: 4 additions & 3 deletions lib/sbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/
#include <zebra.h>

#include "printfrr.h"
#include "sbuf.h"
#include "memory.h"

Expand Down Expand Up @@ -68,7 +69,7 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)

written1 = indent;
va_start(args, format);
written2 = vsnprintf(NULL, 0, format, args);
written2 = vsnprintfrr(NULL, 0, format, args);
va_end(args);

new_size = buf->size;
Expand All @@ -92,8 +93,8 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
buf->pos = buf->size;

va_start(args, format);
written = vsnprintf(buf->buf + buf->pos, buf->size - buf->pos, format,
args);
written = vsnprintfrr(buf->buf + buf->pos, buf->size - buf->pos,
format, args);
va_end(args);

if (written >= 0)
Expand Down
2 changes: 1 addition & 1 deletion lib/sbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const char *sbuf_buf(struct sbuf *buf);
void sbuf_free(struct sbuf *buf);
#include "lib/log.h"
void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
PRINTF_ATTRIBUTE(3, 4);
PRINTFRR(3, 4);

#ifdef __cplusplus
}
Expand Down
9 changes: 5 additions & 4 deletions lib/termtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <zebra.h>
#include <stdio.h>

#include "printfrr.h"
#include "memory.h"
#include "termtable.h"

Expand Down Expand Up @@ -134,6 +135,7 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i,
{
assert(i >= -1 && i < tt->nrows);

char shortbuf[256];
char *res, *orig, *section;
struct ttable_cell *row;
int col = 0;
Expand All @@ -158,9 +160,7 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i,
/* CALLOC a block of cells */
row = XCALLOC(MTYPE_TTABLE, tt->ncols * sizeof(struct ttable_cell));

res = NULL;
vasprintf(&res, format, ap);

res = vasnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap);
orig = res;

while (res && col < tt->ncols) {
Expand All @@ -170,7 +170,8 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i,
col++;
}

free(orig);
if (orig != shortbuf)
XFREE(MTYPE_TMP, orig);

/* insert row */
if (i == -1 || i == tt->nrows)
Expand Down
5 changes: 2 additions & 3 deletions lib/termtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ void ttable_cell_del(struct ttable_cell *cell);
* columns were specified
*/
struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row,
const char *format, ...)
PRINTF_ATTRIBUTE(3, 4);
const char *format, ...) PRINTFRR(3, 4);
/**
* Inserts a new row at the end of the table.
*
Expand All @@ -164,7 +163,7 @@ struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row,
* columns were specified
*/
struct ttable_cell *ttable_add_row(struct ttable *tt, const char *format, ...)
PRINTF_ATTRIBUTE(2, 3);
PRINTFRR(2, 3);

/**
* Removes a row from the table.
Expand Down
4 changes: 2 additions & 2 deletions lib/vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ void vty_frame(struct vty *vty, const char *format, ...)
va_list args;

va_start(args, format);
vsnprintf(vty->frame + vty->frame_pos,
sizeof(vty->frame) - vty->frame_pos, format, args);
vsnprintfrr(vty->frame + vty->frame_pos,
sizeof(vty->frame) - vty->frame_pos, format, args);
vty->frame_pos = strlen(vty->frame);
va_end(args);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ extern struct vty *vty_stdio(void (*atclose)(int isexit));
* - vty_endframe() clears the buffer without printing it, and prints an
* extra string if the buffer was empty before (for context-end markers)
*/
extern int vty_out(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
extern void vty_frame(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
extern int vty_out(struct vty *, const char *, ...) PRINTFRR(2, 3);
extern void vty_frame(struct vty *, const char *, ...) PRINTFRR(2, 3);
extern void vty_endframe(struct vty *, const char *);
bool vty_set_include(struct vty *vty, const char *regexp);

Expand Down
7 changes: 0 additions & 7 deletions lib/zebra.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,6 @@ size_t strlcpy(char *__restrict dest,
const char *__restrict src, size_t destsize);
#endif

/* GCC have printf type attribute check. */
#ifdef __GNUC__
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#else
#define PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */

/*
* RFC 3542 defines several macros for using struct cmsghdr.
* Here, we define those that are not present
Expand Down
2 changes: 2 additions & 0 deletions tests/lib/test_printfrr.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

static int errors;

static void printcmp(const char *fmt, ...) PRINTFRR(1, 2);
static void printcmp(const char *fmt, ...)
{
va_list ap;
Expand Down Expand Up @@ -58,6 +59,7 @@ static void printcmp(const char *fmt, ...)
errors++;
}

static void printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3);
static void printchk(const char *ref, const char *fmt, ...)
{
va_list ap;
Expand Down
36 changes: 36 additions & 0 deletions tools/frr.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
" settings & syntax hilighting for FRR codebase
" 2019 by David Lamparter, placed in public domain

let c_gnu=1

function! CStyleFRR()
syn clear cFormat
syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbiuoxXDOUfFeEgGcCsSn]\|[pd]\([A-Z][A-Z0-9]*[a-z]*\|\)\|\[\^\=.[^]]*\]\)" contained
syn match cFormat display "%%" contained

syn keyword cIterator frr_each frr_each_safe frr_each_from
syn keyword cMacroOp offsetof container_of container_of_null array_size

syn keyword cStorageClass atomic
syn keyword cFormatConst PRId64 PRIu64 PRIx64
syn keyword cFormatConst PRId32 PRIu32 PRIx32
syn keyword cFormatConst PRId16 PRIu16 PRIx16
syn keyword cFormatConst PRId8 PRIu8 PRIx8

" you can unlink these by just giving them their own hilighting / color
hi link cFormatConst cFormat
hi link cIterator cRepeat
hi link cMacroOp cOperator

" indentation
setlocal cindent
setlocal cinoptions=:0,(0,u4,w1,W8
setlocal shiftwidth=8
setlocal softtabstop=0
setlocal textwidth=0
setlocal fo=croql
setlocal noet
endfunction

" auto-apply the above based on path rules
"autocmd BufRead,BufNewFile /home/.../frr/*.[ch] call CStyleFRR()
Loading

0 comments on commit 096873b

Please sign in to comment.