2013-12-24 21:17:24 +00: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 ;
struct profile_item_t ;
2013-12-29 00:18:38 +00:00
struct block_t ;
2013-12-24 21:17:24 +00:00
2013-12-31 22:37:37 +00: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 ,
/* 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. */
parse_execution_skipped
} ;
2013-12-24 21:17:24 +00:00
class parse_execution_context_t
{
private :
const parse_node_tree_t tree ;
const wcstring src ;
2013-12-29 00:18:38 +00:00
io_chain_t block_io ;
2013-12-24 21:17:24 +00:00
parser_t * const parser ;
2013-12-31 22:37:37 +00:00
//parse_error_list_t errors;
2013-12-24 21:17:24 +00:00
2013-12-26 20:24:00 +00:00
int eval_level ;
2013-12-24 21:17:24 +00:00
std : : vector < profile_item_t * > profile_items ;
/* No copying allowed */
parse_execution_context_t ( const parse_execution_context_t & ) ;
parse_execution_context_t & operator = ( const parse_execution_context_t & ) ;
2013-12-29 00:18:38 +00:00
/* Should I cancel? */
bool should_cancel_execution ( const block_t * block ) const ;
2013-12-26 20:24:00 +00:00
2013-12-30 00:23:26 +00: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 ;
2013-12-24 21:17:24 +00:00
/* Report an error. Always returns true. */
2014-01-01 08:04:02 +00:00
parse_execution_result_t report_error ( const parse_node_t & node , const wchar_t * fmt , . . . ) ;
2013-12-27 09:38:43 +00:00
/* Wildcard error helper */
2014-01-01 08:04:02 +00:00
parse_execution_result_t report_unmatched_wildcard_error ( const parse_node_t & unmatched_wildcard ) ;
2013-12-24 21:17:24 +00:00
2014-01-07 18:45:36 +00:00
/* Command not found support */
2013-12-30 00:23:26 +00:00
void handle_command_not_found ( const wcstring & cmd , const parse_node_t & statement_node , int err_code ) ;
2013-12-26 20:55:10 +00:00
/* Utilities */
2013-12-24 21:17:24 +00:00
wcstring get_source ( const parse_node_t & node ) const ;
2013-12-26 20:55:10 +00: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-24 21:17:24 +00:00
node_offset_t get_offset ( const parse_node_t & node ) const ;
2014-01-01 23:29:56 +00:00
const parse_node_t * infinite_recursive_statement_in_job_list ( const parse_node_t & job_list , wcstring * out_func_name ) const ;
2013-12-24 21:17:24 +00:00
2014-01-07 18:45:36 +00:00
/* Indicates whether a job is a simple block (one block, no redirections) */
bool job_is_simple_block ( const parse_node_t & node ) const ;
2013-12-31 22:37:37 +00:00
enum process_type_t process_type_for_command ( const parse_node_t & plain_statement , const wcstring & cmd ) const ;
2013-12-27 09:38:43 +00:00
/* These create process_t structures from statements */
2013-12-31 22:37:37 +00: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 ) ;
/* 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 ) ;
parse_execution_result_t run_function_statement ( const parse_node_t & header , const parse_node_t & contents ) ;
parse_execution_result_t run_begin_statement ( const parse_node_t & header , const parse_node_t & contents ) ;
2013-12-24 21:17:24 +00:00
wcstring_list_t determine_arguments ( const parse_node_t & parent , const parse_node_t * * out_unmatched_wildcard_node ) ;
2013-12-26 20:55:10 +00: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 ) ;
2013-12-24 21:17:24 +00:00
2013-12-31 22:37:37 +00: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 ) ;
2013-12-24 21:17:24 +00:00
public :
2013-12-29 00:18:38 +00:00
parse_execution_context_t ( const parse_node_tree_t & t , const wcstring & s , parser_t * p ) ;
2013-12-24 21:17:24 +00:00
2013-12-29 00:33:26 +00:00
/* Start executing at the given node offset. Returns 0 if there was no error, 1 if there was an error */
2013-12-31 22:37:37 +00:00
parse_execution_result_t eval_node_at_offset ( node_offset_t offset , const block_t * associated_block , const io_chain_t & io ) ;
2013-12-24 21:17:24 +00:00
} ;
# endif