]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: make "%Ld" work for int64_t
authorDavid Lamparter <equinox@diac24.net>
Wed, 12 Jun 2019 15:08:01 +0000 (17:08 +0200)
committerDavid Lamparter <equinox@diac24.net>
Wed, 12 Jun 2019 17:35:43 +0000 (19:35 +0200)
... without compiler plugins.

Signed-off-by: David Lamparter <equinox@diac24.net>
isisd/isis_misc.h
lib/compiler.h
lib/log.h
lib/sbuf.h
lib/termtable.h
lib/vty.h
lib/zebra.h
tests/lib/test_printfrr.c

index c551fde7d1358a53ff77bd98a27dad9ac1d97e03..fbfabaf24f40726c6bbaf252e8ca2089170cb584 100644 (file)
@@ -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
index 9ce91e3361aac6fe00e865bd09779ab9c1149683..218100417cb3789b543493f94c4c8dbe16dc7690 100644 (file)
@@ -218,6 +218,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
index 3ef4d2f379fa11d632c393643098aa6b6e34a335..c5ae6fe32f295cb52cccd7f3db1f062bb60cfff1 100644 (file)
--- a/lib/log.h
+++ b/lib/log.h
@@ -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, ...)                                        \
index b1518a3aa8de3538f93de0ac7f3f35d217b2cf9d..9f0311006d11c134fa1d5ce99c9a36c7429765e5 100644 (file)
@@ -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
 }
index 491010a856faca54efc381bf07c1fc36f6b7f8cc..4f7c595ce2f7eb7432d02cece7cf4d46711f2540 100644 (file)
@@ -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.
  *
@@ -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.
index 035e75802481da3a74604a831a8e0973dfe8a233..c7352efbd32c67f503bc62559c7a6f8faff67db1 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -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);
 
index 2f9ada09beb7c5665fedc7a5afc37cdf1e2a494c..51b4849f597d261f8693d80090e75cd7934adc5e 100644 (file)
@@ -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
index c8ef150b07bc03564da3b042e07d7f4730018699..24de3fa88d0d88720d7a8dedb7dda11babee1b1e 100644 (file)
@@ -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;
@@ -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;