2016-05-03 08:22:44 +08:00
|
|
|
// The fish parser.
|
2005-10-04 23:11:39 +08:00
|
|
|
#ifndef FISH_PARSER_H
|
|
|
|
#define FISH_PARSER_H
|
|
|
|
|
2016-04-21 14:00:54 +08:00
|
|
|
#include <stddef.h>
|
2017-04-30 12:33:50 +08:00
|
|
|
#include <unistd.h>
|
2017-02-11 10:47:02 +08:00
|
|
|
|
|
|
|
#include <csignal>
|
2016-04-21 14:00:54 +08:00
|
|
|
#include <list>
|
2017-02-11 10:47:02 +08:00
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
2016-04-21 14:00:54 +08:00
|
|
|
#include <vector>
|
2005-10-04 23:11:39 +08:00
|
|
|
|
2015-07-25 23:14:25 +08:00
|
|
|
#include "common.h"
|
2006-02-01 23:49:11 +08:00
|
|
|
#include "event.h"
|
2016-02-28 10:25:58 +08:00
|
|
|
#include "expand.h"
|
2016-05-03 08:22:44 +08:00
|
|
|
#include "parse_constants.h"
|
|
|
|
#include "parse_tree.h"
|
|
|
|
#include "proc.h"
|
2015-07-25 23:14:25 +08:00
|
|
|
|
2016-04-21 14:00:54 +08:00
|
|
|
class io_chain_t;
|
2005-10-04 23:11:39 +08:00
|
|
|
|
2019-02-21 13:41:35 +08:00
|
|
|
/// event_blockage_t represents a block on events.
|
2019-05-05 18:09:25 +08:00
|
|
|
struct event_blockage_t {};
|
2012-02-08 13:04:51 +08:00
|
|
|
|
2012-08-27 13:42:29 +08:00
|
|
|
typedef std::list<event_blockage_t> event_blockage_list_t;
|
2012-02-08 13:04:51 +08:00
|
|
|
|
2019-02-21 14:42:58 +08:00
|
|
|
inline bool event_block_list_blocks_type(const event_blockage_list_t &ebls) {
|
2019-02-21 13:41:35 +08:00
|
|
|
return !ebls.empty();
|
2012-02-08 13:04:51 +08:00
|
|
|
}
|
2005-12-12 06:21:01 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Types of blocks.
|
|
|
|
enum block_type_t {
|
|
|
|
WHILE, /// While loop block
|
|
|
|
FOR, /// For loop block
|
|
|
|
IF, /// If block
|
|
|
|
FUNCTION_CALL, /// Function invocation block
|
|
|
|
FUNCTION_CALL_NO_SHADOW, /// Function invocation block with no variable shadowing
|
|
|
|
SWITCH, /// Switch block
|
|
|
|
SUBST, /// Command substitution scope
|
|
|
|
TOP, /// Outermost block
|
|
|
|
BEGIN, /// Unconditional block
|
|
|
|
SOURCE, /// Block created by the . (source) builtin
|
|
|
|
EVENT, /// Block created on event notifier invocation
|
|
|
|
BREAKPOINT, /// Breakpoint block
|
2014-03-03 05:46:30 +08:00
|
|
|
};
|
2012-08-27 13:42:29 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Possible states for a loop.
|
2019-05-19 14:12:34 +08:00
|
|
|
enum class loop_status_t {
|
|
|
|
normals, /// current loop block executed as normal
|
|
|
|
breaks, /// current loop block should be removed
|
|
|
|
continues, /// current loop block should be skipped
|
2014-10-31 16:15:50 +08:00
|
|
|
};
|
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// block_t represents a block of commands.
|
2019-05-20 05:44:17 +08:00
|
|
|
class block_t {
|
|
|
|
/// Construct from a block type.
|
2016-02-28 11:38:15 +08:00
|
|
|
explicit block_t(block_type_t t);
|
2012-08-27 14:16:20 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Type of block.
|
|
|
|
const block_type_t block_type;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// Whether execution of the commands in this block should be skipped.
|
2018-02-12 12:10:57 +08:00
|
|
|
bool skip{false};
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Name of file that created this block. This string is intern'd.
|
2018-02-12 12:10:57 +08:00
|
|
|
const wchar_t *src_filename{nullptr};
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Line number where this block was created.
|
2018-02-12 12:10:57 +08:00
|
|
|
int src_lineno{0};
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Whether we should pop the environment variable stack when we're popped off of the block
|
|
|
|
/// stack.
|
2018-02-12 12:10:57 +08:00
|
|
|
bool wants_pop_env{false};
|
|
|
|
/// List of event blocks.
|
|
|
|
event_blockage_list_t event_blocks{};
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2019-05-20 03:55:16 +08:00
|
|
|
// If this is a function block, the function name and arguments.
|
|
|
|
// Otherwise empty.
|
|
|
|
wcstring function_name{};
|
|
|
|
wcstring_list_t function_args{};
|
|
|
|
|
2019-05-20 04:01:59 +08:00
|
|
|
// If this is a source block, the source'd file, interned.
|
|
|
|
// Otherwise nothing.
|
|
|
|
const wchar_t *sourced_file{};
|
|
|
|
|
2019-05-20 04:07:06 +08:00
|
|
|
// If this is an event block, the event. Otherwise ignored.
|
|
|
|
maybe_t<event_t> event;
|
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
block_type_t type() const { return this->block_type; }
|
|
|
|
|
|
|
|
/// Description of the block, for debugging.
|
|
|
|
wcstring description() const;
|
|
|
|
|
2019-05-20 05:40:06 +08:00
|
|
|
/// Entry points for creating blocks.
|
|
|
|
static block_t if_block();
|
|
|
|
static block_t event_block(event_t evt);
|
|
|
|
static block_t function_block(wcstring name, wcstring_list_t args, bool shadows);
|
|
|
|
static block_t source_block(const wchar_t *src);
|
|
|
|
static block_t for_block();
|
|
|
|
static block_t while_block();
|
|
|
|
static block_t switch_block();
|
|
|
|
static block_t scope_block(block_type_t type);
|
|
|
|
static block_t breakpoint_block();
|
|
|
|
|
2019-05-20 05:44:17 +08:00
|
|
|
~block_t();
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
struct profile_item_t {
|
|
|
|
/// Time spent executing the specified command, including parse time for nested blocks.
|
2012-11-19 08:30:30 +08:00
|
|
|
int exec;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Time spent parsing the specified command, including execution time for command
|
|
|
|
/// substitutions.
|
2012-11-19 08:30:30 +08:00
|
|
|
int parse;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// The block level of the specified command. nested blocks and command substitutions both
|
|
|
|
/// increase the block level.
|
2012-11-19 08:30:30 +08:00
|
|
|
size_t level;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// If the execution of this command was skipped.
|
2014-02-10 06:04:43 +08:00
|
|
|
bool skipped;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// The command string.
|
2012-11-19 08:30:30 +08:00
|
|
|
wcstring cmd;
|
2012-01-21 03:24:43 +08:00
|
|
|
};
|
2012-01-20 02:28:44 +08:00
|
|
|
|
2013-12-27 05:24:10 +08:00
|
|
|
class parse_execution_context_t;
|
2015-07-25 23:14:25 +08:00
|
|
|
class completion_t;
|
2012-01-23 12:47:13 +08:00
|
|
|
|
2019-04-29 07:11:49 +08:00
|
|
|
/// 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};
|
2019-04-29 07:41:58 +08:00
|
|
|
|
2019-04-29 09:13:55 +08:00
|
|
|
/// Last reader run count.
|
|
|
|
uint64_t last_exec_run_counter{UINT64_MAX};
|
|
|
|
|
2019-04-29 07:41:58 +08:00
|
|
|
/// Number of recursive calls to builtin_complete().
|
|
|
|
uint32_t builtin_complete_recursion_level{0};
|
2019-04-30 11:58:58 +08:00
|
|
|
|
|
|
|
/// Whether we are currently cleaning processes.
|
|
|
|
bool is_cleaning_procs{false};
|
2019-05-13 05:42:18 +08:00
|
|
|
|
|
|
|
/// The job id of the job being populated.
|
|
|
|
/// This supports the '--on-job-exit caller' feature.
|
|
|
|
job_id_t caller_job_id{-1};
|
2019-05-13 09:02:57 +08:00
|
|
|
|
|
|
|
/// Whether we are running a subshell command.
|
|
|
|
bool is_subshell{false};
|
|
|
|
|
|
|
|
/// Whether we are running a block of commands.
|
|
|
|
bool is_block{false};
|
|
|
|
|
|
|
|
/// Whether we are running due to a `breakpoint` command.
|
|
|
|
bool is_breakpoint{false};
|
|
|
|
|
|
|
|
/// Whether we are running an event handler. This is not a bool because we keep count of the
|
|
|
|
/// event nesting level.
|
|
|
|
int is_event{0};
|
2019-05-19 14:12:34 +08:00
|
|
|
|
|
|
|
/// Whether we should break or continue the current loop.
|
|
|
|
enum loop_status_t loop_status { loop_status_t::normals };
|
2019-04-29 07:11:49 +08:00
|
|
|
};
|
|
|
|
|
2019-02-25 04:12:24 +08:00
|
|
|
class parser_t : public std::enable_shared_from_this<parser_t> {
|
2013-12-25 05:17:24 +08:00
|
|
|
friend class parse_execution_context_t;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
private:
|
|
|
|
/// Indication that we should skip all blocks.
|
2018-09-09 16:36:21 +08:00
|
|
|
volatile sig_atomic_t cancellation_requested = false;
|
2018-02-12 14:00:17 +08:00
|
|
|
/// The current execution context.
|
|
|
|
std::unique_ptr<parse_execution_context_t> execution_context;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// List of called functions, used to help prevent infinite recursion.
|
2012-01-30 14:06:58 +08:00
|
|
|
wcstring_list_t forbidden_function;
|
2016-05-03 08:22:44 +08:00
|
|
|
/// The jobs associated with this parser.
|
2019-05-05 13:12:31 +08:00
|
|
|
job_list_t job_list;
|
2017-01-22 07:35:35 +08:00
|
|
|
/// The list of blocks
|
|
|
|
std::vector<std::unique_ptr<block_t>> block_stack;
|
2018-02-12 13:42:23 +08:00
|
|
|
/// The 'depth' of the fish call stack.
|
|
|
|
int eval_level = -1;
|
2018-09-10 16:17:57 +08:00
|
|
|
/// Set of variables for the parser.
|
2019-05-21 00:27:46 +08:00
|
|
|
const std::shared_ptr<env_stack_t> variables;
|
2019-04-29 07:11:49 +08:00
|
|
|
/// Miscellaneous library data.
|
|
|
|
library_data_t library_data{};
|
2014-03-17 07:45:00 +08:00
|
|
|
|
2017-01-22 06:33:17 +08:00
|
|
|
/// List of profile items
|
|
|
|
/// These are pointers because we return pointers to them to callers,
|
|
|
|
/// who may hold them across blocks (which would cause reallocations internal
|
|
|
|
/// to profile_items)
|
|
|
|
std::vector<std::unique_ptr<profile_item_t>> profile_items;
|
2014-03-17 07:45:00 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
// No copying allowed.
|
|
|
|
parser_t(const parser_t &);
|
|
|
|
parser_t &operator=(const parser_t &);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Adds a job to the beginning of the job list.
|
2017-01-27 06:47:32 +08:00
|
|
|
void job_add(shared_ptr<job_t> job);
|
Big fat refactoring of how redirections work. In fish 1.x and 2.0.0, the redirections for a process were flattened into a big list associated with the job, so there was no way to tell which redirections applied to each process. Each process therefore got all the redirections associated with the job. See https://github.com/fish-shell/fish-shell/issues/877 for how this could manifest.
With this change, jobs only track their block-level redirections. Process level redirections are correctly associated with the process, and at exec time we stitch them together (block, pipe, and process redirects).
This fixes the weird issues where redirects bleed across pipelines (like #877), and also allows us to play with the order in which redirections are applied, since the final list is constructed right before it's needed. This lets us put pipes after block level redirections but before process level redirections, so that a 2>&1-type redirection gets picked up after the pipe, i.e. it should fix https://github.com/fish-shell/fish-shell/issues/110
This is a significant change. The tests all pass. Cross your fingers.
2013-08-20 07:16:41 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the name of the currently evaluated function if we are currently evaluating a
|
|
|
|
/// function, null otherwise. This is tested by moving down the block-scope-stack, checking
|
|
|
|
/// every block if it is of type FUNCTION_CALL.
|
2017-06-24 14:19:09 +08:00
|
|
|
const wchar_t *is_function(size_t idx = 0) const;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2018-09-22 12:52:47 +08:00
|
|
|
// Given a file path, return something nicer. Currently we just "unexpand" tildes.
|
|
|
|
wcstring user_presentable_path(const wcstring &path) const;
|
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Helper for stack_trace().
|
2015-09-22 02:24:49 +08:00
|
|
|
void stack_trace_internal(size_t block_idx, wcstring *out) const;
|
|
|
|
|
2018-09-09 16:36:21 +08:00
|
|
|
/// Create a parser.
|
|
|
|
parser_t();
|
2019-05-21 00:27:46 +08:00
|
|
|
parser_t(std::shared_ptr<env_stack_t> vars);
|
2018-09-09 16:36:21 +08:00
|
|
|
|
|
|
|
/// The main parser.
|
2019-02-25 04:12:24 +08:00
|
|
|
static std::shared_ptr<parser_t> principal;
|
2018-09-09 16:36:21 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
public:
|
|
|
|
/// Get the "principal" parser, whatever that is.
|
2012-01-23 13:40:08 +08:00
|
|
|
static parser_t &principal_parser();
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Indicates that execution of all blocks in the principal parser should stop. This is called
|
|
|
|
/// from signal handlers!
|
2012-06-05 05:20:01 +08:00
|
|
|
static void skip_all_blocks();
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Global event blocks.
|
2012-08-27 13:42:29 +08:00
|
|
|
event_blockage_list_t global_event_blocks;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Evaluate the expressions contained in cmd.
|
|
|
|
///
|
|
|
|
/// \param cmd the string to evaluate
|
|
|
|
/// \param io io redirections to perform on all started jobs
|
|
|
|
/// \param block_type The type of block to push on the block stack
|
|
|
|
///
|
2018-02-12 15:13:06 +08:00
|
|
|
/// \return 0 on success, 1 on a parse error.
|
2019-04-02 11:19:28 +08:00
|
|
|
int eval(wcstring cmd, const io_chain_t &io, enum block_type_t block_type);
|
2012-01-17 03:09:19 +08:00
|
|
|
|
2017-12-23 06:40:15 +08:00
|
|
|
/// Evaluate the parsed source ps.
|
2019-04-14 05:57:00 +08:00
|
|
|
/// \return 0 on success, 1 on a parse error.
|
|
|
|
int eval(parsed_source_ref_t ps, const io_chain_t &io, enum block_type_t block_type);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2018-02-12 11:34:12 +08:00
|
|
|
/// Evaluates a node.
|
2018-02-11 11:16:35 +08:00
|
|
|
/// The node type must be grammar::statement or grammar::job_list.
|
|
|
|
template <typename T>
|
2018-02-12 11:34:12 +08:00
|
|
|
int eval_node(parsed_source_ref_t ps, tnode_t<T> node, const io_chain_t &io,
|
2018-11-04 15:58:44 +08:00
|
|
|
block_type_t block_type, std::shared_ptr<job_t> parent_job);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Evaluate line as a list of parameters, i.e. tokenize it and perform parameter expansion and
|
2019-05-05 10:16:26 +08:00
|
|
|
/// cmdsubst execution on the tokens. Errors are ignored. If a parser is provided, it is used
|
|
|
|
/// for command substitution expansion.
|
|
|
|
static std::vector<completion_t> expand_argument_list(const wcstring &arg_list_src,
|
|
|
|
expand_flags_t flags,
|
|
|
|
const environment_t &vars,
|
|
|
|
const std::shared_ptr<parser_t> &parser);
|
2016-05-03 08:22:44 +08:00
|
|
|
|
2017-06-24 13:14:21 +08:00
|
|
|
/// Returns a string describing the current parser position in the format 'FILENAME (line
|
2016-05-03 08:22:44 +08:00
|
|
|
/// LINE_NUMBER): LINE'. Example:
|
|
|
|
///
|
|
|
|
/// init.fish (line 127): ls|grep pancake
|
2014-03-17 05:49:51 +08:00
|
|
|
wcstring current_line();
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the current line number.
|
2012-01-17 03:16:12 +08:00
|
|
|
int get_lineno() const;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the block at the given index. 0 corresponds to the innermost block. Returns NULL
|
|
|
|
/// when idx is at or equal to the number of blocks.
|
2013-12-21 09:41:21 +08:00
|
|
|
const block_t *block_at_index(size_t idx) const;
|
|
|
|
block_t *block_at_index(size_t idx);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the current (innermost) block.
|
2016-07-31 02:48:39 +08:00
|
|
|
block_t *current_block();
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Count of blocks.
|
|
|
|
size_t block_count() const { return block_stack.size(); }
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Get the list of jobs.
|
2019-05-05 13:12:31 +08:00
|
|
|
job_list_t &jobs() { return job_list; }
|
|
|
|
const job_list_t &jobs() const { return job_list; }
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2018-09-10 16:17:57 +08:00
|
|
|
/// Get the variables.
|
2019-05-21 00:27:46 +08:00
|
|
|
env_stack_t &vars() { return *variables; }
|
|
|
|
const env_stack_t &vars() const { return *variables; }
|
2018-09-10 16:17:57 +08:00
|
|
|
|
2019-04-29 07:11:49 +08:00
|
|
|
/// Get the library data.
|
|
|
|
library_data_t &libdata() { return library_data; }
|
|
|
|
const library_data_t &libdata() const { return library_data; }
|
|
|
|
|
2019-05-13 05:00:44 +08:00
|
|
|
/// Get and set the last proc statuses.
|
|
|
|
int get_last_status() const { return vars().get_last_status(); }
|
|
|
|
statuses_t get_last_statuses() const { return vars().get_last_statuses(); }
|
|
|
|
void set_last_statuses(statuses_t s) { vars().set_last_statuses(std::move(s)); }
|
|
|
|
|
2019-05-20 05:40:06 +08:00
|
|
|
/// Pushes a new block. Returns a pointer to the block, stored in the parser. The pointer is
|
|
|
|
/// valid until the call to pop_block()
|
|
|
|
block_t *push_block(block_t &&b);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Remove the outermost block, asserting it's the given one.
|
2013-12-27 04:24:00 +08:00
|
|
|
void pop_block(const block_t *b);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Return a description of the given blocktype.
|
2012-11-19 08:30:30 +08:00
|
|
|
const wchar_t *get_block_desc(int block) const;
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2017-06-24 13:14:21 +08:00
|
|
|
/// Return the function name for the specified stack frame. Default is one (current frame).
|
2017-06-24 14:19:09 +08:00
|
|
|
const wchar_t *get_function_name(int level = 1);
|
2017-04-13 06:34:25 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Promotes a job to the front of the list.
|
2012-02-28 10:43:24 +08:00
|
|
|
void job_promote(job_t *job);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Return the job with the specified job id. If id is 0 or less, return the last job used.
|
2017-01-27 06:47:32 +08:00
|
|
|
job_t *job_get(job_id_t job_id);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the job with the given pid.
|
2018-08-10 07:46:11 +08:00
|
|
|
job_t *job_get_from_pid(pid_t pid) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns a new profile item if profiling is active. The caller should fill it in. The
|
|
|
|
/// parser_t will clean it up.
|
2014-02-10 06:04:43 +08:00
|
|
|
profile_item_t *create_profile_item();
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
void get_backtrace(const wcstring &src, const parse_error_list_t &errors,
|
2017-06-18 13:36:56 +08:00
|
|
|
wcstring &output) const;
|
2016-05-03 08:22:44 +08:00
|
|
|
|
|
|
|
/// Detect errors in the specified string when parsed as an argument list. Returns true if an
|
|
|
|
/// error occurred.
|
|
|
|
bool detect_errors_in_argument_list(const wcstring &arg_list_src, wcstring *out_err,
|
2018-08-10 07:46:11 +08:00
|
|
|
const wchar_t *prefix) const;
|
2016-05-03 08:22:44 +08:00
|
|
|
|
|
|
|
/// Tell the parser that the specified function may not be run if not inside of a conditional
|
|
|
|
/// block. This is to remove some possibilities of infinite recursion.
|
2012-11-19 08:30:30 +08:00
|
|
|
void forbid_function(const wcstring &function);
|
2014-03-19 05:42:38 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Undo last call to parser_forbid_function().
|
2012-01-17 03:09:19 +08:00
|
|
|
void allow_function();
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Output profiling data to the given filename.
|
2014-02-10 06:04:43 +08:00
|
|
|
void emit_profiling(const char *path) const;
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Returns the file currently evaluated by the parser. This can be different than
|
|
|
|
/// reader_current_filename, e.g. if we are evaulating a function defined in a different file
|
|
|
|
/// than the one curently read.
|
2012-01-17 03:16:12 +08:00
|
|
|
const wchar_t *current_filename() const;
|
2006-01-26 23:47:22 +08:00
|
|
|
|
2016-05-03 08:22:44 +08:00
|
|
|
/// Return a string representing the current stack trace.
|
2015-09-22 02:24:49 +08:00
|
|
|
wcstring stack_trace() const;
|
2017-01-22 06:53:10 +08:00
|
|
|
|
2019-05-05 09:17:18 +08:00
|
|
|
/// \return a shared pointer reference to this parser.
|
|
|
|
std::shared_ptr<parser_t> shared();
|
|
|
|
|
2017-01-22 06:53:10 +08:00
|
|
|
~parser_t();
|
2012-01-17 03:16:12 +08:00
|
|
|
};
|
2006-09-06 04:43:47 +08:00
|
|
|
|
2005-10-04 23:11:39 +08:00
|
|
|
#endif
|