[PATCH v9 1/4] usage: make error functions a stack
From: Jacob Keller <jacob.e.keller@intel.com>
Date: 2016-06-15 23:01:56
Subsystem:
the rest · Maintainer:
Linus Torvalds
Rename set_error_routine to be push_error_routine, and add a new pop_error_routine. This allows temporary modifications of the error routine over a small block of code. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> --- Renamed set_error_routine to push_error_routine in order to match the pop_error_routine. git-compat-util.h | 3 ++- run-command.c | 2 +- usage.c | 32 ++++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index 9de318071083..b650e3cb6cdc 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h@@ -343,7 +343,8 @@ static inline int const_error(void) #endif extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); -extern void set_error_routine(void (*routine)(const char *err, va_list params)); +extern void push_error_routine(void (*routine)(const char *err, va_list params)); +extern void pop_error_routine(void); extern void set_die_is_recursing_routine(int (*routine)(void)); extern int starts_with(const char *str, const char *prefix);
diff --git a/run-command.c b/run-command.c
index be07d4ad335b..a611b819c25d 100644
--- a/run-command.c
+++ b/run-command.c@@ -360,7 +360,7 @@ fail_pipe: set_cloexec(child_err); } set_die_routine(die_child); - set_error_routine(error_child); + push_error_routine(error_child); close(notify_pipe[0]); set_cloexec(notify_pipe[1]);
diff --git a/usage.c b/usage.c
index ed146453cabe..3fe26771f7e6 100644
--- a/usage.c
+++ b/usage.c@@ -57,18 +57,42 @@ static int die_is_recursing_builtin(void) * (ugh), so keep things static. */ static NORETURN_PTR void (*usage_routine)(const char *err, va_list params) = usage_builtin; static NORETURN_PTR void (*die_routine)(const char *err, va_list params) = die_builtin; -static void (*error_routine)(const char *err, va_list params) = error_builtin; static void (*warn_routine)(const char *err, va_list params) = warn_builtin; static int (*die_is_recursing)(void) = die_is_recursing_builtin; +struct error_func_list { + void (*func)(const char *, va_list); + struct error_func_list *next; +}; +static struct error_func_list default_error_func = { error_builtin }; +static struct error_func_list *error_funcs = &default_error_func; + void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)) { die_routine = routine; } -void set_error_routine(void (*routine)(const char *err, va_list params)) +/* push error routine onto the error function stack */ +void push_error_routine(void (*routine)(const char *err, va_list params)) { - error_routine = routine; + struct error_func_list *efl = xmalloc(sizeof(*efl)); + efl->func = routine; + efl->next = error_funcs; + error_funcs = efl; +} + +/* pop a single error routine off of the error function stack, thus reverting + * to previous error. Should always be paired with a push_error_routine */ +void pop_error_routine(void) +{ + struct error_func_list *efl = error_funcs; + + assert(error_funcs != &default_error_func); + + if (efl->next) { + error_funcs = efl->next; + free(efl); + } } void set_die_is_recursing_routine(int (*routine)(void))
@@ -144,7 +168,7 @@ int error(const char *err, ...) va_list params; va_start(params, err); - error_routine(err, params); + error_funcs->func(err, params); va_end(params); return -1; }
--
2.0.1.475.g9b8d714