diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/cerr.c | 73 | ||||
-rw-r--r-- | src/common/cerr.h | 19 |
2 files changed, 92 insertions, 0 deletions
diff --git a/src/common/cerr.c b/src/common/cerr.c new file mode 100644 index 0000000..0032795 --- /dev/null +++ b/src/common/cerr.c @@ -0,0 +1,73 @@ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "cerr.h" + +#define SGR_BOLD "\33[1m" +#define SGR_DONE "\33[0m" + +static bool color; +static const char *progname; + +void +cerrinit(const char *s) +{ + const char *p = strrchr(s, '/'); + progname = p ? p + 1 : s; + + if (isatty(STDOUT_FILENO)) { + const char *ev = getenv("NO_COLOR"); + if (!ev || !*ev) + color = true; + } +} + +void +die(const char *fmt, ...) +{ + va_list ap; + int e = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s%s:%s ", color ? SGR_BOLD : "", progname, + color ? SGR_DONE : ""); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": %s\n", strerror(e)); + va_end(ap); + + exit(EXIT_FAILURE); +} + +void +diex(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s%s:%s ", color ? SGR_BOLD : "", progname, + color ? SGR_DONE : ""); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); + + exit(EXIT_FAILURE); +} + +void +die_with_off(const char *file, size_t off, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s%s:%s:%zu:%s ", color ? SGR_BOLD : "", progname, file, + off, color ? SGR_DONE : ""); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); + + exit(EXIT_FAILURE); +} diff --git a/src/common/cerr.h b/src/common/cerr.h new file mode 100644 index 0000000..de58b1d --- /dev/null +++ b/src/common/cerr.h @@ -0,0 +1,19 @@ +#ifndef AHOY_COMMON_CERR_H +#define AHOY_COMMON_CERR_H + +#include <stddef.h> + +/* clang-format off */ + +[[gnu::nonnull]] void cerrinit(const char *); + +[[noreturn, gnu::nonnull, gnu::format(printf, 1, 2)]] +void die(const char *, ...); + +[[noreturn, gnu::nonnull, gnu::format(printf, 1, 2)]] +void diex(const char *, ...); + +[[noreturn, gnu::nonnull, gnu::format(printf, 3, 4)]] +void die_with_off(const char *, size_t, const char *, ...); + +#endif /* !AHOY_COMMON_CERR_H */ |