diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index c37c43186e..1a7bc4591c 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -217,6 +217,9 @@ For C programs: . since mid 2017 with 512f41cf, we have been using designated initializers for array (e.g. "int array[10] = { [5] = 2 }"). + . since early 2021 with 765dc168882, we have been using variadic + macros, mostly for printf-like trace and debug macros. + These used to be forbidden, but we have not heard any breakage report, and they are assumed to be safe. diff --git a/banned.h b/banned.h index 7ab4f2e492..6ccf46bc19 100644 --- a/banned.h +++ b/banned.h @@ -21,13 +21,8 @@ #undef sprintf #undef vsprintf -#ifdef HAVE_VARIADIC_MACROS #define sprintf(...) BANNED(sprintf) #define vsprintf(...) BANNED(vsprintf) -#else -#define sprintf(buf,fmt,arg) BANNED(sprintf) -#define vsprintf(buf,fmt,arg) BANNED(vsprintf) -#endif #undef gmtime #define gmtime(t) BANNED(gmtime) diff --git a/git-compat-util.h b/git-compat-util.h index 2d9b75a021..e50e2fafae 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1256,24 +1256,12 @@ static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size, #endif #endif -/* - * This is always defined as a first step towards making the use of variadic - * macros unconditional. If it causes compilation problems on your platform, - * please report it to the Git mailing list at git@vger.kernel.org. - */ -#define HAVE_VARIADIC_MACROS 1 - /* usage.c: only to be used for testing BUG() implementation (see test-tool) */ extern int BUG_exit_code; -#ifdef HAVE_VARIADIC_MACROS __attribute__((format (printf, 3, 4))) NORETURN void BUG_fl(const char *file, int line, const char *fmt, ...); #define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__) -#else -__attribute__((format (printf, 1, 2))) NORETURN -void BUG(const char *fmt, ...); -#endif /* * Preserves errno, prints a message, but gives no warning for ENOENT. diff --git a/trace.c b/trace.c index f726686fd9..794a087c21 100644 --- a/trace.c +++ b/trace.c @@ -108,16 +108,11 @@ static int prepare_trace_line(const char *file, int line, gettimeofday(&tv, NULL); secs = tv.tv_sec; localtime_r(&secs, &tm); - strbuf_addf(buf, "%02d:%02d:%02d.%06ld ", tm.tm_hour, tm.tm_min, - tm.tm_sec, (long) tv.tv_usec); - -#ifdef HAVE_VARIADIC_MACROS - /* print file:line */ - strbuf_addf(buf, "%s:%d ", file, line); + strbuf_addf(buf, "%02d:%02d:%02d.%06ld %s:%d", tm.tm_hour, tm.tm_min, + tm.tm_sec, (long) tv.tv_usec, file, line); /* align trace output (column 40 catches most files names in git) */ while (buf->len < 40) strbuf_addch(buf, ' '); -#endif return 1; } @@ -229,74 +224,6 @@ static void trace_performance_vprintf_fl(const char *file, int line, strbuf_release(&buf); } -#ifndef HAVE_VARIADIC_MACROS - -void trace_printf(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - trace_vprintf_fl(NULL, 0, &trace_default_key, format, ap); - va_end(ap); -} - -void trace_printf_key(struct trace_key *key, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - trace_vprintf_fl(NULL, 0, key, format, ap); - va_end(ap); -} - -void trace_argv_printf(const char **argv, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - trace_argv_vprintf_fl(NULL, 0, argv, format, ap); - va_end(ap); -} - -void trace_strbuf(struct trace_key *key, const struct strbuf *data) -{ - trace_strbuf_fl(NULL, 0, key, data); -} - -void trace_performance(uint64_t nanos, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - trace_performance_vprintf_fl(NULL, 0, nanos, format, ap); - va_end(ap); -} - -void trace_performance_since(uint64_t start, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - trace_performance_vprintf_fl(NULL, 0, getnanotime() - start, - format, ap); - va_end(ap); -} - -void trace_performance_leave(const char *format, ...) -{ - va_list ap; - uint64_t since; - - if (perf_indent) - perf_indent--; - - if (!format) /* Allow callers to leave without tracing anything */ - return; - - since = perf_start_times[perf_indent]; - va_start(ap, format); - trace_performance_vprintf_fl(NULL, 0, getnanotime() - since, - format, ap); - va_end(ap); -} - -#else - void trace_printf_key_fl(const char *file, int line, struct trace_key *key, const char *format, ...) { @@ -342,9 +269,6 @@ void trace_performance_leave_fl(const char *file, int line, va_end(ap); } -#endif /* HAVE_VARIADIC_MACROS */ - - static const char *quote_crnl(const char *path) { static struct strbuf new_path = STRBUF_INIT; diff --git a/trace.h b/trace.h index e25984051a..4e771f86ac 100644 --- a/trace.h +++ b/trace.h @@ -126,71 +126,6 @@ void trace_command_performance(const char **argv); void trace_verbatim(struct trace_key *key, const void *buf, unsigned len); uint64_t trace_performance_enter(void); -#ifndef HAVE_VARIADIC_MACROS - -/** - * Prints a formatted message, similar to printf. - */ -__attribute__((format (printf, 1, 2))) -void trace_printf(const char *format, ...); - -__attribute__((format (printf, 2, 3))) -void trace_printf_key(struct trace_key *key, const char *format, ...); - -/** - * Prints a formatted message, followed by a quoted list of arguments. - */ -__attribute__((format (printf, 2, 3))) -void trace_argv_printf(const char **argv, const char *format, ...); - -/** - * Prints the strbuf, without additional formatting (i.e. doesn't - * choke on `%` or even `\0`). - */ -void trace_strbuf(struct trace_key *key, const struct strbuf *data); - -/** - * Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled. - * - * Example: - * ------------ - * uint64_t t = 0; - * for (;;) { - * // ignore - * t -= getnanotime(); - * // code section to measure - * t += getnanotime(); - * // ignore - * } - * trace_performance(t, "frotz"); - * ------------ - */ -__attribute__((format (printf, 2, 3))) -void trace_performance(uint64_t nanos, const char *format, ...); - -/** - * Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled. - * - * Example: - * ------------ - * uint64_t start = getnanotime(); - * // code section to measure - * trace_performance_since(start, "foobar"); - * ------------ - */ -__attribute__((format (printf, 2, 3))) -void trace_performance_since(uint64_t start, const char *format, ...); - -__attribute__((format (printf, 1, 2))) -void trace_performance_leave(const char *format, ...); - -#else - -/* - * Macros to add file:line - see above for C-style declarations of how these - * should be used. - */ - /* * TRACE_CONTEXT may be set to __FUNCTION__ if the compiler supports it. The * default is __FILE__, as it is consistent with assert(), and static function @@ -204,7 +139,10 @@ void trace_performance_leave(const char *format, ...); # define TRACE_CONTEXT __FILE__ #endif -/* +/** + * Macros to add the file:line of the calling code, instead of that of + * the trace function itself. + * * Note: with C99 variadic macros, __VA_ARGS__ must include the last fixed * parameter ('format' in this case). Otherwise, a call without variable * arguments will have a surplus ','. E.g.: @@ -220,6 +158,16 @@ void trace_performance_leave(const char *format, ...); * comma, but this is non-standard. */ +/** + * trace_printf(), accepts "const char *format, ...". + * + * Prints a formatted message, similar to printf. + */ +#define trace_printf(...) trace_printf_key(&trace_default_key, __VA_ARGS__) + +/** + * trace_printf_key(), accepts "struct trace_key *key, const char *format, ...". + */ #define trace_printf_key(key, ...) \ do { \ if (trace_pass_fl(key)) \ @@ -227,8 +175,11 @@ void trace_performance_leave(const char *format, ...); __VA_ARGS__); \ } while (0) -#define trace_printf(...) trace_printf_key(&trace_default_key, __VA_ARGS__) - +/** + * trace_argv_printf(), accepts "struct trace_key *key, const char *format, ...)". + * + * Prints a formatted message, followed by a quoted list of arguments. + */ #define trace_argv_printf(argv, ...) \ do { \ if (trace_pass_fl(&trace_default_key)) \ @@ -236,12 +187,36 @@ void trace_performance_leave(const char *format, ...); argv, __VA_ARGS__); \ } while (0) +/** + * trace_strbuf(), accepts "struct trace_key *key, const struct strbuf *data". + * + * Prints the strbuf, without additional formatting (i.e. doesn't + * choke on `%` or even `\0`). + */ #define trace_strbuf(key, data) \ do { \ if (trace_pass_fl(key)) \ trace_strbuf_fl(TRACE_CONTEXT, __LINE__, key, data);\ } while (0) +/** + * trace_performance(), accepts "uint64_t nanos, const char *format, ...". + * + * Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled. + * + * Example: + * ------------ + * uint64_t t = 0; + * for (;;) { + * // ignore + * t -= getnanotime(); + * // code section to measure + * t += getnanotime(); + * // ignore + * } + * trace_performance(t, "frotz"); + * ------------ + */ #define trace_performance(nanos, ...) \ do { \ if (trace_pass_fl(&trace_perf_key)) \ @@ -249,6 +224,18 @@ void trace_performance_leave(const char *format, ...); __VA_ARGS__); \ } while (0) +/** + * trace_performance_since(), accepts "uint64_t start, const char *format, ...". + * + * Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled. + * + * Example: + * ------------ + * uint64_t start = getnanotime(); + * // code section to measure + * trace_performance_since(start, "foobar"); + * ------------ + */ #define trace_performance_since(start, ...) \ do { \ if (trace_pass_fl(&trace_perf_key)) \ @@ -257,6 +244,9 @@ void trace_performance_leave(const char *format, ...); __VA_ARGS__); \ } while (0) +/** + * trace_performance_leave(), accepts "const char *format, ...". + */ #define trace_performance_leave(...) \ do { \ if (trace_pass_fl(&trace_perf_key)) \ @@ -285,6 +275,4 @@ static inline int trace_pass_fl(struct trace_key *key) return key->fd || !key->initialized; } -#endif /* HAVE_VARIADIC_MACROS */ - #endif /* TRACE_H */ diff --git a/trace2.c b/trace2.c index b2d471526f..179caa72cf 100644 --- a/trace2.c +++ b/trace2.c @@ -641,20 +641,6 @@ void trace2_region_enter_printf_fl(const char *file, int line, va_end(ap); } -#ifndef HAVE_VARIADIC_MACROS -void trace2_region_enter_printf(const char *category, const char *label, - const struct repository *repo, const char *fmt, - ...) -{ - va_list ap; - - va_start(ap, fmt); - trace2_region_enter_printf_va_fl(NULL, 0, category, label, repo, fmt, - ap); - va_end(ap); -} -#endif - void trace2_region_leave_printf_va_fl(const char *file, int line, const char *category, const char *label, const struct repository *repo, @@ -717,20 +703,6 @@ void trace2_region_leave_printf_fl(const char *file, int line, va_end(ap); } -#ifndef HAVE_VARIADIC_MACROS -void trace2_region_leave_printf(const char *category, const char *label, - const struct repository *repo, const char *fmt, - ...) -{ - va_list ap; - - va_start(ap, fmt); - trace2_region_leave_printf_va_fl(NULL, 0, category, label, repo, fmt, - ap); - va_end(ap); -} -#endif - void trace2_data_string_fl(const char *file, int line, const char *category, const struct repository *repo, const char *key, const char *value) @@ -826,17 +798,6 @@ void trace2_printf_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -#ifndef HAVE_VARIADIC_MACROS -void trace2_printf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - trace2_printf_va_fl(NULL, 0, fmt, ap); - va_end(ap); -} -#endif - const char *trace2_session_id(void) { return tr2_sid_get(); diff --git a/trace2.h b/trace2.h index 0cc7b5f531..1b109f57d0 100644 --- a/trace2.h +++ b/trace2.h @@ -397,18 +397,9 @@ void trace2_region_enter_printf_fl(const char *file, int line, const struct repository *repo, const char *fmt, ...); -#ifdef HAVE_VARIADIC_MACROS #define trace2_region_enter_printf(category, label, repo, ...) \ trace2_region_enter_printf_fl(__FILE__, __LINE__, (category), (label), \ (repo), __VA_ARGS__) -#else -/* clang-format off */ -__attribute__((format (region_enter_printf, 4, 5))) -void trace2_region_enter_printf(const char *category, const char *label, - const struct repository *repo, const char *fmt, - ...); -/* clang-format on */ -#endif /** * Emit a 'region_leave' event for .