usage.con commit cherry-pick: handle root commits with external strategies (1618073)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "git-compat-util.h"
   7
   8void vreportf(const char *prefix, const char *err, va_list params)
   9{
  10        char msg[4096];
  11        vsnprintf(msg, sizeof(msg), err, params);
  12        fprintf(stderr, "%s%s\n", prefix, msg);
  13}
  14
  15static NORETURN void usage_builtin(const char *err, va_list params)
  16{
  17        vreportf("usage: ", err, params);
  18        exit(129);
  19}
  20
  21static NORETURN void die_builtin(const char *err, va_list params)
  22{
  23        vreportf("fatal: ", err, params);
  24        exit(128);
  25}
  26
  27static void error_builtin(const char *err, va_list params)
  28{
  29        vreportf("error: ", err, params);
  30}
  31
  32static void warn_builtin(const char *warn, va_list params)
  33{
  34        vreportf("warning: ", warn, params);
  35}
  36
  37/* If we are in a dlopen()ed .so write to a global variable would segfault
  38 * (ugh), so keep things static. */
  39static NORETURN_PTR void (*usage_routine)(const char *err, va_list params) = usage_builtin;
  40static NORETURN_PTR void (*die_routine)(const char *err, va_list params) = die_builtin;
  41static void (*error_routine)(const char *err, va_list params) = error_builtin;
  42static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
  43
  44void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params))
  45{
  46        die_routine = routine;
  47}
  48
  49void NORETURN usagef(const char *err, ...)
  50{
  51        va_list params;
  52
  53        va_start(params, err);
  54        usage_routine(err, params);
  55        va_end(params);
  56}
  57
  58void NORETURN usage(const char *err)
  59{
  60        usagef("%s", err);
  61}
  62
  63void NORETURN die(const char *err, ...)
  64{
  65        va_list params;
  66
  67        va_start(params, err);
  68        die_routine(err, params);
  69        va_end(params);
  70}
  71
  72void NORETURN die_errno(const char *fmt, ...)
  73{
  74        va_list params;
  75        char fmt_with_err[1024];
  76        char str_error[256], *err;
  77        int i, j;
  78
  79        err = strerror(errno);
  80        for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) {
  81                if ((str_error[j++] = err[i++]) != '%')
  82                        continue;
  83                if (j < sizeof(str_error) - 1) {
  84                        str_error[j++] = '%';
  85                } else {
  86                        /* No room to double the '%', so we overwrite it with
  87                         * '\0' below */
  88                        j--;
  89                        break;
  90                }
  91        }
  92        str_error[j] = 0;
  93        snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, str_error);
  94
  95        va_start(params, fmt);
  96        die_routine(fmt_with_err, params);
  97        va_end(params);
  98}
  99
 100int error(const char *err, ...)
 101{
 102        va_list params;
 103
 104        va_start(params, err);
 105        error_routine(err, params);
 106        va_end(params);
 107        return -1;
 108}
 109
 110void warning(const char *warn, ...)
 111{
 112        va_list params;
 113
 114        va_start(params, warn);
 115        warn_routine(warn, params);
 116        va_end(params);
 117}