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
2015-07-25 15:14:25 +00:00
# include <stddef.h>
2016-04-21 06:00:54 +00:00
2015-07-25 15:14:25 +00:00
# include "common.h"
# include "io.h"
# include "parse_constants.h"
2013-12-24 21:17:24 +00:00
# include "parse_tree.h"
# include "proc.h"
2016-04-21 06:00:54 +00:00
# include <stdbool.h>
2013-12-24 21:17:24 +00:00
2015-07-25 15:14:25 +00:00
class parser_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 ,
2014-01-15 09:40:40 +00:00
2013-12-31 22:37:37 +00:00
/* The job was cancelled (e.g. Ctrl-C) */
parse_execution_cancelled ,
2014-01-15 09:40:40 +00:00
2013-12-31 22:37:37 +00: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-24 21:17:24 +00:00
class parse_execution_context_t
{
2014-01-15 09:40:40 +00:00
private :
2013-12-24 21:17:24 +00:00
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;
2014-01-15 09:40:40 +00:00
2013-12-26 20:24:00 +00:00
int eval_level ;
2014-03-31 17:01:39 +00:00
2014-03-02 00:04:13 +00:00
/* The currently executing node index, used to indicate the line number */
node_offset_t executing_node_idx ;
2014-03-31 17:01:39 +00:00
2014-03-02 00:04:13 +00:00
/* Cached line number information */
size_t cached_lineno_offset ;
int cached_lineno_count ;
2014-01-15 09:40:40 +00:00
2013-12-24 21:17:24 +00: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 09:40:40 +00:00
2013-12-29 00:18:38 +00:00
/* Should I cancel? */
bool should_cancel_execution ( const block_t * block ) const ;
2014-01-15 09:40:40 +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 ;
2014-01-15 09:40:40 +00:00
2013-12-24 21:17:24 +00:00
/* Report an error. Always returns true. */
2014-03-22 00:13:33 +00: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-03-31 17:01:39 +00:00
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 ) ;
2014-01-15 09:40:40 +00:00
2014-01-07 18:45:36 +00:00
/* Command not found support */
2015-04-18 19:53:43 +00:00
parse_execution_result_t handle_command_not_found ( const wcstring & cmd , const parse_node_t & statement_node , int err_code ) ;
2014-03-31 17:01:39 +00:00
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 ;
2014-01-15 09:40:40 +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 ;
2014-01-15 09:40:40 +00:00
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 ;
2014-01-15 09:40:40 +00:00
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 ) ;
2014-01-15 09:40:40 +00:00
2013-12-31 22:37:37 +00: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 00:32:54 +00:00
parse_execution_result_t run_function_statement ( const parse_node_t & header , const parse_node_t & block_end_command ) ;
2013-12-31 22:37:37 +00:00
parse_execution_result_t run_begin_statement ( const parse_node_t & header , const parse_node_t & contents ) ;
2014-01-15 09:40:40 +00:00
2016-02-08 18:49:26 +00:00
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 ) ;
2014-01-15 09:40:40 +00:00
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 ) ;
2014-01-15 09:40:40 +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 ) ;
2014-01-15 09:40:40 +00:00
2014-03-16 23:45:00 +00: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 00:32:54 +00:00
int line_offset_of_character_at_offset ( size_t char_idx ) ;
2014-03-16 23:45:00 +00:00
2014-01-15 09:40:40 +00:00
public :
2016-02-28 08:33:11 +00:00
parse_execution_context_t ( moved_ref < parse_node_tree_t > t , const wcstring & s , parser_t * p , int initial_eval_level ) ;
2014-02-09 22:04:43 +00:00
/* Returns the current eval level */
2014-03-31 17:01:39 +00:00
int current_eval_level ( ) const
{
return eval_level ;
}
2014-03-16 23:45:00 +00:00
/* Returns the current line number, indexed from 1. Not const since it touches cached_lineno_offset */
2014-03-02 00:04:13 +00:00
int get_current_line_number ( ) ;
2014-01-15 09:40:40 +00:00
2014-03-17 05:06:32 +00:00
/* Returns the source offset, or -1 */
int get_current_source_offset ( ) const ;
/* Returns the source string */
2014-03-31 17:01:39 +00:00
const wcstring & get_source ( ) const
{
return src ;
}
2014-03-17 05:06:32 +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 ) ;
2014-01-15 09:40:40 +00:00
2013-12-24 21:17:24 +00:00
} ;
# endif