From b0a695e9facbeada7e76649e5a8acee3ebc91d78 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 28 Apr 2019 16:11:49 -0700 Subject: [PATCH] Migrate the global exec_count into the parser --- src/builtin_eval.cpp | 4 ++-- src/exec.cpp | 15 ++++----------- src/exec.h | 3 --- src/parser.h | 17 ++++++++++++----- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/builtin_eval.cpp b/src/builtin_eval.cpp index 32e6a81f3..7ed003e85 100644 --- a/src/builtin_eval.cpp +++ b/src/builtin_eval.cpp @@ -24,13 +24,13 @@ int builtin_eval(parser_t &parser, io_streams_t &streams, wchar_t **argv) { new_cmd += argv[i]; } - size_t cached_exec_count = exec_get_exec_count(); + const auto cached_exec_count = parser.libdata().exec_count; int status = STATUS_CMD_OK; if (argc > 1) { if (parser.eval(std::move(new_cmd), *streams.io_chain, block_type_t::TOP) != 0) { // This indicates a parse error; nothing actually got executed. status = STATUS_CMD_ERROR; - } else if (cached_exec_count == exec_get_exec_count()) { + } else if (cached_exec_count == parser.libdata().exec_count) { // Issue #5692, in particular, to catch `eval ""`, `eval "begin; end;"`, etc. // where we have an argument but nothing is executed. status = STATUS_CMD_OK; diff --git a/src/exec.cpp b/src/exec.cpp index 746769dbd..d3d604c91 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -864,14 +864,6 @@ static bool exec_block_or_func_process(parser_t &parser, std::shared_ptr return true; } -// The number of overall "command" executions, for whatever definition of "command". Its delta -// is used to determine the number of recursive `exec_process_in_job()` invocations. -static size_t exec_count = 0; - -size_t exec_get_exec_count() { - return exec_count; -} - /// Executes a process \p in job \j, using the pipes \p pipes (which may have invalid fds if this is /// the first or last process). /// \p deferred_pipes represents the pipes from our deferred process; if set ensure they get closed @@ -936,7 +928,7 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< if (p->type != process_type_t::block_node) { // An simple `begin ... end` should not be considered an execution of a command. - exec_count++; + parser.libdata().exec_count++; } // Execute the process. @@ -947,7 +939,7 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< // Allow buffering unless this is a deferred run. If deferred, then processes after us // were already launched, so they are ready to receive (or reject) our output. bool allow_buffering = !is_deferred_run; - auto cached_exec_count = exec_count; + auto cached_exec_count = parser.libdata().exec_count; if (!exec_block_or_func_process(parser, j, p, all_ios, process_net_io_chain, allow_buffering)) { return false; @@ -956,7 +948,8 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< // Functions are basically treated as named blocks, and this is the only place we can // distinguish between them. A block by default does not touch $status, on the other // hand, calling an empty function should clear $status. - if (exec_count == cached_exec_count && p->type == process_type_t::function) { + if (parser.libdata().exec_count == cached_exec_count && + p->type == process_type_t::function) { p->status = proc_status_t::from_exit_code(0); } diff --git a/src/exec.h b/src/exec.h index fe776db8a..12c5d9051 100644 --- a/src/exec.h +++ b/src/exec.h @@ -31,9 +31,6 @@ int exec_subshell(const wcstring &cmd, parser_t &parser, bool preserve_exit_stat /// Loops over close until the syscall was run without being interrupted. void exec_close(int fd); -/// Returns the number of executions. May roll over. -size_t exec_get_exec_count(); - /// Gets the interpreter for a given command. char *get_interpreter(const char *command, char *interpreter, size_t buff_size); diff --git a/src/parser.h b/src/parser.h index 83cecab7b..b00c54a6a 100644 --- a/src/parser.h +++ b/src/parser.h @@ -147,6 +147,12 @@ struct profile_item_t { class parse_execution_context_t; class completion_t; +/// Miscelleneous data used to avoid recursion and others. +struct library_data_t { + /// A counter incremented every time a command executes. + uint64_t exec_count{0}; +}; + class parser_t : public std::enable_shared_from_this { friend class parse_execution_context_t; @@ -165,11 +171,8 @@ class parser_t : public std::enable_shared_from_this { int eval_level = -1; /// Set of variables for the parser. env_stack_t &variables; -#if 0 -// TODO: Lint says this isn't used (which is true). Should this be removed? - /// Gets a description of the block stack, for debugging. - wcstring block_stack_description() const; -#endif + /// Miscellaneous library data. + library_data_t library_data{}; /// List of profile items /// These are pointers because we return pointers to them to callers, @@ -269,6 +272,10 @@ class parser_t : public std::enable_shared_from_this { env_stack_t &vars() { return variables; } const env_stack_t &vars() const { return variables; } + /// Get the library data. + library_data_t &libdata() { return library_data; } + const library_data_t &libdata() const { return library_data; } + /// 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()