blob: 0ca9e752934555d3f758b65c7bf4ca0534c29932 [file] [log] [blame]
/*
* Copyright (c) 2017 Oticon A/S
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <stdio.h> /* for printfs */
#include <stdarg.h> /* for va args */
#include <unistd.h>
#include "nsi_tasks.h"
#include "nsi_cmdline.h"
#include "nsi_tracing.h"
#include "nsi_main.h"
/**
* Are stdout and stderr connected to a tty
* 0 = no
* 1 = yes
* -1 = we do not know yet
* Indexed 0:stdout, 1:stderr
*/
static int is_a_tty[2] = {-1, -1};
#define ST_OUT 0
#define ST_ERR 1
static void decide_about_color(void)
{
if (is_a_tty[0] == -1) {
is_a_tty[0] = isatty(STDOUT_FILENO);
}
if (is_a_tty[1] == -1) {
is_a_tty[1] = isatty(STDERR_FILENO);
}
}
#define ERROR 0
#define WARN 1
#define TRACE 2
static const char * const trace_type_esc_start[] = {
"\x1b[1;31m", /* ERROR - Foreground color = red, bold */
"\x1b[95m", /* WARNING - Foreground color = magenta */
"\x1b[0;39m", /* TRACE - reset all styles */
};
static const char trace_esc_end[] = "\x1b[0;39m"; /* Reset all styles */
void nsi_vprint_warning(const char *format, va_list vargs)
{
if (is_a_tty[ST_ERR] == -1) {
decide_about_color();
}
if (is_a_tty[ST_ERR]) {
fprintf(stderr, "%s", trace_type_esc_start[WARN]);
}
vfprintf(stderr, format, vargs);
if (is_a_tty[ST_ERR]) {
fprintf(stderr, "%s", trace_esc_end);
}
}
void nsi_vprint_error_and_exit(const char *format, va_list vargs)
{
if (is_a_tty[ST_ERR] == -1) {
decide_about_color();
}
if (is_a_tty[ST_ERR]) {
fprintf(stderr, "%s", trace_type_esc_start[ERROR]);
}
vfprintf(stderr, format, vargs);
if (is_a_tty[ST_ERR]) {
fprintf(stderr, "%s\n", trace_esc_end);
}
nsi_exit(1);
}
void nsi_vprint_trace(const char *format, va_list vargs)
{
if (is_a_tty[ST_OUT] == -1) {
decide_about_color();
}
if (is_a_tty[ST_OUT]) {
fprintf(stdout, "%s", trace_type_esc_start[TRACE]);
}
vfprintf(stdout, format, vargs);
if (is_a_tty[ST_OUT]) {
fprintf(stdout, "%s", trace_esc_end);
}
}
static void trace_disable_color(char *argv, int offset)
{
is_a_tty[0] = 0;
is_a_tty[1] = 0;
}
static void trace_enable_color(char *argv, int offset)
{
is_a_tty[0] = -1;
is_a_tty[1] = -1;
}
static void trace_force_color(char *argv, int offset)
{
is_a_tty[0] = 1;
is_a_tty[1] = 1;
}
int nsi_trace_over_tty(int file_number)
{
return is_a_tty[file_number];
}
NSI_TASK(decide_about_color, PRE_BOOT_2, 0);
static void nsi_add_tracing_options(void)
{
static struct args_struct_t trace_options[] = {
{
.is_switch = true,
.option = "color",
.type = 'b',
.call_when_found = trace_enable_color,
.descript = "(default) Enable color in traces if printing to console"
},
{
.is_switch = true,
.option = "no-color",
.type = 'b',
.call_when_found = trace_disable_color,
.descript = "Disable color in traces even if printing to console"
},
{
.is_switch = true,
.option = "force-color",
.type = 'b',
.call_when_found = trace_force_color,
.descript = "Enable color in traces even if printing to files/pipes"
},
ARG_TABLE_ENDMARKER
};
nsi_add_command_line_opts(trace_options);
}
NSI_TASK(nsi_add_tracing_options, PRE_BOOT_1, 0);