diff --git a/git-compat-util.h b/git-compat-util.h index 4bb59b3101..e9629b2a9d 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -463,6 +463,21 @@ void set_warn_routine(report_fn routine); report_fn get_warn_routine(void); void set_die_is_recursing_routine(int (*routine)(void)); +/* + * Check that an out-parameter that is "at least as const as" a matching + * in-parameter. For example, skip_prefix() will return "out" that is a subset + * of "str". So: + * + * const str, const out: ok + * non-const str, const out: ok + * non-const str, non-const out: ok + * const str, non-const out: compile error + * + * See the skip_prefix macro below for an example of use. + */ +#define CONST_OUTPARAM(in, out) \ + ((const char **)(0 ? ((*(out) = (in)),(out)) : (out))) + /* * If the string "str" begins with the string found in "prefix", return true. * The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in @@ -479,8 +494,10 @@ void set_die_is_recursing_routine(int (*routine)(void)); * [skip prefix if present, otherwise use whole string] * skip_prefix(name, "refs/heads/", &name); */ -static inline bool skip_prefix(const char *str, const char *prefix, - const char **out) +#define skip_prefix(str, prefix, out) \ + skip_prefix_impl((str), (prefix), CONST_OUTPARAM((str), (out))) +static inline bool skip_prefix_impl(const char *str, const char *prefix, + const char **out) { do { if (!*prefix) {