diff options
-rw-r--r-- | listen/listen.c | 32 | ||||
-rw-r--r-- | listen/listen.h | 20 |
2 files changed, 46 insertions, 6 deletions
diff --git a/listen/listen.c b/listen/listen.c index 2b05f8b..0b33fb2 100644 --- a/listen/listen.c +++ b/listen/listen.c @@ -47,13 +47,33 @@ static void display_port(char *dev) /* * Format the timestamp */ -static char * ts_format(register int sec, register int usec) +static char * ts_format(unsigned int sec, unsigned int usec) { - static char buf[sizeof("00:00:00.000000")]; - (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u", - sec / 3600, (sec % 3600) / 60, sec % 60, usec); - - return buf; + static char buf[sizeof("00:00:00.000000")]; + unsigned int hours, minutes, seconds; + + hours = sec / 3600; + minutes = (sec % 3600) / 60; + seconds = sec % 60; + + /* + * The real purpose of these checks is to let GCC figure out the + * value range of all variables thus avoid bogus warnings. For any + * halfway modern GCC the checks will be optimized away. + */ + if (hours >= 60) + unreachable(); + if (minutes >= 60) + unreachable(); + if (seconds >= 60) + unreachable(); + if (usec >= 1000000) + unreachable(); + + snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u", + hours, minutes, seconds, usec); + + return buf; } /* diff --git a/listen/listen.h b/listen/listen.h index 0075bf3..46ec397 100644 --- a/listen/listen.h +++ b/listen/listen.h @@ -1,3 +1,23 @@ +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if GCC_VERSION >= 40500 + +/* + * Mark a position in code as unreachable. This can be used to + * suppress control flow warnings after asm blocks that transfer + * control elsewhere. + * + * Early snapshots of gcc 4.5 don't support this and we can't detect + * this in the preprocessor, but we can live with this because they're + * unreleased. + */ +#define unreachable() \ + do { __builtin_unreachable(); } while (0) +#else +#define unreachable() do { } while (1) +#endif #define T_ERROR 1 #define T_PORT 2 |