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
16static 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
33static 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
69void 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