aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/terminal.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2015-06-05 15:58:00 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2016-06-25 16:48:39 +0200
commit99d303ac2739e65a02fbbc325b74ad6fcac63cc2 (patch)
tree6f4095f42d3d298cdd5ab8bc6f8ed89d9673b38b /src/tools/terminal.c
downloadwireguard-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.c79
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);
+}