mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-09 12:11:20 -03:00
restyle parse_execution module to match project style
Reduces lint errors from 184 to 84 (-54%). Line count from 2139 to 1943 (-9%). Another step in resolving issue #2902.
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
/**\file parse_constants.h
|
||||
|
||||
Constants used in the programmatic representation of fish code.
|
||||
*/
|
||||
// Constants used in the programmatic representation of fish code.
|
||||
#ifndef FISH_PARSE_CONSTANTS_H
|
||||
#define FISH_PARSE_CONSTANTS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define PARSE_ASSERT(a) assert(a)
|
||||
#define PARSER_DIE() do { fprintf(stderr, "Parser dying!\n"); exit_without_destructors(-1); } while (0)
|
||||
#define PARSER_DIE() \
|
||||
do { \
|
||||
fprintf(stderr, "Parser dying!\n"); \
|
||||
exit_without_destructors(-1); \
|
||||
} while (0)
|
||||
|
||||
// IMPORTANT: If the following enum is modified you must update the corresponding parser_token_types
|
||||
// array in parse_tree.cpp.
|
||||
enum parse_token_type_t
|
||||
{
|
||||
enum parse_token_type_t {
|
||||
token_type_invalid,
|
||||
|
||||
// Non-terminal tokens
|
||||
@@ -47,8 +47,8 @@ enum parse_token_type_t
|
||||
|
||||
symbol_argument_list,
|
||||
|
||||
// "freestanding" argument lists are parsed from the argument list supplied to 'complete -a'
|
||||
// They are not generated by parse trees rooted in symbol_job_list
|
||||
// Freestanding argument lists are parsed from the argument list supplied to 'complete -a'
|
||||
// They are not generated by parse trees rooted in symbol_job_list.
|
||||
symbol_freestanding_argument_list,
|
||||
|
||||
symbol_argument,
|
||||
@@ -58,17 +58,17 @@ enum parse_token_type_t
|
||||
|
||||
symbol_end_command,
|
||||
|
||||
// Terminal types
|
||||
// Terminal types.
|
||||
parse_token_type_string,
|
||||
parse_token_type_pipe,
|
||||
parse_token_type_redirection,
|
||||
parse_token_type_background,
|
||||
parse_token_type_end,
|
||||
|
||||
// Special terminal type that means no more tokens forthcoming
|
||||
// Special terminal type that means no more tokens forthcoming.
|
||||
parse_token_type_terminate,
|
||||
|
||||
// Very special terminal types that don't appear in the production list
|
||||
// Very special terminal types that don't appear in the production list.
|
||||
parse_special_type_parse_error,
|
||||
parse_special_type_tokenizer_error,
|
||||
parse_special_type_comment,
|
||||
@@ -83,15 +83,14 @@ enum parse_token_type_t
|
||||
LAST_PARSE_TOKEN_TYPE = parse_token_type_end
|
||||
} __packed;
|
||||
// Array of strings corresponding to the enums above instantiated in parse_tree.cpp.
|
||||
extern const wchar_t * const parser_token_types[];
|
||||
extern const wchar_t *const parser_token_types[];
|
||||
|
||||
// These must be maintained in sorted order (except for none, which isn't a keyword). This enables
|
||||
// us to do binary search.
|
||||
//
|
||||
// IMPORTANT: If the following enum is modified you must update the corresponding keyword_map array
|
||||
// in parse_tree.cpp.
|
||||
enum parse_keyword_t
|
||||
{
|
||||
enum parse_keyword_t {
|
||||
parse_keyword_none,
|
||||
parse_keyword_and,
|
||||
parse_keyword_begin,
|
||||
@@ -112,261 +111,206 @@ enum parse_keyword_t
|
||||
LAST_KEYWORD = parse_keyword_while
|
||||
} __packed;
|
||||
|
||||
/* Node tag values */
|
||||
// Node tag values.
|
||||
|
||||
/* Statement decorations, stored in node tag */
|
||||
enum parse_statement_decoration_t
|
||||
{
|
||||
// Statement decorations, stored in node tag.
|
||||
enum parse_statement_decoration_t {
|
||||
parse_statement_decoration_none,
|
||||
parse_statement_decoration_command,
|
||||
parse_statement_decoration_builtin,
|
||||
parse_statement_decoration_exec
|
||||
};
|
||||
|
||||
/* Boolean statement types, stored in node tag */
|
||||
enum parse_bool_statement_type_t
|
||||
{
|
||||
parse_bool_and,
|
||||
parse_bool_or,
|
||||
parse_bool_not
|
||||
};
|
||||
// Boolean statement types, stored in node tag.
|
||||
enum parse_bool_statement_type_t { parse_bool_and, parse_bool_or, parse_bool_not };
|
||||
|
||||
/* Whether a statement is backgrounded */
|
||||
enum parse_optional_background_t
|
||||
{
|
||||
parse_no_background,
|
||||
parse_background
|
||||
};
|
||||
// Whether a statement is backgrounded.
|
||||
enum parse_optional_background_t { parse_no_background, parse_background };
|
||||
|
||||
/* Parse error code list */
|
||||
enum parse_error_code_t
|
||||
{
|
||||
// Parse error code list.
|
||||
enum parse_error_code_t {
|
||||
parse_error_none,
|
||||
|
||||
/* Matching values from enum parser_error */
|
||||
// Matching values from enum parser_error.
|
||||
parse_error_syntax,
|
||||
parse_error_eval,
|
||||
parse_error_cmdsubst,
|
||||
|
||||
parse_error_generic, // unclassified error types
|
||||
parse_error_generic, // unclassified error types
|
||||
|
||||
//tokenizer errors
|
||||
// Tokenizer errors.
|
||||
parse_error_tokenizer_unterminated_quote,
|
||||
parse_error_tokenizer_unterminated_subshell,
|
||||
parse_error_tokenizer_unterminated_slice,
|
||||
parse_error_tokenizer_unterminated_escape,
|
||||
parse_error_tokenizer_other,
|
||||
|
||||
parse_error_unbalancing_end, //end outside of block
|
||||
parse_error_unbalancing_else, //else outside of if
|
||||
parse_error_unbalancing_case, //case outside of switch
|
||||
parse_error_unbalancing_end, // end outside of block
|
||||
parse_error_unbalancing_else, // else outside of if
|
||||
parse_error_unbalancing_case, // case outside of switch
|
||||
|
||||
parse_error_double_pipe, // foo || bar, has special error message
|
||||
parse_error_double_background // foo && bar, has special error message
|
||||
parse_error_double_pipe, // foo || bar, has special error message
|
||||
parse_error_double_background // foo && bar, has special error message
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PARSER_TEST_ERROR = 1,
|
||||
PARSER_TEST_INCOMPLETE = 2
|
||||
};
|
||||
enum { PARSER_TEST_ERROR = 1, PARSER_TEST_INCOMPLETE = 2 };
|
||||
typedef unsigned int parser_test_error_bits_t;
|
||||
|
||||
struct parse_error_t
|
||||
{
|
||||
/** Text of the error */
|
||||
struct parse_error_t {
|
||||
/// Text of the error.
|
||||
wcstring text;
|
||||
|
||||
/** Code for the error */
|
||||
/// Code for the error.
|
||||
enum parse_error_code_t code;
|
||||
|
||||
/** Offset and length of the token in the source code that triggered this error */
|
||||
/// Offset and length of the token in the source code that triggered this error.
|
||||
size_t source_start;
|
||||
size_t source_length;
|
||||
|
||||
/** Return a string describing the error, suitable for presentation to the user. If skip_caret is false, the offending line with a caret is printed as well */
|
||||
/// Return a string describing the error, suitable for presentation to the user. If skip_caret
|
||||
/// is false, the offending line with a caret is printed as well.
|
||||
wcstring describe(const wcstring &src) const;
|
||||
|
||||
/** Return a string describing the error, suitable for presentation to the user, with the given prefix. If skip_caret is false, the offending line with a caret is printed as well */
|
||||
wcstring describe_with_prefix(const wcstring &src, const wcstring &prefix, bool is_interactive, bool skip_caret) const;
|
||||
/// Return a string describing the error, suitable for presentation to the user, with the given
|
||||
/// prefix. If skip_caret is false, the offending line with a caret is printed as well.
|
||||
wcstring describe_with_prefix(const wcstring &src, const wcstring &prefix, bool is_interactive,
|
||||
bool skip_caret) const;
|
||||
};
|
||||
typedef std::vector<parse_error_t> parse_error_list_t;
|
||||
|
||||
/* Special source_start value that means unknown */
|
||||
// Special source_start value that means unknown.
|
||||
#define SOURCE_LOCATION_UNKNOWN (static_cast<size_t>(-1))
|
||||
|
||||
/* Helper function to offset error positions by the given amount. This is used when determining errors in a substring of a larger source buffer. */
|
||||
/// Helper function to offset error positions by the given amount. This is used when determining
|
||||
/// errors in a substring of a larger source buffer.
|
||||
void parse_error_offset_source_start(parse_error_list_t *errors, size_t amt);
|
||||
|
||||
/** Maximum number of function calls. */
|
||||
/// Maximum number of function calls.
|
||||
#define FISH_MAX_STACK_DEPTH 128
|
||||
|
||||
/** Error message on a function that calls itself immediately */
|
||||
#define INFINITE_FUNC_RECURSION_ERR_MSG _( L"The function '%ls' calls itself immediately, which would result in an infinite loop.")
|
||||
/// Error message on a function that calls itself immediately.
|
||||
#define INFINITE_FUNC_RECURSION_ERR_MSG \
|
||||
_(L"The function '%ls' calls itself immediately, which would result in an infinite loop.")
|
||||
|
||||
/** Error message on reaching maximum call stack depth */
|
||||
#define CALL_STACK_LIMIT_EXCEEDED_ERR_MSG _( L"The function call stack limit has been exceeded. Do you have an accidental infinite loop?")
|
||||
/// Error message on reaching maximum call stack depth.
|
||||
#define CALL_STACK_LIMIT_EXCEEDED_ERR_MSG \
|
||||
_(L"The function call stack limit has been exceeded. Do you have an accidental infinite " \
|
||||
L"loop?")
|
||||
|
||||
/** Error message when encountering an illegal command name */
|
||||
#define ILLEGAL_CMD_ERR_MSG _( L"Illegal command name '%ls'")
|
||||
/// Error message when encountering an illegal command name.
|
||||
#define ILLEGAL_CMD_ERR_MSG _(L"Illegal command name '%ls'")
|
||||
|
||||
/** Error message when encountering an unknown builtin name */
|
||||
#define UNKNOWN_BUILTIN_ERR_MSG _( L"Unknown builtin '%ls'")
|
||||
/// Error message when encountering an unknown builtin name.
|
||||
#define UNKNOWN_BUILTIN_ERR_MSG _(L"Unknown builtin '%ls'")
|
||||
|
||||
/** Error message when encountering a failed expansion, e.g. for the variable name in for loops */
|
||||
#define FAILED_EXPANSION_VARIABLE_NAME_ERR_MSG _( L"Unable to expand variable name '%ls'")
|
||||
/// Error message when encountering a failed expansion, e.g. for the variable name in for loops.
|
||||
#define FAILED_EXPANSION_VARIABLE_NAME_ERR_MSG _(L"Unable to expand variable name '%ls'")
|
||||
|
||||
/** Error message when encountering a failed process expansion, e.g. %notaprocess */
|
||||
#define FAILED_EXPANSION_PROCESS_ERR_MSG _( L"Unable to find a process '%ls'")
|
||||
/// Error message when encountering a failed process expansion, e.g. %notaprocess.
|
||||
#define FAILED_EXPANSION_PROCESS_ERR_MSG _(L"Unable to find a process '%ls'")
|
||||
|
||||
/** Error message when encountering an illegal file descriptor */
|
||||
#define ILLEGAL_FD_ERR_MSG _( L"Illegal file descriptor in redirection '%ls'")
|
||||
/// Error message when encountering an illegal file descriptor.
|
||||
#define ILLEGAL_FD_ERR_MSG _(L"Illegal file descriptor in redirection '%ls'")
|
||||
|
||||
/** Error message for wildcards with no matches */
|
||||
#define WILDCARD_ERR_MSG _( L"No matches for wildcard '%ls'.")
|
||||
/// Error message for wildcards with no matches.
|
||||
#define WILDCARD_ERR_MSG _(L"No matches for wildcard '%ls'.")
|
||||
|
||||
/** Error when using break outside of loop */
|
||||
#define INVALID_BREAK_ERR_MSG _( L"'break' while not inside of loop" )
|
||||
/// Error when using break outside of loop.
|
||||
#define INVALID_BREAK_ERR_MSG _(L"'break' while not inside of loop")
|
||||
|
||||
/** Error when using continue outside of loop */
|
||||
#define INVALID_CONTINUE_ERR_MSG _( L"'continue' while not inside of loop" )
|
||||
/// Error when using continue outside of loop.
|
||||
#define INVALID_CONTINUE_ERR_MSG _(L"'continue' while not inside of loop")
|
||||
|
||||
/** Error when using return builtin outside of function definition */
|
||||
#define INVALID_RETURN_ERR_MSG _( L"'return' outside of function definition" )
|
||||
/// Error when using return builtin outside of function definition.
|
||||
#define INVALID_RETURN_ERR_MSG _(L"'return' outside of function definition")
|
||||
|
||||
// Error messages. The number is a reminder of how many format specifiers are contained.
|
||||
|
||||
/*** Error messages. The number is a reminder of how many format specifiers are contained. */
|
||||
/// Error for $^.
|
||||
#define ERROR_BAD_VAR_CHAR1 _(L"$%lc is not a valid variable in fish.")
|
||||
|
||||
/** Error for (e.g.) $^ */
|
||||
#define ERROR_BAD_VAR_CHAR1 _( L"$%lc is not a valid variable in fish." )
|
||||
/// Error for ${a}.
|
||||
#define ERROR_BRACKETED_VARIABLE1 _(L"Variables cannot be bracketed. In fish, please use {$%ls}.")
|
||||
|
||||
/** Error for ${a} */
|
||||
#define ERROR_BRACKETED_VARIABLE1 _( L"Variables cannot be bracketed. In fish, please use {$%ls}." )
|
||||
/// Error for "${a}".
|
||||
#define ERROR_BRACKETED_VARIABLE_QUOTED1 \
|
||||
_(L"Variables cannot be bracketed. In fish, please use \"$%ls\".")
|
||||
|
||||
/** Error for "${a}" */
|
||||
#define ERROR_BRACKETED_VARIABLE_QUOTED1 _( L"Variables cannot be bracketed. In fish, please use \"$%ls\"." )
|
||||
/// Error issued on $?.
|
||||
#define ERROR_NOT_STATUS _(L"$? is not the exit status. In fish, please use $status.")
|
||||
|
||||
/** Error issued on $? */
|
||||
#define ERROR_NOT_STATUS _( L"$? is not the exit status. In fish, please use $status.")
|
||||
/// Error issued on $$.
|
||||
#define ERROR_NOT_PID _(L"$$ is not the pid. In fish, please use %%self.")
|
||||
|
||||
/** Error issued on $$ */
|
||||
#define ERROR_NOT_PID _( L"$$ is not the pid. In fish, please use %%self.")
|
||||
/// Error issued on $#.
|
||||
#define ERROR_NOT_ARGV_COUNT _(L"$# is not supported. In fish, please use 'count $argv'.")
|
||||
|
||||
/** Error issued on $# */
|
||||
#define ERROR_NOT_ARGV_COUNT _( L"$# is not supported. In fish, please use 'count $argv'.")
|
||||
/// Error issued on $@.
|
||||
#define ERROR_NOT_ARGV_AT _(L"$@ is not supported. In fish, please use $argv.")
|
||||
|
||||
/** Error issued on $@ */
|
||||
#define ERROR_NOT_ARGV_AT _( L"$@ is not supported. In fish, please use $argv.")
|
||||
/// Error issued on $(...).
|
||||
#define ERROR_BAD_VAR_SUBCOMMAND1 _(L"$(...) is not supported. In fish, please use '(%ls)'.")
|
||||
|
||||
/** Error issued on $(...) */
|
||||
#define ERROR_BAD_VAR_SUBCOMMAND1 _( L"$(...) is not supported. In fish, please use '(%ls)'." )
|
||||
/// Error issued on $*.
|
||||
#define ERROR_NOT_ARGV_STAR _(L"$* is not supported. In fish, please use $argv.")
|
||||
|
||||
/** Error issued on $* */
|
||||
#define ERROR_NOT_ARGV_STAR _( L"$* is not supported. In fish, please use $argv." )
|
||||
/// Error issued on $.
|
||||
#define ERROR_NO_VAR_NAME _(L"Expected a variable name after this $.")
|
||||
|
||||
/** Error issued on $ */
|
||||
#define ERROR_NO_VAR_NAME _( L"Expected a variable name after this $.")
|
||||
/// Error on ||.
|
||||
#define ERROR_BAD_OR _(L"Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.")
|
||||
|
||||
/** Error on || */
|
||||
#define ERROR_BAD_OR _( L"Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.")
|
||||
/// Error on &&.
|
||||
#define ERROR_BAD_AND _(L"Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'.")
|
||||
|
||||
/** Error on && */
|
||||
#define ERROR_BAD_AND _( L"Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'.")
|
||||
/// Error on foo=bar.
|
||||
#define ERROR_BAD_EQUALS_IN_COMMAND5 \
|
||||
_(L"Unsupported use of '='. To run '%ls' with a modified environment, please use 'env " \
|
||||
L"%ls=%ls %ls%ls'")
|
||||
|
||||
/** Error on foo=bar */
|
||||
#define ERROR_BAD_EQUALS_IN_COMMAND5 _( L"Unsupported use of '='. To run '%ls' with a modified environment, please use 'env %ls=%ls %ls%ls'")
|
||||
/// Error message for Posix-style assignment: foo=bar.
|
||||
#define ERROR_BAD_COMMAND_ASSIGN_ERR_MSG \
|
||||
_(L"Unsupported use of '='. In fish, please use 'set %ls %ls'.")
|
||||
|
||||
/** Error message for Posix-style assignment: foo=bar */
|
||||
#define ERROR_BAD_COMMAND_ASSIGN_ERR_MSG _( L"Unsupported use of '='. In fish, please use 'set %ls %ls'.")
|
||||
/// While block description.
|
||||
#define WHILE_BLOCK N_(L"'while' block")
|
||||
|
||||
/// For block description.
|
||||
#define FOR_BLOCK N_(L"'for' block")
|
||||
|
||||
/// Breakpoint block.
|
||||
#define BREAKPOINT_BLOCK N_(L"Block created by breakpoint")
|
||||
|
||||
/**
|
||||
While block description
|
||||
*/
|
||||
#define WHILE_BLOCK N_( L"'while' block" )
|
||||
/// If block description.
|
||||
#define IF_BLOCK N_(L"'if' conditional block")
|
||||
|
||||
/**
|
||||
For block description
|
||||
*/
|
||||
#define FOR_BLOCK N_( L"'for' block" )
|
||||
/// Function definition block description.
|
||||
#define FUNCTION_DEF_BLOCK N_(L"function definition block")
|
||||
|
||||
/**
|
||||
Breakpoint block
|
||||
*/
|
||||
#define BREAKPOINT_BLOCK N_( L"Block created by breakpoint" )
|
||||
/// Function invocation block description.
|
||||
#define FUNCTION_CALL_BLOCK N_(L"function invocation block")
|
||||
|
||||
/// Function invocation block description.
|
||||
#define FUNCTION_CALL_NO_SHADOW_BLOCK N_(L"function invocation block with no variable shadowing")
|
||||
|
||||
/// Switch block description.
|
||||
#define SWITCH_BLOCK N_(L"'switch' block")
|
||||
|
||||
/**
|
||||
If block description
|
||||
*/
|
||||
#define IF_BLOCK N_( L"'if' conditional block" )
|
||||
/// Fake block description.
|
||||
#define FAKE_BLOCK N_(L"unexecutable block")
|
||||
|
||||
/// Top block description.
|
||||
#define TOP_BLOCK N_(L"global root block")
|
||||
|
||||
/**
|
||||
Function definition block description
|
||||
*/
|
||||
#define FUNCTION_DEF_BLOCK N_( L"function definition block" )
|
||||
/// Command substitution block description.
|
||||
#define SUBST_BLOCK N_(L"command substitution block")
|
||||
|
||||
/// Begin block description.
|
||||
#define BEGIN_BLOCK N_(L"'begin' unconditional block")
|
||||
|
||||
/**
|
||||
Function invocation block description
|
||||
*/
|
||||
#define FUNCTION_CALL_BLOCK N_( L"function invocation block" )
|
||||
|
||||
/**
|
||||
Function invocation block description
|
||||
*/
|
||||
#define FUNCTION_CALL_NO_SHADOW_BLOCK N_( L"function invocation block with no variable shadowing" )
|
||||
|
||||
|
||||
/**
|
||||
Switch block description
|
||||
*/
|
||||
#define SWITCH_BLOCK N_( L"'switch' block" )
|
||||
|
||||
|
||||
/**
|
||||
Fake block description
|
||||
*/
|
||||
#define FAKE_BLOCK N_( L"unexecutable block" )
|
||||
|
||||
|
||||
/**
|
||||
Top block description
|
||||
*/
|
||||
#define TOP_BLOCK N_( L"global root block" )
|
||||
|
||||
|
||||
/**
|
||||
Command substitution block description
|
||||
*/
|
||||
#define SUBST_BLOCK N_( L"command substitution block" )
|
||||
|
||||
|
||||
/**
|
||||
Begin block description
|
||||
*/
|
||||
#define BEGIN_BLOCK N_( L"'begin' unconditional block" )
|
||||
|
||||
|
||||
/**
|
||||
Source block description
|
||||
*/
|
||||
#define SOURCE_BLOCK N_( L"Block created by the . builtin" )
|
||||
|
||||
/**
|
||||
Source block description
|
||||
*/
|
||||
#define EVENT_BLOCK N_( L"event handler block" )
|
||||
|
||||
|
||||
/**
|
||||
Unknown block description
|
||||
*/
|
||||
#define UNKNOWN_BLOCK N_( L"unknown/invalid block" )
|
||||
/// Source block description.
|
||||
#define SOURCE_BLOCK N_(L"Block created by the . builtin")
|
||||
|
||||
/// Source block description.
|
||||
#define EVENT_BLOCK N_(L"event handler block")
|
||||
|
||||
/// Unknown block description.
|
||||
#define UNKNOWN_BLOCK N_(L"unknown/invalid block")
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,65 +1,55 @@
|
||||
/**\file parse_execution.h
|
||||
|
||||
Provides the "linkage" between a parse_node_tree_t and actual execution structures (job_t, etc.).
|
||||
*/
|
||||
// Provides the "linkage" between a parse_node_tree_t and actual execution structures (job_t, etc.).
|
||||
#ifndef FISH_PARSE_EXECUTION_H
|
||||
#define FISH_PARSE_EXECUTION_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "common.h"
|
||||
#include "io.h"
|
||||
#include "parse_constants.h"
|
||||
#include "parse_tree.h"
|
||||
#include "proc.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
class parser_t;
|
||||
struct block_t;
|
||||
|
||||
enum parse_execution_result_t
|
||||
{
|
||||
/* The job was successfully executed (though it have failed on its own). */
|
||||
enum parse_execution_result_t {
|
||||
/// The job was successfully executed (though it have failed on its own).
|
||||
parse_execution_success,
|
||||
|
||||
/* The job did not execute due to some error (e.g. failed to wildcard expand). An error will have been printed and proc_last_status will have been set. */
|
||||
/// The job did not execute due to some error (e.g. failed to wildcard expand). An error will
|
||||
/// have been printed and proc_last_status will have been set.
|
||||
parse_execution_errored,
|
||||
|
||||
/* The job was cancelled (e.g. Ctrl-C) */
|
||||
/// The job was cancelled (e.g. Ctrl-C).
|
||||
parse_execution_cancelled,
|
||||
|
||||
/* The job was skipped (e.g. due to a not-taken 'and' command). This is a special return allowed only from the populate functions, not the run functions. */
|
||||
/// The job was skipped (e.g. due to a not-taken 'and' command). This is a special return
|
||||
/// allowed only from the populate functions, not the run functions.
|
||||
parse_execution_skipped
|
||||
};
|
||||
|
||||
class parse_execution_context_t
|
||||
{
|
||||
private:
|
||||
class parse_execution_context_t {
|
||||
private:
|
||||
const parse_node_tree_t tree;
|
||||
const wcstring src;
|
||||
io_chain_t block_io;
|
||||
parser_t * const parser;
|
||||
//parse_error_list_t errors;
|
||||
|
||||
parser_t *const parser;
|
||||
// parse_error_list_t errors;
|
||||
int eval_level;
|
||||
|
||||
/* The currently executing node index, used to indicate the line number */
|
||||
// The currently executing node index, used to indicate the line number.
|
||||
node_offset_t executing_node_idx;
|
||||
|
||||
/* Cached line number information */
|
||||
// Cached line number information.
|
||||
size_t cached_lineno_offset;
|
||||
int cached_lineno_count;
|
||||
// No copying allowed.
|
||||
parse_execution_context_t(const parse_execution_context_t &);
|
||||
parse_execution_context_t &operator=(const parse_execution_context_t &);
|
||||
|
||||
/* No copying allowed */
|
||||
parse_execution_context_t(const parse_execution_context_t&);
|
||||
parse_execution_context_t& operator=(const parse_execution_context_t&);
|
||||
|
||||
/* Should I cancel? */
|
||||
// Should I cancel?
|
||||
bool should_cancel_execution(const block_t *block) const;
|
||||
|
||||
/* Ways that we can stop executing a block. These are in a sort of ascending order of importance, e.g. `exit` should trump `break` */
|
||||
enum execution_cancellation_reason_t
|
||||
{
|
||||
// Ways that we can stop executing a block. These are in a sort of ascending order of
|
||||
// importance, e.g. `exit` should trump `break`.
|
||||
enum execution_cancellation_reason_t {
|
||||
execution_cancellation_none,
|
||||
execution_cancellation_loop_control,
|
||||
execution_cancellation_skip,
|
||||
@@ -67,85 +57,98 @@ class parse_execution_context_t
|
||||
};
|
||||
execution_cancellation_reason_t cancellation_reason(const block_t *block) const;
|
||||
|
||||
/* Report an error. Always returns true. */
|
||||
// Report an error. Always returns true.
|
||||
parse_execution_result_t report_error(const parse_node_t &node, const wchar_t *fmt, ...) const;
|
||||
parse_execution_result_t report_errors(const parse_error_list_t &errors) const;
|
||||
|
||||
/* Wildcard error helper */
|
||||
parse_execution_result_t report_unmatched_wildcard_error(const parse_node_t &unmatched_wildcard);
|
||||
// Wildcard error helper.
|
||||
parse_execution_result_t report_unmatched_wildcard_error(
|
||||
const parse_node_t &unmatched_wildcard);
|
||||
|
||||
/* Command not found support */
|
||||
parse_execution_result_t handle_command_not_found(const wcstring &cmd, const parse_node_t &statement_node, int err_code);
|
||||
/// Command not found support.
|
||||
parse_execution_result_t handle_command_not_found(const wcstring &cmd,
|
||||
const parse_node_t &statement_node,
|
||||
int err_code);
|
||||
|
||||
/* Utilities */
|
||||
// Utilities
|
||||
wcstring get_source(const parse_node_t &node) const;
|
||||
const parse_node_t *get_child(const parse_node_t &parent, node_offset_t which, parse_token_type_t expected_type = token_type_invalid) const;
|
||||
const parse_node_t *get_child(const parse_node_t &parent, node_offset_t which,
|
||||
parse_token_type_t expected_type = token_type_invalid) const;
|
||||
node_offset_t get_offset(const parse_node_t &node) const;
|
||||
const parse_node_t *infinite_recursive_statement_in_job_list(const parse_node_t &job_list, wcstring *out_func_name) const;
|
||||
const parse_node_t *infinite_recursive_statement_in_job_list(const parse_node_t &job_list,
|
||||
wcstring *out_func_name) const;
|
||||
|
||||
/* Indicates whether a job is a simple block (one block, no redirections) */
|
||||
/// Indicates whether a job is a simple block (one block, no redirections).
|
||||
bool job_is_simple_block(const parse_node_t &node) const;
|
||||
|
||||
enum process_type_t process_type_for_command(const parse_node_t &plain_statement, const wcstring &cmd) const;
|
||||
enum process_type_t process_type_for_command(const parse_node_t &plain_statement,
|
||||
const wcstring &cmd) const;
|
||||
|
||||
/* These create process_t structures from statements */
|
||||
parse_execution_result_t populate_job_process(job_t *job, process_t *proc, const parse_node_t &statement_node);
|
||||
parse_execution_result_t populate_boolean_process(job_t *job, process_t *proc, const parse_node_t &bool_statement);
|
||||
parse_execution_result_t populate_plain_process(job_t *job, process_t *proc, const parse_node_t &statement);
|
||||
parse_execution_result_t populate_block_process(job_t *job, process_t *proc, const parse_node_t &statement_node);
|
||||
// These create process_t structures from statements.
|
||||
parse_execution_result_t populate_job_process(job_t *job, process_t *proc,
|
||||
const parse_node_t &statement_node);
|
||||
parse_execution_result_t populate_boolean_process(job_t *job, process_t *proc,
|
||||
const parse_node_t &bool_statement);
|
||||
parse_execution_result_t populate_plain_process(job_t *job, process_t *proc,
|
||||
const parse_node_t &statement);
|
||||
parse_execution_result_t populate_block_process(job_t *job, process_t *proc,
|
||||
const parse_node_t &statement_node);
|
||||
|
||||
/* These encapsulate the actual logic of various (block) statements. */
|
||||
// These encapsulate the actual logic of various (block) statements.
|
||||
parse_execution_result_t run_block_statement(const parse_node_t &statement);
|
||||
parse_execution_result_t run_for_statement(const parse_node_t &header, const parse_node_t &contents);
|
||||
parse_execution_result_t run_for_statement(const parse_node_t &header,
|
||||
const parse_node_t &contents);
|
||||
parse_execution_result_t run_if_statement(const parse_node_t &statement);
|
||||
parse_execution_result_t run_switch_statement(const parse_node_t &statement);
|
||||
parse_execution_result_t run_while_statement(const parse_node_t &header, const parse_node_t &contents);
|
||||
parse_execution_result_t run_function_statement(const parse_node_t &header, const parse_node_t &block_end_command);
|
||||
parse_execution_result_t run_begin_statement(const parse_node_t &header, const parse_node_t &contents);
|
||||
parse_execution_result_t run_while_statement(const parse_node_t &header,
|
||||
const parse_node_t &contents);
|
||||
parse_execution_result_t run_function_statement(const parse_node_t &header,
|
||||
const parse_node_t &block_end_command);
|
||||
parse_execution_result_t run_begin_statement(const parse_node_t &header,
|
||||
const parse_node_t &contents);
|
||||
|
||||
enum globspec_t
|
||||
{
|
||||
failglob,
|
||||
nullglob
|
||||
};
|
||||
parse_execution_result_t determine_arguments(const parse_node_t &parent, wcstring_list_t *out_arguments, globspec_t glob_behavior);
|
||||
enum globspec_t { failglob, nullglob };
|
||||
parse_execution_result_t determine_arguments(const parse_node_t &parent,
|
||||
wcstring_list_t *out_arguments,
|
||||
globspec_t glob_behavior);
|
||||
|
||||
/* Determines the IO chain. Returns true on success, false on error */
|
||||
// Determines the IO chain. Returns true on success, false on error.
|
||||
bool determine_io_chain(const parse_node_t &statement, io_chain_t *out_chain);
|
||||
|
||||
parse_execution_result_t run_1_job(const parse_node_t &job_node, const block_t *associated_block);
|
||||
parse_execution_result_t run_job_list(const parse_node_t &job_list_node, const block_t *associated_block);
|
||||
parse_execution_result_t populate_job_from_job_node(job_t *j, const parse_node_t &job_node, const block_t *associated_block);
|
||||
parse_execution_result_t run_1_job(const parse_node_t &job_node,
|
||||
const block_t *associated_block);
|
||||
parse_execution_result_t run_job_list(const parse_node_t &job_list_node,
|
||||
const block_t *associated_block);
|
||||
parse_execution_result_t populate_job_from_job_node(job_t *j, const parse_node_t &job_node,
|
||||
const block_t *associated_block);
|
||||
|
||||
/* Returns the line number of the node at the given index, indexed from 0. Not const since it touches cached_lineno_offset */
|
||||
// Returns the line number of the node at the given index, indexed from 0. Not const since it
|
||||
// touches cached_lineno_offset.
|
||||
int line_offset_of_node_at_offset(node_offset_t idx);
|
||||
int line_offset_of_character_at_offset(size_t char_idx);
|
||||
|
||||
public:
|
||||
parse_execution_context_t(moved_ref<parse_node_tree_t> t, const wcstring &s, parser_t *p, int initial_eval_level);
|
||||
public:
|
||||
parse_execution_context_t(moved_ref<parse_node_tree_t> t, const wcstring &s, parser_t *p,
|
||||
int initial_eval_level);
|
||||
|
||||
/* Returns the current eval level */
|
||||
int current_eval_level() const
|
||||
{
|
||||
return eval_level;
|
||||
}
|
||||
/// Returns the current eval level.
|
||||
int current_eval_level() const { return eval_level; }
|
||||
|
||||
/* Returns the current line number, indexed from 1. Not const since it touches cached_lineno_offset */
|
||||
/// Returns the current line number, indexed from 1. Not const since it touches
|
||||
/// cached_lineno_offset.
|
||||
int get_current_line_number();
|
||||
|
||||
/* Returns the source offset, or -1 */
|
||||
/// Returns the source offset, or -1.
|
||||
int get_current_source_offset() const;
|
||||
|
||||
/* Returns the source string */
|
||||
const wcstring &get_source() const
|
||||
{
|
||||
return src;
|
||||
}
|
||||
|
||||
/* Start executing at the given node offset. Returns 0 if there was no error, 1 if there was an error */
|
||||
parse_execution_result_t eval_node_at_offset(node_offset_t offset, const block_t *associated_block, const io_chain_t &io);
|
||||
/// Returns the source string.
|
||||
const wcstring &get_source() const { return src; }
|
||||
|
||||
/// Start executing at the given node offset. Returns 0 if there was no error, 1 if there was an
|
||||
/// error.
|
||||
parse_execution_result_t eval_node_at_offset(node_offset_t offset,
|
||||
const block_t *associated_block,
|
||||
const io_chain_t &io);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user