Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>2022-06-02 15:25:33 +0300
committerJunio C Hamano <gitster@pobox.com>2022-06-02 22:51:35 +0300
commit0cc05b044fd690f37565262a5b09f60c203c5218 (patch)
tree30682a4f70be5dc2665554dd0f840d6df4ba0e99 /usage.c
parent19d75948ef7abe9066efa4462108827d70565ae9 (diff)
usage.c: add a non-fatal bug() function to go with BUG()
Add a bug() function to use in cases where we'd like to indicate a runtime BUG(), but would like to defer the BUG() call because we're possibly accumulating more bug() callers to exhaustively indicate what went wrong. We already have this sort of facility in various parts of the codebase, just in the form of ad-hoc re-inventions of the functionality that this new API provides. E.g. this will be used to replace optbug() in parse-options.c, and the 'error("BUG:[...]' we do in a loop in builtin/receive-pack.c. Unlike the code this replaces we'll log to trace2 with this new bug() function (as with other usage.c functions, including BUG()), we'll also be able to avoid calls to xstrfmt() in some cases, as the bug() function itself accepts variadic sprintf()-like arguments. Any caller to bug() can follow up such calls with BUG_if_bug(), which will BUG() out (i.e. abort()) if there were any preceding calls to bug(), callers can also decide not to call BUG_if_bug() and leave the resulting BUG() invocation until exit() time. There are currently no bug() API users that don't call BUG_if_bug() themselves after a for-loop, but allowing for not calling BUG_if_bug() keeps the API flexible. As the tests and documentation here show we'll catch missing BUG_if_bug() invocations in our exit() wrapper. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'usage.c')
-rw-r--r--usage.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/usage.c b/usage.c
index b738dd178b..79900d0287 100644
--- a/usage.c
+++ b/usage.c
@@ -290,18 +290,24 @@ void warning(const char *warn, ...)
/* Only set this, ever, from t/helper/, when verifying that bugs are caught. */
int BUG_exit_code;
-static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params)
+static void BUG_vfl_common(const char *file, int line, const char *fmt,
+ va_list params)
{
char prefix[256];
- va_list params_copy;
- static int in_bug;
-
- va_copy(params_copy, params);
/* truncation via snprintf is OK here */
snprintf(prefix, sizeof(prefix), "BUG: %s:%d: ", file, line);
vreportf(prefix, fmt, params);
+}
+
+static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params)
+{
+ va_list params_copy;
+ static int in_bug;
+
+ va_copy(params_copy, params);
+ BUG_vfl_common(file, line, fmt, params);
if (in_bug)
abort();
@@ -317,11 +323,28 @@ static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_lis
NORETURN void BUG_fl(const char *file, int line, const char *fmt, ...)
{
va_list ap;
+
+ bug_called_must_BUG = 0;
+
va_start(ap, fmt);
BUG_vfl(file, line, fmt, ap);
va_end(ap);
}
+int bug_called_must_BUG;
+void bug_fl(const char *file, int line, const char *fmt, ...)
+{
+ va_list ap, cp;
+
+ bug_called_must_BUG = 1;
+
+ va_copy(cp, ap);
+ va_start(ap, fmt);
+ BUG_vfl_common(file, line, fmt, ap);
+ va_end(ap);
+ trace2_cmd_error_va(fmt, cp);
+}
+
#ifdef SUPPRESS_ANNOTATED_LEAKS
void unleak_memory(const void *ptr, size_t len)
{