2005-09-20 21:26:39 +08:00
|
|
|
/** \file parser.h
|
2012-11-18 18:23:22 +08:00
|
|
|
The fish parser.
|
2005-09-20 21:26:39 +08:00
|
|
|
*/
|
|
|
|
|
2005-10-04 23:11:39 +08:00
|
|
|
#ifndef FISH_PARSER_H
|
|
|
|
#define FISH_PARSER_H
|
|
|
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
#include "proc.h"
|
|
|
|
#include "util.h"
|
2006-02-01 23:49:11 +08:00
|
|
|
#include "event.h"
|
2012-02-08 14:10:35 +08:00
|
|
|
#include "function.h"
|
2013-12-13 10:18:07 +08:00
|
|
|
#include "parse_tree.h"
|
2012-01-17 03:09:19 +08:00
|
|
|
#include <vector>
|
2005-10-04 23:11:39 +08:00
|
|
|
|
2006-01-24 04:40:14 +08:00
|
|
|
/**
|
2012-08-27 13:42:29 +08:00
|
|
|
event_blockage_t represents a block on events of the specified type
|
2006-01-24 04:40:14 +08:00
|
|
|
*/
|
2012-08-27 13:42:29 +08:00
|
|
|
struct event_blockage_t
|
2005-12-12 06:21:01 +08:00
|
|
|
{
|
2012-11-19 08:30:30 +08:00
|
|
|
/**
|
|
|
|
The types of events to block. This is interpreted as a bitset
|
|
|
|
whete the value is 1 for every bit corresponding to a blocked
|
|
|
|
event type. For example, if EVENT_VARIABLE type events should
|
|
|
|
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
|
|
|
|
|
|
|
|
Note that EVENT_ANY can be used to specify any event.
|
|
|
|
*/
|
|
|
|
unsigned int typemask;
|
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
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
inline bool event_block_list_blocks_type(const event_blockage_list_t &ebls, int type)
|
|
|
|
{
|
|
|
|
for (event_blockage_list_t::const_iterator iter = ebls.begin(); iter != ebls.end(); ++iter)
|
|
|
|
{
|
|
|
|
if (iter->typemask & (1<<EVENT_ANY))
|
2012-02-08 13:04:51 +08:00
|
|
|
return true;
|
2012-11-19 08:30:30 +08:00
|
|
|
if (iter->typemask & (1<<type))
|
2012-02-08 13:04:51 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2005-12-12 06:21:01 +08:00
|
|
|
|
|
|
|
|
2012-11-18 18:23:22 +08:00
|
|
|
/**
|
|
|
|
Types of blocks
|
2012-08-27 13:42:29 +08:00
|
|
|
*/
|
|
|
|
enum block_type_t
|
|
|
|
{
|
2012-11-19 08:30:30 +08:00
|
|
|
WHILE, /**< While loop block */
|
|
|
|
FOR, /**< For loop block */
|
|
|
|
IF, /**< If block */
|
|
|
|
FUNCTION_DEF, /**< Function definition block */
|
|
|
|
FUNCTION_CALL, /**< Function invocation block */
|
|
|
|
FUNCTION_CALL_NO_SHADOW, /**< Function invocation block with no variable shadowing */
|
|
|
|
SWITCH, /**< Switch block */
|
|
|
|
FAKE, /**< Fake 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
|
|
|
|
2005-09-20 21:26:39 +08:00
|
|
|
/**
|
2012-11-18 18:23:22 +08:00
|
|
|
block_t represents a block of commands.
|
2005-09-20 21:26:39 +08:00
|
|
|
*/
|
2012-08-27 13:42:29 +08:00
|
|
|
struct block_t
|
2005-09-20 21:26:39 +08:00
|
|
|
{
|
2012-11-19 08:30:30 +08:00
|
|
|
protected:
|
2012-08-27 14:16:20 +08:00
|
|
|
/** Protected constructor. Use one of the subclasses below. */
|
|
|
|
block_t(block_type_t t);
|
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
private:
|
|
|
|
const block_type_t block_type; /**< Type of block. */
|
2012-08-27 14:16:20 +08:00
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
public:
|
|
|
|
block_type_t type() const
|
|
|
|
{
|
2014-03-03 05:46:30 +08:00
|
|
|
return this->block_type;
|
2012-11-19 08:30:30 +08:00
|
|
|
}
|
2012-08-27 14:16:20 +08:00
|
|
|
|
2014-03-17 07:45:00 +08:00
|
|
|
/** Description of the block, for debugging */
|
|
|
|
wcstring description() const;
|
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
bool skip; /**< Whether execution of the commands in this block should be skipped */
|
|
|
|
int tok_pos; /**< The start index of the block */
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-25 05:17:24 +08:00
|
|
|
node_offset_t node_offset; /* Offset of the node */
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2013-12-24 06:53:56 +08:00
|
|
|
/** Status for the current loop block. Can be any of the values from the loop_status enum. */
|
2012-11-19 08:30:30 +08:00
|
|
|
int loop_status;
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2013-12-24 06:53:56 +08:00
|
|
|
/** The job that is currently evaluated in the specified block. */
|
2012-11-19 08:30:30 +08:00
|
|
|
job_t *job;
|
2012-09-01 16:46:14 +08:00
|
|
|
|
2014-03-17 07:45:00 +08:00
|
|
|
/** Name of file that created this block. This string is intern'd. */
|
2012-11-19 08:30:30 +08:00
|
|
|
const wchar_t *src_filename;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2013-12-24 06:53:56 +08:00
|
|
|
/** Line number where this block was created */
|
2012-11-19 08:30:30 +08:00
|
|
|
int src_lineno;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-08 13:04:51 +08:00
|
|
|
/** Whether we should pop the environment variable stack when we're popped off of the block stack */
|
2012-02-08 09:06:45 +08:00
|
|
|
bool wants_pop_env;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
/** List of event blocks. */
|
|
|
|
event_blockage_list_t event_blocks;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-08 09:06:45 +08:00
|
|
|
/** Destructor */
|
2012-08-27 13:42:29 +08:00
|
|
|
virtual ~block_t();
|
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct if_block_t : public block_t
|
|
|
|
{
|
2012-08-27 14:16:20 +08:00
|
|
|
if_block_t();
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct event_block_t : public block_t
|
|
|
|
{
|
2012-12-23 04:40:34 +08:00
|
|
|
event_t const event;
|
2012-12-23 01:38:28 +08:00
|
|
|
event_block_t(const event_t &evt);
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct function_block_t : public block_t
|
|
|
|
{
|
2013-01-30 18:22:38 +08:00
|
|
|
const process_t *process;
|
2012-08-27 13:42:29 +08:00
|
|
|
wcstring name;
|
2013-01-30 18:22:38 +08:00
|
|
|
function_block_t(const process_t *p, const wcstring &n, bool shadows);
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct source_block_t : public block_t
|
|
|
|
{
|
2012-08-27 13:42:29 +08:00
|
|
|
const wchar_t * const source_file;
|
2012-08-27 14:16:20 +08:00
|
|
|
source_block_t(const wchar_t *src);
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct for_block_t : public block_t
|
|
|
|
{
|
2014-03-03 05:46:30 +08:00
|
|
|
for_block_t();
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct while_block_t : public block_t
|
|
|
|
{
|
2012-08-27 14:16:20 +08:00
|
|
|
while_block_t();
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct switch_block_t : public block_t
|
|
|
|
{
|
2014-03-03 05:46:30 +08:00
|
|
|
switch_block_t();
|
2012-08-27 14:16:20 +08:00
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct fake_block_t : public block_t
|
|
|
|
{
|
2012-08-27 14:16:20 +08:00
|
|
|
fake_block_t();
|
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct scope_block_t : public block_t
|
|
|
|
{
|
2012-08-27 14:16:20 +08:00
|
|
|
scope_block_t(block_type_t type); //must be BEGIN, TOP or SUBST
|
|
|
|
};
|
|
|
|
|
2012-08-27 14:34:34 +08:00
|
|
|
struct breakpoint_block_t : public block_t
|
|
|
|
{
|
2012-08-27 14:16:20 +08:00
|
|
|
breakpoint_block_t();
|
2012-08-27 13:42:29 +08:00
|
|
|
};
|
2005-09-20 21:26:39 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
Possible states for a loop
|
|
|
|
*/
|
2012-11-18 18:23:22 +08:00
|
|
|
enum loop_status
|
2005-09-20 21:26:39 +08:00
|
|
|
{
|
2012-11-19 08:30:30 +08:00
|
|
|
LOOP_NORMAL, /**< Current loop block executed as normal */
|
|
|
|
LOOP_BREAK, /**< Current loop block should be removed */
|
|
|
|
LOOP_CONTINUE, /**< Current loop block should be skipped */
|
2005-09-20 21:26:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Errors that can be generated by the parser
|
|
|
|
*/
|
2012-11-18 18:23:22 +08:00
|
|
|
enum parser_error
|
2005-09-20 21:26:39 +08:00
|
|
|
{
|
2012-11-19 08:30:30 +08:00
|
|
|
/**
|
|
|
|
No error
|
|
|
|
*/
|
|
|
|
NO_ERR=0,
|
|
|
|
/**
|
|
|
|
An error in the syntax
|
|
|
|
*/
|
|
|
|
SYNTAX_ERROR,
|
|
|
|
/**
|
|
|
|
Error occured while evaluating commands
|
|
|
|
*/
|
|
|
|
EVAL_ERROR,
|
|
|
|
/**
|
|
|
|
Error while evaluating cmdsubst
|
|
|
|
*/
|
|
|
|
CMDSUBST_ERROR,
|
2012-01-17 03:09:19 +08:00
|
|
|
};
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
enum parser_type_t
|
|
|
|
{
|
2012-01-17 04:10:08 +08:00
|
|
|
PARSER_TYPE_NONE,
|
|
|
|
PARSER_TYPE_GENERAL,
|
|
|
|
PARSER_TYPE_FUNCTIONS_ONLY,
|
2012-01-31 02:28:30 +08:00
|
|
|
PARSER_TYPE_COMPLETIONS_ONLY,
|
2012-11-19 08:30:30 +08:00
|
|
|
PARSER_TYPE_ERRORS_ONLY
|
2012-01-17 04:10:08 +08:00
|
|
|
};
|
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
struct profile_item_t
|
|
|
|
{
|
2014-02-10 06:04:43 +08:00
|
|
|
/** Time spent executing the specified command, including parse time for nested blocks. */
|
2012-11-19 08:30:30 +08:00
|
|
|
int exec;
|
2014-02-10 06:04:43 +08:00
|
|
|
|
|
|
|
/** Time spent parsing the specified command, including execution time for command substitutions. */
|
2012-11-19 08:30:30 +08:00
|
|
|
int parse;
|
2014-02-10 06:04:43 +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;
|
2014-02-10 06:04:43 +08:00
|
|
|
|
|
|
|
/** If the execution of this command was skipped. */
|
|
|
|
bool skipped;
|
|
|
|
|
|
|
|
/** 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
|
|
|
|
2012-11-22 09:48:35 +08:00
|
|
|
struct tokenizer_t;
|
2013-12-27 05:24:10 +08:00
|
|
|
class parse_execution_context_t;
|
2012-01-23 12:47:13 +08:00
|
|
|
|
2012-11-19 08:30:30 +08:00
|
|
|
class parser_t
|
|
|
|
{
|
2013-12-25 05:17:24 +08:00
|
|
|
friend class parse_execution_context_t;
|
2012-11-19 08:30:30 +08:00
|
|
|
private:
|
2012-01-23 13:40:08 +08:00
|
|
|
enum parser_type_t parser_type;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-05-07 04:36:51 +08:00
|
|
|
/** Whether or not we output errors */
|
|
|
|
const bool show_errors;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2014-01-03 04:37:50 +08:00
|
|
|
/** Indication that we should skip all blocks */
|
|
|
|
bool cancellation_requested;
|
2014-02-21 02:57:13 +08:00
|
|
|
|
|
|
|
/** Indicates that we are within the process of initializing fish */
|
|
|
|
bool is_within_fish_initialization;
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-27 05:24:10 +08:00
|
|
|
/** Stack of execution contexts. We own these pointers and must delete them */
|
|
|
|
std::vector<parse_execution_context_t *> execution_contexts;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-01-23 13:57:30 +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;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** The jobs associated with this parser */
|
|
|
|
job_list_t my_job_list;
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-21 09:41:21 +08:00
|
|
|
/** The list of blocks, allocated with new. It's our responsibility to delete these */
|
|
|
|
std::vector<block_t *> block_stack;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2014-03-17 07:45:00 +08:00
|
|
|
/** Gets a description of the block stack, for debugging */
|
|
|
|
wcstring block_stack_description() const;
|
|
|
|
|
|
|
|
/** List of profile items, allocated with new */
|
2014-03-19 05:42:38 +08:00
|
|
|
std::vector<profile_item_t *> profile_items;
|
2014-03-17 07:45:00 +08:00
|
|
|
|
2012-01-17 04:10:08 +08:00
|
|
|
/* No copying allowed */
|
|
|
|
parser_t(const parser_t&);
|
|
|
|
parser_t& operator=(const parser_t&);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
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
|
|
|
/** Create a job */
|
2013-12-27 05:24:10 +08:00
|
|
|
job_t *job_create(const io_chain_t &io);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-27 17:38:43 +08:00
|
|
|
/** Adds a job to the beginning of the job list. */
|
|
|
|
void job_add(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
|
|
|
|
2012-04-22 11:08:08 +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.
|
|
|
|
*/
|
|
|
|
const wchar_t *is_function() const;
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2014-03-17 07:45:00 +08:00
|
|
|
public:
|
|
|
|
|
2012-01-23 13:40:08 +08:00
|
|
|
/** Get the "principal" parser, whatever that is */
|
|
|
|
static parser_t &principal_parser();
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-06-05 05:20:01 +08:00
|
|
|
/** Indicates that execution of all blocks in the principal parser should stop.
|
|
|
|
This is called from signal handlers!
|
|
|
|
*/
|
|
|
|
static void skip_all_blocks();
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-01-17 04:10:08 +08:00
|
|
|
/** Create a parser of the given type */
|
2012-05-07 04:36:51 +08:00
|
|
|
parser_t(enum parser_type_t type, bool show_errors);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-01-17 03:09:19 +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
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
|
|
|
Evaluate the expressions contained in cmd.
|
2005-12-08 00:06:47 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
\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
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
\return 0 on success, 1 otherwise
|
|
|
|
*/
|
2014-03-22 08:13:33 +08:00
|
|
|
int eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-27 17:38:43 +08:00
|
|
|
/** Evaluates a block node at the given node offset in the topmost execution context */
|
|
|
|
int eval_block_node(node_offset_t node_idx, const io_chain_t &io, enum block_type_t block_type);
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
|
|
|
Evaluate line as a list of parameters, i.e. tokenize it and perform parameter expansion and cmdsubst execution on the tokens.
|
2013-06-10 05:21:24 +08:00
|
|
|
The output is inserted into output.
|
2014-03-17 23:45:25 +08:00
|
|
|
Errors are ignored.
|
2012-01-17 03:09:19 +08:00
|
|
|
|
2014-03-17 23:45:25 +08:00
|
|
|
\param arg_src String to evaluate as an argument list
|
|
|
|
\param output List to insert output into
|
2012-01-17 03:09:19 +08:00
|
|
|
*/
|
2014-03-19 05:14:32 +08:00
|
|
|
void expand_argument_list(const wcstring &arg_src, std::vector<completion_t> &output);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
|
|
|
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
|
2012-11-18 18:23:22 +08:00
|
|
|
Example:
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
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
|
|
|
|
2012-02-28 10:43:24 +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
|
|
|
|
2013-12-21 09:41:21 +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. */
|
|
|
|
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
|
|
|
|
2013-12-21 09:41:21 +08:00
|
|
|
/** Returns the current (innermost) block */
|
|
|
|
const block_t *current_block() const;
|
|
|
|
block_t *current_block();
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-21 09:41:21 +08:00
|
|
|
/** Count of blocks */
|
|
|
|
size_t block_count() const
|
|
|
|
{
|
|
|
|
return block_stack.size();
|
|
|
|
}
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Get the list of jobs */
|
2012-11-19 08:30:30 +08:00
|
|
|
job_list_t &job_list()
|
|
|
|
{
|
|
|
|
return my_job_list;
|
|
|
|
}
|
2014-02-21 02:57:13 +08:00
|
|
|
|
|
|
|
/* 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);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-08-27 13:42:29 +08:00
|
|
|
/** Pushes the block. pop_block will call delete on it. */
|
2012-11-19 08:30:30 +08:00
|
|
|
void push_block(block_t *newv);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Remove the outermost block namespace */
|
2012-01-17 03:09:19 +08:00
|
|
|
void pop_block();
|
2014-01-15 17:40:40 +08:00
|
|
|
|
2013-12-27 04:24:00 +08:00
|
|
|
/** Remove the outermost block, asserting it's the given one */
|
|
|
|
void pop_block(const block_t *b);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-02-28 10:43:24 +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
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Removes a job */
|
|
|
|
bool job_remove(job_t *job);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Promotes a job to the front of the list */
|
|
|
|
void job_promote(job_t *job);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Return the job with the specified job id. If id is 0 or less, return the last job used. */
|
|
|
|
job_t *job_get(int job_id);
|
2012-11-18 18:23:22 +08:00
|
|
|
|
2012-02-28 10:43:24 +08:00
|
|
|
/** Returns the job with the given pid */
|
2012-11-19 08:30:30 +08:00
|
|
|
job_t *job_get_from_pid(int pid);
|
2014-02-10 06:04:43 +08:00
|
|
|
|
|
|
|
/* Returns a new profile item if profiling is active. The caller should fill it in. The parser_t will clean it up. */
|
|
|
|
profile_item_t *create_profile_item();
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
|
|
|
Test if the specified string can be parsed, or if more bytes need
|
|
|
|
to be read first. The result will have the PARSER_TEST_ERROR bit
|
|
|
|
set if there is a syntax error in the code, and the
|
|
|
|
PARSER_TEST_INCOMPLETE bit set if the code contains unclosed
|
|
|
|
blocks.
|
|
|
|
|
|
|
|
\param buff the text buffer to test
|
|
|
|
\param block_level if non-null, the block nesting level will be filled out into this array
|
|
|
|
\param out if non-null, any errors in the command will be filled out into this buffer
|
|
|
|
\param prefix the prefix string to prepend to each error message written to the \c out buffer
|
|
|
|
*/
|
2013-12-16 08:05:37 +08:00
|
|
|
void get_backtrace(const wcstring &src, const parse_error_list_t &errors, wcstring *output) const;
|
2006-05-22 03:25:24 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
2014-03-19 05:14:32 +08:00
|
|
|
Detect errors in the specified string when parsed as an argument list. Returns true if an error occurred.
|
2012-01-17 03:09:19 +08:00
|
|
|
*/
|
2014-03-19 05:14:32 +08:00
|
|
|
bool detect_errors_in_argument_list(const wcstring &arg_list_src, wcstring *out_err, const wchar_t *prefix);
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +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
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
|
|
|
Undo last call to parser_forbid_function().
|
|
|
|
*/
|
|
|
|
void allow_function();
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
2014-02-10 06:04:43 +08:00
|
|
|
Output profiling data to the given filename
|
2012-01-17 03:09:19 +08:00
|
|
|
*/
|
2014-02-10 06:04:43 +08:00
|
|
|
void emit_profiling(const char *path) const;
|
2005-09-20 21:26:39 +08:00
|
|
|
|
2012-01-17 03:09:19 +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
|
|
|
|
2012-01-17 03:09:19 +08:00
|
|
|
/**
|
2012-02-23 02:51:06 +08:00
|
|
|
Write a stack trace starting at the specified block to the specified wcstring
|
2012-01-17 03:09:19 +08:00
|
|
|
*/
|
2013-12-21 09:44:37 +08:00
|
|
|
void stack_trace(size_t block_idx, wcstring &buff) const;
|
2012-01-17 03:16:12 +08:00
|
|
|
};
|
2006-09-06 04:43:47 +08:00
|
|
|
|
2013-12-27 05:24:10 +08:00
|
|
|
/* Temporary */
|
|
|
|
bool parser_use_ast(void);
|
|
|
|
|
2006-01-26 23:47:22 +08:00
|
|
|
|
2005-10-04 23:11:39 +08:00
|
|
|
#endif
|