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 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 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 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