diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2015-06-05 15:58:00 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-06-25 16:48:39 +0200 |
commit | 99d303ac2739e65a02fbbc325b74ad6fcac63cc2 (patch) | |
tree | 6f4095f42d3d298cdd5ab8bc6f8ed89d9673b38b /src/tools/terminal.c | |
download | wireguard-monolithic-historical-99d303ac2739e65a02fbbc325b74ad6fcac63cc2.tar.xz wireguard-monolithic-historical-99d303ac2739e65a02fbbc325b74ad6fcac63cc2.zip |
Initial commit
Diffstat (limited to 'src/tools/terminal.c')
-rw-r--r-- | src/tools/terminal.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/tools/terminal.c b/src/tools/terminal.c new file mode 100644 index 0000000..74d04c2 --- /dev/null +++ b/src/tools/terminal.c @@ -0,0 +1,79 @@ +/* Copyright 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ + +#define _GNU_SOURCE +#include <ctype.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> + +static bool color_mode(FILE *file) +{ + static int mode = -1; + char *var; + if (mode != -1) + return mode; + var = getenv("WG_COLOR_MODE"); + if (var && !strcmp(var, "always")) + mode = true; + else if (var && !strcmp(var, "never")) + mode = false; + else + return isatty(fileno(file)); + return mode; +} + +static void filter_ansi(FILE *file, const char *fmt, va_list args) +{ + char *str = NULL; + size_t len, i, j; + + if (color_mode(file)) { + vfprintf(file, fmt, args); + return; + } + + len = vasprintf(&str, fmt, args); + + if (len >= 2) { + for (i = 0; i < len - 2; ++i) { + if (str[i] == '\x1b' && str[i + 1] == '[') { + str[i] = str[i + 1] = '\0'; + for (j = i + 2; j < len; ++j) { + if (isalpha(str[j])) + break; + str[j] = '\0'; + } + str[j] = '\0'; + } + } + } + for (i = 0; i < len; i = j) { + fputs(&str[i], file); + for (j = i + strlen(&str[i]); j < len; ++j) { + if (str[j] != '\0') + break; + } + } + + free(str); +} + +void terminal_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + filter_ansi(stdout, fmt, args); + va_end(args); +} + +void terminal_fprintf(FILE *file, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + filter_ansi(file, fmt, args); + va_end(args); +} |