2013-12-25 05:17:24 +08:00
/**\file parse_execution.h
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 "config.h"
# include "util.h"
# include "parse_tree.h"
# include "proc.h"
class job_t ;
2013-12-29 08:18:38 +08:00
struct block_t ;
2013-12-25 05:17:24 +08:00
2014-01-01 06:37:37 +08:00
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. */
parse_execution_errored ,
2014-01-15 17:40:40 +08:00
2014-01-01 06:37:37 +08:00
/* The job was cancelled (e.g. Ctrl-C) */
parse_execution_cancelled ,
2014-01-15 17:40:40 +08:00
2014-01-01 06:37:37 +08:00
/* 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
} ;
2013-12-25 05:17:24 +08:00
class parse_execution_context_t
{
2014-01-15 17:40:40 +08:00
private :
2013-12-25 05:17:24 +08:00
const parse_node_tree_t tree ;
const wcstring src ;
2013-12-29 08:18:38 +08:00
io_chain_t block_io ;
2013-12-25 05:17:24 +08:00
parser_t * const parser ;
2014-01-01 06:37:37 +08:00
//parse_error_list_t errors;
2014-01-15 17:40:40 +08:00
2013-12-27 04:24:00 +08:00
int eval_level ;
2014-04-01 01:01:39 +08:00
2014-03-02 08:04:13 +08:00
/* The currently executing node index, used to indicate the line number */
node_offset_t executing_node_idx ;
2014-04-01 01:01:39 +08:00
2014-03-02 08:04:13 +08:00
/* Cached line number information */
size_t cached_lineno_offset ;
int cached_lineno_count ;
2014-01-15 17:40:40 +08:00
2013-12-25 05:17:24 +08:00
/* No copying allowed */
parse_execution_context_t ( const parse_execution_context_t & ) ;
parse_execution_context_t & operator = ( const parse_execution_context_t & ) ;
2014-01-15 17:40:40 +08:00
2013-12-29 08:18:38 +08:00
/* Should I cancel? */
bool should_cancel_execution ( const block_t * block ) const ;
2014-01-15 17:40:40 +08:00
2013-12-30 08:23:26 +08:00
/* 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 ,
execution_cancellation_exit
} ;
execution_cancellation_reason_t cancellation_reason ( const block_t * block ) const ;
2014-01-15 17:40:40 +08:00
2013-12-25 05:17:24 +08:00
/* Report an error. Always returns true. */
2014-03-22 08:13:33 +08:00
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 ;
2014-04-01 01:01:39 +08:00
2013-12-27 17:38:43 +08:00
/* Wildcard error helper */
2014-01-01 16:04:02 +08:00
parse_execution_result_t report_unmatched_wildcard_error ( const parse_node_t & unmatched_wildcard ) ;
2014-01-15 17:40:40 +08:00
2014-01-08 02:45:36 +08:00
/* Command not found support */
2013-12-30 08:23:26 +08:00
void handle_command_not_found ( const wcstring & cmd , const parse_node_t & statement_node , int err_code ) ;
2014-04-01 01:01:39 +08:00
2013-12-27 04:55:10 +08:00
/* Utilities */
2013-12-25 05:17:24 +08:00
wcstring get_source ( const parse_node_t & node ) const ;
2013-12-27 04:55:10 +08:00
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 ;
2013-12-25 05:17:24 +08:00
node_offset_t get_offset ( const parse_node_t & node ) const ;
2014-01-02 07:29:56 +08:00
const parse_node_t * infinite_recursive_statement_in_job_list ( const parse_node_t & job_list , wcstring * out_func_name ) const ;
2014-01-15 17:40:40 +08:00
2014-01-08 02:45:36 +08:00
/* Indicates whether a job is a simple block (one block, no redirections) */
bool job_is_simple_block ( const parse_node_t & node ) const ;
2014-01-15 17:40:40 +08:00
2014-01-01 06:37:37 +08:00
enum process_type_t process_type_for_command ( const parse_node_t & plain_statement , const wcstring & cmd ) const ;
2014-01-15 17:40:40 +08:00
2013-12-27 17:38:43 +08:00
/* These create process_t structures from statements */
2014-01-01 06:37:37 +08:00
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 ) ;
2014-01-15 17:40:40 +08:00
2014-01-01 06:37:37 +08:00
/* 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_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 ) ;
2014-09-28 08:32:54 +08:00
parse_execution_result_t run_function_statement ( const parse_node_t & header , const parse_node_t & block_end_command ) ;
2014-01-01 06:37:37 +08:00
parse_execution_result_t run_begin_statement ( const parse_node_t & header , const parse_node_t & contents ) ;
2014-01-15 17:40:40 +08:00
2014-10-14 09:47:13 +08:00
parse_execution_result_t determine_arguments ( const parse_node_t & parent , wcstring_list_t * out_arguments ) ;
2014-01-15 17:40:40 +08:00
2013-12-27 04:55:10 +08:00
/* 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 ) ;
2014-01-15 17:40:40 +08:00
2014-01-01 06:37:37 +08:00
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 ) ;
2014-01-15 17:40:40 +08:00
2014-03-17 07:45:00 +08:00
/* 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 ) ;
2014-09-28 08:32:54 +08:00
int line_offset_of_character_at_offset ( size_t char_idx ) ;
2014-03-17 07:45:00 +08:00
2014-01-15 17:40:40 +08:00
public :
2014-02-10 06:04:43 +08:00
parse_execution_context_t ( const parse_node_tree_t & t , const wcstring & s , parser_t * p , int initial_eval_level ) ;
/* Returns the current eval level */
2014-04-01 01:01:39 +08:00
int current_eval_level ( ) const
{
return eval_level ;
}
2014-03-17 07:45:00 +08:00
/* Returns the current line number, indexed from 1. Not const since it touches cached_lineno_offset */
2014-03-02 08:04:13 +08:00
int get_current_line_number ( ) ;
2014-01-15 17:40:40 +08:00
2014-03-17 13:06:32 +08:00
/* Returns the source offset, or -1 */
int get_current_source_offset ( ) const ;
/* Returns the source string */
2014-04-01 01:01:39 +08:00
const wcstring & get_source ( ) const
{
return src ;
}
2014-03-17 13:06:32 +08:00
2013-12-29 08:33:26 +08:00
/* Start executing at the given node offset. Returns 0 if there was no error, 1 if there was an error */
2014-01-01 06:37:37 +08:00
parse_execution_result_t eval_node_at_offset ( node_offset_t offset , const block_t * associated_block , const io_chain_t & io ) ;
2014-01-15 17:40:40 +08:00
2013-12-25 05:17:24 +08:00
} ;
# endif