usage.con commit fixup tr/stash-format merge (5f809ff)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "git-compat-util.h"
   7
   8static void report(const char *prefix, const char *err, va_list params)
   9{
  10        char msg[1024];
  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)
  16{
  17        fprintf(stderr, "usage: %s\n", err);
  18        exit(129);
  19}
  20
  21static NORETURN void die_builtin(const char *err, va_list params)
  22{
  23        report("fatal: ", err, params);
  24        exit(128);
  25}
  26
  27static void error_builtin(const char *err, va_list params)
  28{
  29        report("error: ", err, params);
  30}
  31
  32static void warn_builtin(const char *warn, va_list params)
  33{
  34        report("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) = 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 usage(const char *err)
  50{
  51        usage_routine(err);
  52}
  53
  54void die(const char *err, ...)
  55{
  56        va_list params;
  57
  58        va_start(params, err);
  59        die_routine(err, params);
  60        va_end(params);
  61}
  62
  63void die_errno(const char *fmt, ...)
  64{
  65        va_list params;
  66        char fmt_with_err[1024];
  67        char str_error[256], *err;
  68        int i, j;
  69
  70        err = strerror(errno);
  71        for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) {
  72                if ((str_error[j++] = err[i++]) != '%')
  73                        continue;
  74                if (j < sizeof(str_error) - 1) {
  75                        str_error[j++] = '%';
  76                } else {
  77                        /* No room to double the '%', so we overwrite it with
  78                         * '\0' below */
  79                        j--;
  80                        break;
  81                }
  82        }
  83        str_error[j] = 0;
  84        snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, str_error);
  85
  86        va_start(params, fmt);
  87        die_routine(fmt_with_err, params);
  88        va_end(params);
  89}
  90
  91int error(const char *err, ...)
  92{
  93        va_list params;
  94
  95        va_start(params, err);
  96        error_routine(err, params);
  97        va_end(params);
  98        return -1;
  99}
 100
 101void warning(const char *warn, ...)
 102{
 103        va_list params;
 104
 105        va_start(params, warn);
 106        warn_routine(warn, params);
 107        va_end(params);
 108}