mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Turn a lot of common.h variables into getter functions
Improves thread safety.
This commit is contained in:
parent
9dc1fd50c9
commit
f66e010949
15 changed files with 67 additions and 29 deletions
|
@ -494,7 +494,7 @@ static int builtin_set_list(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
||||||
streams.out.append(L" ");
|
streams.out.append(L" ");
|
||||||
streams.out.append(val);
|
streams.out.append(val);
|
||||||
|
|
||||||
if (shorten) streams.out.push_back(ellipsis_char);
|
if (shorten) streams.out.push_back(get_ellipsis_char());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "expand.h"
|
#include "expand.h"
|
||||||
#include "fallback.h" // IWYU pragma: keep
|
#include "fallback.h" // IWYU pragma: keep
|
||||||
#include "future_feature_flags.h"
|
#include "future_feature_flags.h"
|
||||||
|
#include "global_safety.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "wildcard.h"
|
#include "wildcard.h"
|
||||||
#include "wutil.h" // IWYU pragma: keep
|
#include "wutil.h" // IWYU pragma: keep
|
||||||
|
@ -64,19 +65,32 @@ struct termios shell_modes;
|
||||||
/// This allows us to determine if we're running on the main thread
|
/// This allows us to determine if we're running on the main thread
|
||||||
static std::atomic<size_t> thread_id { 0 };
|
static std::atomic<size_t> thread_id { 0 };
|
||||||
/// This allows us to notice when we've forked.
|
/// This allows us to notice when we've forked.
|
||||||
static bool is_forked_proc = false;
|
static relaxed_atomic_bool_t is_forked_proc{false};
|
||||||
/// This allows us to bypass the main thread checks
|
/// This allows us to bypass the main thread checks
|
||||||
static bool thread_asserts_cfg_for_testing = false;
|
static relaxed_atomic_bool_t thread_asserts_cfg_for_testing{false};
|
||||||
|
|
||||||
|
static relaxed_atomic_t<wchar_t> ellipsis_char;
|
||||||
|
wchar_t get_ellipsis_char() { return ellipsis_char; }
|
||||||
|
|
||||||
|
static relaxed_atomic_t<const wchar_t *> ellipsis_str;
|
||||||
|
const wchar_t *get_ellipsis_str() { return ellipsis_str; }
|
||||||
|
|
||||||
|
static relaxed_atomic_t<const wchar_t *> omitted_newline_str;
|
||||||
|
const wchar_t *get_omitted_newline_str() { return omitted_newline_str; }
|
||||||
|
|
||||||
|
static relaxed_atomic_t<int> omitted_newline_width;
|
||||||
|
int get_omitted_newline_width() { return omitted_newline_width; }
|
||||||
|
|
||||||
|
static relaxed_atomic_t<wchar_t> obfuscation_read_char;
|
||||||
|
wchar_t get_obfuscation_read_char() { return obfuscation_read_char; }
|
||||||
|
|
||||||
wchar_t ellipsis_char;
|
|
||||||
const wchar_t *ellipsis_str = nullptr;
|
|
||||||
const wchar_t *omitted_newline_str;
|
|
||||||
int omitted_newline_width;
|
|
||||||
wchar_t obfuscation_read_char;
|
|
||||||
bool g_profiling_active = false;
|
bool g_profiling_active = false;
|
||||||
const wchar_t *program_name;
|
const wchar_t *program_name;
|
||||||
std::atomic<int> debug_level{1}; // default maximum debug output level (errors and warnings)
|
std::atomic<int> debug_level{1}; // default maximum debug output level (errors and warnings)
|
||||||
int debug_stack_frames = 0; // default number of stack frames to show on debug() calls
|
|
||||||
|
static relaxed_atomic_t<int> debug_stack_frames{0};
|
||||||
|
void set_debug_stack_frames(int v) { debug_stack_frames = v; }
|
||||||
|
int get_debug_stack_frames() { return debug_stack_frames; }
|
||||||
|
|
||||||
/// Be able to restore the term's foreground process group.
|
/// Be able to restore the term's foreground process group.
|
||||||
/// This is set during startup and not modified after.
|
/// This is set during startup and not modified after.
|
||||||
|
|
14
src/common.h
14
src/common.h
|
@ -176,20 +176,22 @@ extern struct termios shell_modes;
|
||||||
|
|
||||||
/// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $
|
/// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $
|
||||||
/// on other systems.
|
/// on other systems.
|
||||||
extern wchar_t ellipsis_char;
|
wchar_t get_ellipsis_char();
|
||||||
|
|
||||||
/// The character or string to use where text has been truncated (ellipsis if possible, otherwise
|
/// The character or string to use where text has been truncated (ellipsis if possible, otherwise
|
||||||
/// ...)
|
/// ...)
|
||||||
extern const wchar_t *ellipsis_str;
|
const wchar_t *get_ellipsis_str();
|
||||||
|
|
||||||
/// Character representing an omitted newline at the end of text.
|
/// Character representing an omitted newline at the end of text.
|
||||||
extern const wchar_t *omitted_newline_str;
|
const wchar_t *get_omitted_newline_str();
|
||||||
extern int omitted_newline_width;
|
int get_omitted_newline_width();
|
||||||
|
|
||||||
/// Character used for the silent mode of the read command
|
/// Character used for the silent mode of the read command
|
||||||
extern wchar_t obfuscation_read_char;
|
wchar_t get_obfuscation_read_char();
|
||||||
|
|
||||||
/// How many stack frames to show when a debug() call is made.
|
/// How many stack frames to show when a debug() call is made.
|
||||||
extern int debug_stack_frames;
|
int get_debug_stack_frames();
|
||||||
|
void set_debug_stack_frames(int);
|
||||||
|
|
||||||
/// Profiling flag. True if commands should be profiled.
|
/// Profiling flag. True if commands should be profiled.
|
||||||
extern bool g_profiling_active;
|
extern bool g_profiling_active;
|
||||||
|
|
|
@ -337,7 +337,7 @@ static int fish_parse_opt(int argc, char **argv, fish_cmd_opts_t *opts) {
|
||||||
tmp = strtol(optarg, &end, 10);
|
tmp = strtol(optarg, &end, 10);
|
||||||
|
|
||||||
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
||||||
debug_stack_frames = (int)tmp;
|
set_debug_stack_frames((int)tmp);
|
||||||
} else {
|
} else {
|
||||||
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
|
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -575,7 +575,7 @@ int main(int argc, char *argv[]) {
|
||||||
tmp = strtol(optarg, &end, 10);
|
tmp = strtol(optarg, &end, 10);
|
||||||
|
|
||||||
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
||||||
debug_stack_frames = (int)tmp;
|
set_debug_stack_frames((int)tmp);
|
||||||
} else {
|
} else {
|
||||||
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
|
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -324,7 +324,7 @@ static bool parse_debug_frames_flag() {
|
||||||
char *end;
|
char *end;
|
||||||
long tmp = strtol(optarg, &end, 10);
|
long tmp = strtol(optarg, &end, 10);
|
||||||
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
if (tmp > 0 && tmp <= 128 && !*end && !errno) {
|
||||||
debug_stack_frames = (int)tmp;
|
set_debug_stack_frames((int)tmp);
|
||||||
} else {
|
} else {
|
||||||
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag\n"), optarg);
|
std::fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag\n"), optarg);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2047,6 +2047,7 @@ struct pager_layout_testcase_t {
|
||||||
wcstring expected = this->expected;
|
wcstring expected = this->expected;
|
||||||
|
|
||||||
// hack: handle the case where ellipsis is not L'\x2026'
|
// hack: handle the case where ellipsis is not L'\x2026'
|
||||||
|
wchar_t ellipsis_char = get_ellipsis_char();
|
||||||
if (ellipsis_char != L'\x2026') {
|
if (ellipsis_char != L'\x2026') {
|
||||||
std::replace(expected.begin(), expected.end(), L'\x2026', ellipsis_char);
|
std::replace(expected.begin(), expected.end(), L'\x2026', ellipsis_char);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// fish is multithreaded. Global (which includes function and file-level statics) when used naively
|
// fish is multithreaded. Global (which includes function and file-level statics) when used naively
|
||||||
|
@ -70,4 +71,20 @@ class latch_t : detail::fixed_t {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An atomic type that always use relaxed reads.
|
||||||
|
template <typename T>
|
||||||
|
class relaxed_atomic_t {
|
||||||
|
std::atomic<T> value_{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
relaxed_atomic_t() = default;
|
||||||
|
relaxed_atomic_t(T value) : value_(value) {}
|
||||||
|
|
||||||
|
operator T() const { return value_.load(std::memory_order_relaxed); }
|
||||||
|
|
||||||
|
void operator=(T v) { return value_.store(v, std::memory_order_relaxed); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using relaxed_atomic_bool_t = relaxed_atomic_t<bool>;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -89,9 +89,10 @@ static size_t print_max(const wcstring &str, highlight_spec_t color, size_t max,
|
||||||
|
|
||||||
if (width_c > remaining) break;
|
if (width_c > remaining) break;
|
||||||
|
|
||||||
|
wchar_t ellipsis = get_ellipsis_char();
|
||||||
if ((width_c == remaining) && (has_more || i + 1 < str.size())) {
|
if ((width_c == remaining) && (has_more || i + 1 < str.size())) {
|
||||||
line->append(ellipsis_char, color);
|
line->append(ellipsis, color);
|
||||||
int ellipsis_width = fish_wcwidth(ellipsis_char);
|
int ellipsis_width = fish_wcwidth(ellipsis);
|
||||||
remaining -= std::min(remaining, size_t(ellipsis_width));
|
remaining -= std::min(remaining, size_t(ellipsis_width));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -493,7 +494,7 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co
|
||||||
wcstring progress_text;
|
wcstring progress_text;
|
||||||
assert(rendering->remaining_to_disclose != 1);
|
assert(rendering->remaining_to_disclose != 1);
|
||||||
if (rendering->remaining_to_disclose > 1) {
|
if (rendering->remaining_to_disclose > 1) {
|
||||||
progress_text = format_string(_(L"%lsand %lu more rows"), ellipsis_str,
|
progress_text = format_string(_(L"%lsand %lu more rows"), get_ellipsis_str(),
|
||||||
(unsigned long)rendering->remaining_to_disclose);
|
(unsigned long)rendering->remaining_to_disclose);
|
||||||
} else if (start_row > 0 || stop_row < row_count) {
|
} else if (start_row > 0 || stop_row < row_count) {
|
||||||
// We have a scrollable interface. The +1 here is because we are zero indexed, but want
|
// We have a scrollable interface. The +1 here is because we are zero indexed, but want
|
||||||
|
|
|
@ -700,7 +700,7 @@ parse_execution_result_t parse_execution_context_t::handle_command_not_found(
|
||||||
// Looks like a command.
|
// Looks like a command.
|
||||||
this->report_error(statement, ERROR_BAD_EQUALS_IN_COMMAND5, argument.c_str(),
|
this->report_error(statement, ERROR_BAD_EQUALS_IN_COMMAND5, argument.c_str(),
|
||||||
name_str.c_str(), val_str.c_str(), argument.c_str(),
|
name_str.c_str(), val_str.c_str(), argument.c_str(),
|
||||||
ellipsis_str);
|
get_ellipsis_str());
|
||||||
} else {
|
} else {
|
||||||
wcstring assigned_val = reconstruct_orig_str(val_str);
|
wcstring assigned_val = reconstruct_orig_str(val_str);
|
||||||
this->report_error(statement, ERROR_BAD_COMMAND_ASSIGN_ERR_MSG, name_str.c_str(),
|
this->report_error(statement, ERROR_BAD_COMMAND_ASSIGN_ERR_MSG, name_str.c_str(),
|
||||||
|
|
|
@ -794,6 +794,7 @@ static wcstring truncate_string(const wcstring &str) {
|
||||||
wcstring result(str, 0, max_len);
|
wcstring result(str, 0, max_len);
|
||||||
if (str.size() > max_len) {
|
if (str.size() > max_len) {
|
||||||
// Truncate!
|
// Truncate!
|
||||||
|
wchar_t ellipsis_char = get_ellipsis_char();
|
||||||
if (ellipsis_char == L'\x2026') {
|
if (ellipsis_char == L'\x2026') {
|
||||||
result.at(max_len - 1) = ellipsis_char;
|
result.at(max_len - 1) = ellipsis_char;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -410,6 +410,7 @@ static wcstring truncate_command(const wcstring &cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncation required.
|
// Truncation required.
|
||||||
|
const wchar_t *ellipsis_str = get_ellipsis_str();
|
||||||
const size_t ellipsis_length = std::wcslen(ellipsis_str); // no need for wcwidth
|
const size_t ellipsis_length = std::wcslen(ellipsis_str); // no need for wcwidth
|
||||||
size_t trunc_length = max_len - ellipsis_length;
|
size_t trunc_length = max_len - ellipsis_length;
|
||||||
// Eat trailing whitespace.
|
// Eat trailing whitespace.
|
||||||
|
|
|
@ -610,7 +610,7 @@ void reader_data_t::repaint() {
|
||||||
|
|
||||||
wcstring full_line;
|
wcstring full_line;
|
||||||
if (silent) {
|
if (silent) {
|
||||||
full_line = wcstring(cmd_line->text.length(), obfuscation_read_char);
|
full_line = wcstring(cmd_line->text.length(), get_obfuscation_read_char());
|
||||||
} else {
|
} else {
|
||||||
// Combine the command and autosuggestion into one string.
|
// Combine the command and autosuggestion into one string.
|
||||||
full_line = combine_command_and_autosuggestion(cmd_line->text, autosuggestion);
|
full_line = combine_command_and_autosuggestion(cmd_line->text, autosuggestion);
|
||||||
|
@ -1633,7 +1633,7 @@ bool reader_data_t::handle_completions(const std::vector<completion_t> &comp,
|
||||||
prefix.append(el->text, prefix_start, len);
|
prefix.append(el->text, prefix_start, len);
|
||||||
} else {
|
} else {
|
||||||
// Append just the end of the string.
|
// Append just the end of the string.
|
||||||
prefix = wcstring(&ellipsis_char, 1);
|
prefix = wcstring{get_ellipsis_char()};
|
||||||
prefix.append(el->text, prefix_start + len - PREFIX_MAX_LEN, PREFIX_MAX_LEN);
|
prefix.append(el->text, prefix_start + len - PREFIX_MAX_LEN, PREFIX_MAX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -918,7 +918,7 @@ static screen_layout_t compute_layout(screen_t *s, size_t screen_width,
|
||||||
size_t truncation_offset = truncation_offset_for_width(
|
size_t truncation_offset = truncation_offset_for_width(
|
||||||
autosuggest_truncated_widths, available_autosuggest_space - 2);
|
autosuggest_truncated_widths, available_autosuggest_space - 2);
|
||||||
result.autosuggestion = wcstring(autosuggestion, truncation_offset);
|
result.autosuggestion = wcstring(autosuggestion, truncation_offset);
|
||||||
result.autosuggestion.push_back(ellipsis_char);
|
result.autosuggestion.push_back(get_ellipsis_char());
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
@ -1102,7 +1102,7 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) {
|
||||||
|
|
||||||
// Don't need to check for fish_wcwidth errors; this is done when setting up
|
// Don't need to check for fish_wcwidth errors; this is done when setting up
|
||||||
// omitted_newline_char in common.cpp.
|
// omitted_newline_char in common.cpp.
|
||||||
int non_space_width = omitted_newline_width;
|
int non_space_width = get_omitted_newline_width();
|
||||||
// We do `>` rather than `>=` because the code below might require one extra space.
|
// We do `>` rather than `>=` because the code below might require one extra space.
|
||||||
if (screen_width > non_space_width) {
|
if (screen_width > non_space_width) {
|
||||||
bool justgrey = true;
|
bool justgrey = true;
|
||||||
|
@ -1129,7 +1129,7 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abandon_line_string.append(omitted_newline_str);
|
abandon_line_string.append(get_omitted_newline_str());
|
||||||
|
|
||||||
if (cur_term && exit_attribute_mode) {
|
if (cur_term && exit_attribute_mode) {
|
||||||
abandon_line_string.append(
|
abandon_line_string.append(
|
||||||
|
@ -1141,7 +1141,7 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
abandon_line_string.push_back(L'\r');
|
abandon_line_string.push_back(L'\r');
|
||||||
abandon_line_string.append(omitted_newline_str);
|
abandon_line_string.append(get_omitted_newline_str());
|
||||||
// Now we are certainly on a new line. But we may have dropped the omitted newline char on
|
// Now we are certainly on a new line. But we may have dropped the omitted newline char on
|
||||||
// it. So append enough spaces to overwrite the omitted newline char, and then clear all the
|
// it. So append enough spaces to overwrite the omitted newline char, and then clear all the
|
||||||
// spaces from the new line.
|
// spaces from the new line.
|
||||||
|
|
|
@ -39,10 +39,11 @@ wcstring truncate(const wcstring &input, int max_len, ellipsis_type etype) {
|
||||||
return input.substr(0, max_len);
|
return input.substr(0, max_len);
|
||||||
}
|
}
|
||||||
if (etype == ellipsis_type::Prettiest) {
|
if (etype == ellipsis_type::Prettiest) {
|
||||||
|
const wchar_t *ellipsis_str = get_ellipsis_str();
|
||||||
return input.substr(0, max_len - std::wcslen(ellipsis_str)).append(ellipsis_str);
|
return input.substr(0, max_len - std::wcslen(ellipsis_str)).append(ellipsis_str);
|
||||||
}
|
}
|
||||||
wcstring output = input.substr(0, max_len - 1);
|
wcstring output = input.substr(0, max_len - 1);
|
||||||
output.push_back(ellipsis_char);
|
output.push_back(get_ellipsis_char());
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue