1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3 * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4 */
5
6 #include <stdarg.h>
7 #include <stddef.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdbool.h>
12 #include <unistd.h>
13 #include "ctype.h"
14 #include "terminal.h"
15
color_mode(void)16 static bool color_mode(void)
17 {
18 static int mode = -1;
19 const char *var;
20
21 if (mode != -1)
22 return mode;
23 var = getenv("WG_COLOR_MODE");
24 if (var && !strcmp(var, "always"))
25 mode = true;
26 else if (var && !strcmp(var, "never"))
27 mode = false;
28 else
29 mode = isatty(fileno(stdout));
30 return mode;
31 }
32
filter_ansi(const char * fmt,va_list args)33 static void filter_ansi(const char *fmt, va_list args)
34 {
35 char *str = NULL;
36 size_t len, i, j;
37
38 if (color_mode()) {
39 vfprintf(stdout, fmt, args);
40 return;
41 }
42
43 len = vasprintf(&str, fmt, args);
44
45 if (len >= 2) {
46 for (i = 0; i < len - 2; ++i) {
47 if (str[i] == '\x1b' && str[i + 1] == '[') {
48 str[i] = str[i + 1] = '\0';
49 for (j = i + 2; j < len; ++j) {
50 if (char_is_alpha(str[j]))
51 break;
52 str[j] = '\0';
53 }
54 str[j] = '\0';
55 }
56 }
57 }
58 for (i = 0; i < len; i = j) {
59 fputs(&str[i], stdout);
60 for (j = i + strlen(&str[i]); j < len; ++j) {
61 if (str[j] != '\0')
62 break;
63 }
64 }
65
66 free(str);
67 }
68
terminal_printf(const char * fmt,...)69 void terminal_printf(const char *fmt, ...)
70 {
71 va_list args;
72
73 va_start(args, fmt);
74 filter_ansi(fmt, args);
75 va_end(args);
76 }
77