Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
env.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
16
17#include "sham/term/env.hpp"
18#include "sham/term/color.hpp"
19#include "sham/term/tty.hpp"
20#include <string_view>
21#include <cctype>
22#include <vector>
23
24namespace {
25
29 static const std::vector<std::string_view> basic_color_term{
30 "xterm", "vt100", "color", "ansi", "cygwin", "linux"};
31
35 static const std::vector<std::string_view> ansi256_color_term{"xterm-256", "xterm-256color"};
36
40 static const std::vector<std::string_view> truecolor_term{
41 "xterm-truecolor", "xterm-direct", "xterm-kitty", "alacritty"};
42
48 bool string_contains_ci(std::string_view haystack, std::string_view needle) {
49 if (needle.size() > haystack.size()) {
50 return false;
51 }
52 for (size_t i = 0; i + needle.size() <= haystack.size(); ++i) {
53 bool match = true;
54 for (size_t j = 0; j < needle.size(); ++j) {
55 if (std::tolower(static_cast<unsigned char>(haystack[i + j]))
56 != std::tolower(static_cast<unsigned char>(needle[j]))) {
57 match = false;
58 break;
59 }
60 }
61 if (match) {
62 return true;
63 }
64 }
65 return false;
66 }
67
73 bool contains_utf8_marker(std::string_view value) {
74 return string_contains_ci(value, "utf-8") || string_contains_ci(value, "utf8");
75 }
76
86 bool term_support_utf8(sham::term::TermEnvVars vars) {
87 if (vars.lc_all) {
88 return contains_utf8_marker(*vars.lc_all);
89 }
90 if (vars.lc_ctype) {
91 return contains_utf8_marker(*vars.lc_ctype);
92 }
93 if (vars.LANG) {
94 return contains_utf8_marker(*vars.LANG);
95 }
96 return false;
97 }
98
99} // namespace
100
101namespace sham::term {
102
104
105 if (vars.COLORTERM) {
106 if (*vars.COLORTERM == "truecolor" || *vars.COLORTERM == "24bit") {
108 }
109 }
110
111 if (vars.TERM) {
112 for (auto term : truecolor_term) {
113 if (*vars.TERM == term) {
115 }
116 }
117 for (auto term : ansi256_color_term) {
118 if (*vars.TERM == term) {
119 return ColorLevel::ANSI256;
120 }
121 }
122 for (auto term : basic_color_term) {
123 if (*vars.TERM == term) {
124 return ColorLevel::Basic;
125 }
126 }
127 }
128
129 return ColorLevel::NoColor;
130 }
131
132 void parse_terminal_support(TermEnvVars vars, const term_parse_callback_t &error_callback) {
134
135 bool has_envvar_nocolor = bool(vars.NO_COLOR);
136 bool has_envvar_color = bool(vars.CLICOLOR_FORCE);
137
138 if (has_envvar_color && has_envvar_nocolor) {
139 throw error_callback(
140 "one can not set both NO_COLOR and CLICOLOR_FORCE",
141 std::source_location::current());
142 }
143
144 if (has_envvar_nocolor) {
146 }
147
148 if (has_envvar_color) {
150 }
151
152 sham::term::set_support_utf8(term_support_utf8(vars));
153
154 bool has_envvar_no_utf8 = bool(vars.NO_UTF8);
155 bool has_envvar_force_utf8 = bool(vars.FORCE_UTF8);
156
157 if (has_envvar_no_utf8 && has_envvar_force_utf8) {
158 throw error_callback(
159 "one can not set both NO_UTF8 and FORCE_UTF8", std::source_location::current());
160 }
161
162 if (has_envvar_no_utf8) {
164 }
165
166 if (has_envvar_force_utf8) {
168 }
169
170 auto &res = vars.COLUMN;
171
172 int min_sz = 10;
173 if (res) {
174 try {
175 int val = std::stoi(std::string(*res));
176 if (val < min_sz) {
177 val = min_sz;
178 }
180 } catch (const std::invalid_argument &a) {
181 throw error_callback(
182 "Error : COLUMN is not an integer", std::source_location::current());
183 } catch (const std::out_of_range &a) {
184 throw error_callback(
185 "Error : COLUMN is out of range", std::source_location::current());
186 }
187 }
188 }
189
190} // namespace sham::term
Terminal color escape sequences and enable/disable control.
ColorLevel
The possible levels of terminal color support.
Definition color.hpp:27
@ TrueColor
24-bit RGB truecolor, \x1b[38;2;r;g;bm.
Definition color.hpp:35
@ NoColor
No color support, plain ASCII output only.
Definition color.hpp:29
@ Basic
ANSI/16 colors (basic SGR codes), \x1b[3Xm.
Definition color.hpp:31
@ ANSI256
256-color palette (16 ANSI + 216-color cube + 24 grayscale), \x1b[38;5;Nm.
Definition color.hpp:33
void set_color_level(ColorLevel level)
Set the terminal color support level.
Definition color.cpp:46
void enable_colors()
Enable colors.
Definition color.cpp:50
void disable_colors()
Disable all colors.
Definition color.cpp:53
std::function< std::invalid_argument(const char *what, std::source_location where)> term_parse_callback_t
Callback signature for parsing error reporting (returns what, receives source location).
Environment variable parsing for terminal color, size and UTF-8 support configuration (TERM,...
void parse_terminal_support(TermEnvVars vars, const term_parse_callback_t &error_callback)
Parses terminal environment variables to determine color support and set terminal size.
Definition env.cpp:132
ColorLevel detect_color_level(TermEnvVars vars)
Detect the terminal emulator's color support level from TERM/COLORTERM.
Definition env.cpp:103
Holds optional terminal environment variables (TERM, COLORTERM, NO_COLOR, CLICOLOR_FORCE,...
Definition env.hpp:33
This file contains tty info getters.
void set_tty_columns(int columns)
Set the forced width of the terminal.
Definition tty.cpp:54
void set_support_utf8(bool support)
Set whether the current terminal/locale supports UTF-8 output.
Definition tty.cpp:98