1 /*
2  * Copyright (c) 2017 Oticon A/S
3  * Copyright (c) 2023 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stdlib.h>
9 #include <stdio.h>  /* for printfs */
10 #include <stdarg.h> /* for va args */
11 #include <unistd.h>
12 #include "nsi_tasks.h"
13 #include "nsi_cmdline.h"
14 #include "nsi_tracing.h"
15 #include "nsi_main.h"
16 
17 /**
18  * Are stdout and stderr connected to a tty
19  * 0  = no
20  * 1  = yes
21  * -1 = we do not know yet
22  * Indexed 0:stdout, 1:stderr
23  */
24 static int is_a_tty[2] = {-1, -1};
25 
26 #define ST_OUT 0
27 #define ST_ERR 1
28 
decide_about_color(void)29 static void decide_about_color(void)
30 {
31 	if (is_a_tty[0] == -1) {
32 		is_a_tty[0] = isatty(STDOUT_FILENO);
33 	}
34 	if (is_a_tty[1] == -1) {
35 		is_a_tty[1] = isatty(STDERR_FILENO);
36 	}
37 }
38 
39 #define ERROR 0
40 #define WARN 1
41 #define TRACE 2
42 
43 static const char * const trace_type_esc_start[] = {
44 	"\x1b[1;31m", /* ERROR   - Foreground color = red, bold */
45 	"\x1b[95m",   /* WARNING - Foreground color = magenta */
46 	"\x1b[0;39m", /* TRACE   - reset all styles */
47 };
48 
49 static const char trace_esc_end[] = "\x1b[0;39m"; /* Reset all styles */
50 
nsi_vprint_warning(const char * format,va_list vargs)51 void nsi_vprint_warning(const char *format, va_list vargs)
52 {
53 	if (is_a_tty[ST_ERR] == -1) {
54 		decide_about_color();
55 	}
56 	if (is_a_tty[ST_ERR]) {
57 		fprintf(stderr, "%s", trace_type_esc_start[WARN]);
58 	}
59 
60 	vfprintf(stderr, format, vargs);
61 
62 	if (is_a_tty[ST_ERR]) {
63 		fprintf(stderr, "%s", trace_esc_end);
64 	}
65 }
66 
nsi_vprint_error_and_exit(const char * format,va_list vargs)67 void nsi_vprint_error_and_exit(const char *format, va_list vargs)
68 {
69 	if (is_a_tty[ST_ERR] == -1) {
70 		decide_about_color();
71 	}
72 	if (is_a_tty[ST_ERR]) {
73 		fprintf(stderr, "%s", trace_type_esc_start[ERROR]);
74 	}
75 
76 	vfprintf(stderr, format, vargs);
77 
78 	if (is_a_tty[ST_ERR]) {
79 		fprintf(stderr, "%s\n", trace_esc_end);
80 	}
81 
82 	nsi_exit(1);
83 }
84 
nsi_vprint_trace(const char * format,va_list vargs)85 void nsi_vprint_trace(const char *format, va_list vargs)
86 {
87 	if (is_a_tty[ST_OUT] == -1) {
88 		decide_about_color();
89 	}
90 	if (is_a_tty[ST_OUT]) {
91 		fprintf(stdout, "%s", trace_type_esc_start[TRACE]);
92 	}
93 
94 	vfprintf(stdout, format, vargs);
95 
96 	if (is_a_tty[ST_OUT]) {
97 		fprintf(stdout, "%s", trace_esc_end);
98 	}
99 }
100 
trace_disable_color(char * argv,int offset)101 static void trace_disable_color(char *argv, int offset)
102 {
103 	is_a_tty[0] = 0;
104 	is_a_tty[1] = 0;
105 }
106 
trace_enable_color(char * argv,int offset)107 static void trace_enable_color(char *argv, int offset)
108 {
109 	is_a_tty[0] = -1;
110 	is_a_tty[1] = -1;
111 
112 }
113 
trace_force_color(char * argv,int offset)114 static void trace_force_color(char *argv, int offset)
115 {
116 	is_a_tty[0] = 1;
117 	is_a_tty[1] = 1;
118 }
119 
nsi_trace_over_tty(int file_number)120 int nsi_trace_over_tty(int file_number)
121 {
122 	return is_a_tty[file_number];
123 }
124 
125 NSI_TASK(decide_about_color, PRE_BOOT_2, 0);
126 
nsi_add_tracing_options(void)127 static void nsi_add_tracing_options(void)
128 {
129 	static struct args_struct_t trace_options[] = {
130 		{
131 			.is_switch = true,
132 			.option = "color",
133 			.type = 'b',
134 			.call_when_found = trace_enable_color,
135 			.descript = "(default) Enable color in traces if printing to console"
136 		},
137 		{
138 			.is_switch = true,
139 			.option = "no-color",
140 			.type = 'b',
141 			.call_when_found = trace_disable_color,
142 			.descript = "Disable color in traces even if printing to console"
143 		},
144 		{
145 			.is_switch = true,
146 			.option = "force-color",
147 			.type = 'b',
148 			.call_when_found = trace_force_color,
149 			.descript = "Enable color in traces even if printing to files/pipes"
150 		},
151 		ARG_TABLE_ENDMARKER
152 	};
153 
154 	nsi_add_command_line_opts(trace_options);
155 }
156 
157 NSI_TASK(nsi_add_tracing_options, PRE_BOOT_1, 0);
158