diff --git a/src/fish.cpp b/src/fish.cpp index c213321d9..b9857e8af 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -184,9 +184,9 @@ static void source_config_in_directory(const wcstring &dir) { const wcstring cmd = L"builtin source " + escaped_pathname; parser_t &parser = parser_t::principal_parser(); - parser.set_is_within_fish_initialization(true); + set_is_within_fish_initialization(true); parser.eval(cmd, io_chain_t(), TOP); - parser.set_is_within_fish_initialization(false); + set_is_within_fish_initialization(false); } /// Parse init files. exec_path is the path of fish executable as determined by argv[0]. diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 4270fd699..c35e3c551 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -2142,7 +2142,7 @@ static void test_is_potential_path() { /// Test the 'test' builtin. int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv); static bool run_one_test_test(int expected, wcstring_list_t &lst, bool bracket) { - parser_t parser; + parser_t &parser = parser_t::principal_parser(); size_t i, count = lst.size(); wchar_t **argv = new wchar_t *[count + 3]; argv[0] = (wchar_t *)(bracket ? L"[" : L"test"); @@ -2185,7 +2185,7 @@ static bool run_test_test(int expected, const wcstring &str) { static void test_test_brackets() { // Ensure [ knows it needs a ]. - parser_t parser; + parser_t &parser = parser_t::principal_parser(); io_streams_t streams(0); null_terminated_array_t args; @@ -4389,7 +4389,7 @@ static void test_pcre2_escape() { int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv); static void run_one_string_test(const wchar_t *const *argv, int expected_rc, const wchar_t *expected_out) { - parser_t parser; + parser_t &parser = parser_t::principal_parser(); io_streams_t streams(0); streams.stdin_is_directly_redirected = false; // read from argv instead of stdin int rc = builtin_string(parser, streams, const_cast(argv)); diff --git a/src/parser.cpp b/src/parser.cpp index 4196c3dd8..fd33f58fd 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -100,26 +100,22 @@ static wcstring user_presentable_path(const wcstring &path) { return replace_home_directory_with_tilde(path); } -parser_t::parser_t() : cancellation_requested(false), is_within_fish_initialization(false) {} +parser_t::parser_t() = default; // Out of line destructor to enable forward declaration of parse_execution_context_t parser_t::~parser_t() = default; -static parser_t s_principal_parser; +parser_t parser_t::principal; parser_t &parser_t::principal_parser() { ASSERT_IS_MAIN_THREAD(); - return s_principal_parser; -} - -void parser_t::set_is_within_fish_initialization(bool flag) { - is_within_fish_initialization = flag; + return principal; } void parser_t::skip_all_blocks() { // Tell all blocks to skip. // This may be called from a signal handler! - s_principal_parser.cancellation_requested = true; + principal.cancellation_requested = true; } // Given a new-allocated block, push it onto our block stack, acquiring ownership @@ -399,7 +395,7 @@ void parser_t::stack_trace_internal(size_t block_idx, wcstring *buff) const { if (file) { append_format(*buff, _(L"\tcalled on line %d of file %ls\n"), b->src_lineno, user_presentable_path(file).c_str()); - } else if (is_within_fish_initialization) { + } else if (is_within_fish_initialization()) { append_format(*buff, _(L"\tcalled during startup\n")); } else { append_format(*buff, _(L"\tcalled on standard input\n")); @@ -536,7 +532,7 @@ wcstring parser_t::current_line() { if (file) { append_format(prefix, _(L"%ls (line %d): "), user_presentable_path(file).c_str(), lineno); - } else if (is_within_fish_initialization) { + } else if (is_within_fish_initialization()) { append_format(prefix, L"%ls (line %d): ", _(L"Startup"), lineno); } else { append_format(prefix, L"%ls (line %d): ", _(L"Standard input"), lineno); diff --git a/src/parser.h b/src/parser.h index 5449db970..bfeea4406 100644 --- a/src/parser.h +++ b/src/parser.h @@ -162,9 +162,7 @@ class parser_t { private: /// Indication that we should skip all blocks. - volatile sig_atomic_t cancellation_requested; - /// Indicates that we are within the process of initializing fish. - bool is_within_fish_initialization; + volatile sig_atomic_t cancellation_requested = false; /// The current execution context. std::unique_ptr execution_context; /// List of called functions, used to help prevent infinite recursion. @@ -206,6 +204,12 @@ class parser_t { /// Helper for push_block() void push_block_int(block_t *b); + /// Create a parser. + parser_t(); + + /// The main parser. + static parser_t principal; + public: /// Get the "principal" parser, whatever that is. static parser_t &principal_parser(); @@ -214,9 +218,6 @@ class parser_t { /// from signal handlers! static void skip_all_blocks(); - /// Create a parser. - parser_t(); - /// Global event blocks. event_blockage_list_t global_event_blocks; @@ -270,10 +271,6 @@ class parser_t { /// Get the list of jobs. job_list_t &job_list() { return my_job_list; } - // Hackish. In order to correctly report the origin of code with no associated file, we need to - // know whether it's run during initialization or not. - void set_is_within_fish_initialization(bool flag); - /// Pushes a new block created with the given arguments /// Returns a pointer to the block. The pointer is valid /// until the call to pop_block() diff --git a/src/proc.cpp b/src/proc.cpp index 69494c8dc..6f692fb50 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #if HAVE_TERM_H #include @@ -1289,3 +1290,9 @@ void hup_background_jobs() { } } } + +static std::atomic s_is_within_fish_initialization{false}; + +void set_is_within_fish_initialization(bool flag) { s_is_within_fish_initialization.store(flag); } + +bool is_within_fish_initialization() { return s_is_within_fish_initialization.load(); } diff --git a/src/proc.h b/src/proc.h index 2f14c89da..b48e5d215 100644 --- a/src/proc.h +++ b/src/proc.h @@ -399,6 +399,12 @@ int proc_format_status(int status); /// Wait for any process finishing. pid_t proc_wait_any(); +/// Set and get whether we are in initialization. +// Hackish. In order to correctly report the origin of code with no associated file, we need to +// know whether it's run during initialization or not. +void set_is_within_fish_initialization(bool flag); +bool is_within_fish_initialization(); + /// Terminate all background jobs void hup_background_jobs();