#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <pwd.h>
#include <dirent.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "proc.h"
#include "parser.h"
#include "parser_keywords.h"
#include "tokenizer.h"
#include "exec.h"
#include "wildcard.h"
#include "function.h"
#include "builtin.h"
#include "env.h"
#include "expand.h"
#include "reader.h"
#include "sanity.h"
#include "env_universal.h"
#include "event.h"
#include "intern.h"
#include "parse_util.h"
#include "halloc.h"
#include "halloc_util.h"
#include "path.h"
Data Structures | |
| struct | block_lookup_entry |
| Datastructure to describe a block type, like while blocks, command substitution blocks, etc. More... | |
| struct | profile_element_t |
| Struct used to keep track of profiling data for a command. More... | |
Defines | |
| #define | BLOCK_MAX_COUNT 64 |
| Maximum number of block levels in code. | |
| #define | MAX_RECURSION_DEPTH 128 |
| Maximum number of function calls, i.e. | |
| #define | UNKNOWN_BUILTIN_ERR_MSG _(L"Unknown builtin '%ls'") |
| Error message for unknown builtin. | |
| #define | EXEC_ERR_MSG _(L"This command can not be used in a pipeline") |
| Error message for improper use of the exec builtin. | |
| #define | TOK_ERR_MSG _( L"Tokenizer error: '%ls'") |
| Error message for tokenizer error. | |
| #define | COND_ERR_MSG _( L"An additional command is required" ) |
| Error message for short circuit command error. | |
| #define | RECURSION_ERR_MSG _( L"Maximum recursion depth reached. Accidental infinite loop?") |
| Error message on reaching maximum recusrion depth. | |
| #define | BLOCK_END_ERR_MSG _( L"Could not locate end of block. The 'end' command is missing, misspelled or a ';' is missing.") |
| Error message used when the end of a block can't be located. | |
| #define | BLOCK_ERR_MSG _( L"Maximum number of nested blocks reached.") |
| Error message on reaching maximum number of block calls. | |
| #define | CMD_ERR_MSG _( L"Expected a command name, got token of type '%ls'") |
| Error message when a non-string token is found when expecting a command name. | |
| #define | CMD_OR_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; or COMMAND'? See the help section for the 'or' builtin command by typing 'help or'.") |
| Error message when a non-string token is found when expecting a command name. | |
| #define | CMD_AND_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; and COMMAND'? See the help section for the 'and' builtin command by typing 'help and'.") |
| Error message when a non-string token is found when expecting a command name. | |
| #define | ILLEGAL_CMD_ERR_MSG _( L"Illegal command name '%ls'") |
| Error message when encountering an illegal command name. | |
| #define | ILLEGAL_FD_ERR_MSG _( L"Illegal file descriptor '%ls'") |
| Error message when encountering an illegal file descriptor. | |
| #define | WILDCARD_ERR_MSG _( L"Warning: No match for wildcard '%ls'. The command will not be executed.") |
| Error message for wildcards with no matches. | |
| #define | INVALID_CASE_ERR_MSG _( L"'case' builtin not inside of switch block") |
| Error when using case builtin outside of switch block. | |
| #define | INVALID_LOOP_ERR_MSG _( L"Loop control command while not inside of loop" ) |
| Error when using loop control builtins (break or continue) outside of loop. | |
| #define | INVALID_RETURN_ERR_MSG _( L"'return' builtin command outside of function definition" ) |
| Error when using return builtin outside of function definition. | |
| #define | INVALID_ELSE_ERR_MSG _( L"'else' builtin not inside of if block" ) |
| Error when using else builtin outside of if block. | |
| #define | INVALID_END_ERR_MSG _( L"'end' command outside of block") |
| Error when using end builtin outside of block. | |
| #define | COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? For information on assigning values to variables, see the help section on the set command by typing 'help set'.") |
| Error message for Posix-style assignment. | |
| #define | REDIRECT_TOKEN_ERR_MSG _( L"Expected redirection specification, got token of type '%ls'") |
| Error for invalid redirection token. | |
| #define | INVALID_REDIRECTION_ERR_MSG _( L"Encountered redirection when expecting a command name. Fish does not allow a redirection operation before a command.") |
| Error when encountering redirection without a command. | |
| #define | EVAL_NULL_ERR_MSG _( L"Tried to evaluate null pointer." ) |
| Error for evaluating null pointer. | |
| #define | INVALID_SCOPE_ERR_MSG _( L"Tried to evaluate commands using invalid block type '%ls'" ) |
| Error for evaluating in illegal scope. | |
| #define | UNEXPECTED_TOKEN_ERR_MSG _( L"Unexpected token of type '%ls'") |
| Error for wrong token type. | |
| #define | WHILE_BLOCK N_( L"'while' block" ) |
| While block description. | |
| #define | FOR_BLOCK N_( L"'for' block" ) |
| For block description. | |
| #define | BREAKPOINT_BLOCK N_( L"Block created by breakpoint" ) |
| Breakpoint block. | |
| #define | IF_BLOCK N_( L"'if' conditional block" ) |
| If block description. | |
| #define | FUNCTION_DEF_BLOCK N_( L"function definition block" ) |
| Function definition 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" ) |
| Function invocation block description. | |
| #define | SWITCH_BLOCK N_( L"'switch' block" ) |
| Switch block description. | |
| #define | FAKE_BLOCK N_( L"unexecutable block" ) |
| Fake block description. | |
| #define | TOP_BLOCK N_( L"global root block" ) |
| Top block description. | |
| #define | SUBST_BLOCK N_( L"command substitution block" ) |
| Command substitution block description. | |
| #define | BEGIN_BLOCK N_( L"'begin' unconditional block" ) |
| Begin block description. | |
| #define | SOURCE_BLOCK N_( L"Block created by the . builtin" ) |
| Source block description. | |
| #define | EVENT_BLOCK N_( L"event handler block" ) |
| Source block description. | |
| #define | UNKNOWN_BLOCK N_( L"unknown/invalid block" ) |
| Unknown block description. | |
Functions | |
| static int | parse_job (process_t *p, job_t *j, tokenizer *tok) |
| Fully parse a single job. | |
| void | parser_push_block (int type) |
| Return the current number of block nestings. | |
| void | parser_pop_block () |
| Remove the outermost block namespace. | |
| const wchar_t * | parser_get_block_desc (int block) |
| Return a description of the given blocktype. | |
| static int | parser_is_pipe_forbidden (wchar_t *word) |
| Returns 1 if the specified command is a builtin that may not be used in a pipeline. | |
| static const wchar_t * | parser_find_end (const wchar_t *buff) |
| Search the text for the end of the current block. | |
| void | parser_forbid_function (wchar_t *function) |
| Tell the parser that the specified function may not be run if not inside of a conditional block. | |
| void | parser_allow_function () |
| Undo last call to parser_forbid_function(). | |
| void | error (int ec, int p, const wchar_t *str,...) |
| Sets the current evaluation error. | |
| void | parser_init () |
| Initialize static parser data. | |
| static void | print_profile (array_list_t *p, int pos, FILE *out) |
| Print profiling information to the specified stream. | |
| void | parser_destroy () |
| Destroy static parser data. | |
| static void | print_errors (string_buffer_t *target, const wchar_t *prefix) |
| Print error message to string_buffer_t if an error has occured while parsing. | |
| static void | print_errors_stderr () |
| Print error message to stderr if an error has occured while parsing. | |
| int | eval_args (const wchar_t *line, array_list_t *args) |
| Evaluate line as a list of parameters, i.e. | |
| void | parser_stack_trace (block_t *b, string_buffer_t *buff) |
| Write a stack trace starting at the specified block to the specified string_buffer_t. | |
| static const wchar_t * | is_function () |
| Returns the name of the currently evaluated function if we are currently evaluating a function, null otherwise. | |
| int | parser_get_lineno () |
| Returns the current line number. | |
| const wchar_t * | parser_current_filename () |
| Returns the file currently evaluated by the parser. | |
| static int | printed_width (const wchar_t *str, int len) |
| Calculates the on-screen width of the specified substring of the specified string. | |
| wchar_t * | parser_current_line () |
| Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'. | |
| int | parser_get_pos () |
| Returns the current position in the latest string of the tokenizer. | |
| int | parser_get_job_pos () |
| Returns the position where the current job started in the latest string of the tokenizer. | |
| void | parser_set_pos (int p) |
| Set the current position in the latest string of the tokenizer. | |
| const wchar_t * | parser_get_buffer () |
| Get the string currently parsed. | |
| int | parser_is_help (wchar_t *s, int min_match) |
| This function checks if the specified string is a help option. | |
| static void | parse_job_argument_list (process_t *p, job_t *j, tokenizer *tok, array_list_t *args) |
| Parse options for the specified job. | |
| static void | skipped_exec (job_t *j) |
| Do skipped execution of command. | |
| static void | eval_job (tokenizer *tok) |
| Evaluates a job from the specified tokenizer. | |
| int | eval (const wchar_t *cmd, io_data_t *io, int block_type) |
| Evaluate the expressions contained in cmd. | |
| int | parser_get_block_type (const wchar_t *cmd) |
| const wchar_t * | parser_get_block_command (int type) |
| static int | parser_test_argument (const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset) |
| Test if this argument contains any errors. | |
| int | parser_test_args (const wchar_t *buff, string_buffer_t *out, const wchar_t *prefix) |
| Test if the specified string can be parsed as an argument list, e.g. | |
| int | parser_test (const wchar_t *buff, int *block_level, string_buffer_t *out, const wchar_t *prefix) |
| Test if the specified string can be parsed, or if more bytes need to be read first. | |
Variables | |
|
static const struct block_lookup_entry | block_lookup [] |
| List of all legal block types. | |
| static int | error_code |
| Last error code. | |
| event_block_t * | global_event_block = 0 |
| Global event blocks. | |
| io_data_t * | block_io |
| Current block level io redirections. | |
| static int | err_pos |
| Position of last error. | |
| static string_buffer_t * | err_buff = 0 |
| Description of last error. | |
| static tokenizer * | current_tokenizer |
| Pointer to the current tokenizer. | |
| static string_buffer_t * | lineinfo = 0 |
| String for representing the current line. | |
| static int | current_tokenizer_pos |
| This is the position of the beginning of the currently parsed command. | |
| block_t * | current_block = 0 |
| The current innermost block. | |
| static array_list_t * | forbidden_function |
| List of called functions, used to help prevent infinite recursion. | |
| static int | job_start_pos |
| String index where the current job started. | |
| static array_list_t | profile_data |
| List of all profiling data. | |
| static int | eval_level = -1 |
| Keeps track of how many recursive eval calls have been made. | |
Contains functions for parsing and evaluating code.
| #define BLOCK_MAX_COUNT 64 |
Maximum number of block levels in code.
This is not the same as maximum recursion depth, this only has to do with how many block levels are legal in the source code, not at evaluation.
Referenced by parser_test().
| #define MAX_RECURSION_DEPTH 128 |
| #define TOK_ERR_MSG _( L"Tokenizer error: '%ls'") |
Error message for tokenizer error.
The tokenizer message is appended to this message.
Referenced by eval_args(), eval_job(), parse_job(), parse_job_argument_list(), parser_test(), and parser_test_args().
| void error | ( | int | ec, | |
| int | p, | |||
| const wchar_t * | str, | |||
| ... | ||||
| ) |
Sets the current evaluation error.
This function should only be used by libraries that are called by
| ec | The new error code | |
| p | The character offset at which the error occured | |
| str | The printf-style error message filter |
References CHECK, err_pos, error_code, global_context, sb_clear(), sb_halloc(), and sb_vprintf().
| int eval | ( | const wchar_t * | cmd, | |
| io_data_t * | io, | |||
| int | block_type | |||
| ) |
Evaluate the expressions contained in cmd.
| cmd | the string to evaluate | |
| io | io redirections to perform on all started jobs | |
| block_type | The type of block to push on the block stack |
References _, al_destroy(), al_get_count(), al_new(), BLOCK_END_ERR_MSG, bugreport(), builtin_help_get(), CHECK_BLOCK, debug(), error_code, eval_job(), eval_level, EVAL_NULL_ERR_MSG, event_fire(), exit_status(), FATAL_EXIT, INVALID_SCOPE_ERR_MSG, job_reap(), parser_allow_function(), parser_current_line(), parser_get_block_desc(), parser_pop_block(), parser_push_block(), print_errors_stderr(), proc_get_last_status(), sanity_check(), SUBST, tok_destroy(), tok_has_next(), tok_init(), TOP, and block::type.
Referenced by event_fire_internal(), exec_subshell(), input_exec_binding(), internal_exec_helper(), main(), read_init(), read_ni(), reader_run_command(), run_pager(), start_fishd(), and test_parser().
| int eval_args | ( | const wchar_t * | line, | |
| array_list_t * | output | |||
| ) |
Evaluate line as a list of parameters, i.e.
tokenize it and perform parameter expansion and cmdsubst execution on the tokens. The output is inserted into output, and should be freed by the caller.
| line | Line to evaluate | |
| output | List to insert output to |
References CHECK, current_tokenizer_pos, DIE_MEM, err_pos, error, error_code, EXPAND_ERROR, expand_string(), print_errors_stderr(), proc_pop_interactive(), proc_push_interactive(), SYNTAX_ERROR, tmp, tok_destroy(), TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_pos(), tok_has_next(), tok_init(), tok_last(), tok_last_type(), tok_next(), TOK_STRING, and UNEXPECTED_TOKEN_ERR_MSG.
Referenced by complete_from_args().
| static void eval_job | ( | tokenizer * | tok | ) | [static] |
Evaluates a job from the specified tokenizer.
First calls parse_job to parse the job and then calls exec to execute it.
| tok | The tokenizer to read tokens from |
References al_push(), process::argv, profile_element_t::cmd, CMD_AND_ERR_MSG, CMD_ERR_MSG, job::command, current_tokenizer_pos, DIE_MEM, error, eval_level, profile_element_t::exec, exec(), job::first_process, get_time(), halloc(), halloc_wcsndup(), IF, block::if_state, is_block, is_event, is_interactive, is_subshell, block::job, JOB_CONTROL, job_create(), JOB_FOREGROUND, job_free(), job_get_flag(), job_reap(), job_set_flag(), JOB_SKIP, JOB_SKIP_NOTIFICATION, job_start_pos, JOB_TERMINAL, JOB_WILDCARD_ERROR, profile_element_t::level, mini(), block::param1, profile_element_t::parse, parse_job(), proc_get_last_status(), proc_had_barrier, proc_set_last_status(), profile, block::skip, profile_element_t::skipped, skipped_exec(), SYNTAX_ERROR, job::tmodes, TOK_BACKGROUND, TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_pos(), tok_has_next(), tok_last(), tok_last_type(), tok_next(), tok_string(), TOK_STRING, block::type, WHILE, block::while_state, WHILE_TEST_FIRST, WHILE_TESTED, and wperror().
Referenced by eval().
| static const wchar_t* is_function | ( | ) | [static] |
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.
References FUNCTION_CALL, block::function_call_name, block::outer, block::param1, and block::type.
Referenced by parser_current_line(), and parser_get_lineno().
Fully parse a single job.
Does not call exec on it, but any command substitutions in the job will be executed.
| p | The process structure that should be used to represent the first process in the job. | |
| j | The job structure to contain the parsed job | |
| tok | tokenizer to read from |
References _, process::actual_cmd, al_get(), al_get_count(), al_halloc(), al_peek(), al_push(), al_set(), al_truncate(), process::argv, BLOCK_END_ERR_MSG, builtin_exists(), CMD_ERR_MSG, CMD_OR_ERR_MSG, COMMAND_ASSIGN_ERR_MSG, contains, current_tokenizer_pos, debug(), env_get(), err(), error, error_code, event_fire_generic, EXEC_ERR_MSG, expand_one(), EXPAND_SKIP_CMDSUBST, EXPAND_SKIP_VARIABLES, EXTERNAL, job::first_process, FUNCTION_CALL, function_exists(), block::had_command, halloc_register(), halloc_wcsdup(), halloc_wcsndup(), IF, block::if_state, ILLEGAL_CMD_ERR_MSG, INTERNAL_BLOCK, INTERNAL_BUILTIN, INTERNAL_EXEC, INTERNAL_FUNCTION, job_get_flag(), JOB_NEGATE, job_set_flag(), JOB_SKIP, list_to_char_arr(), MAX_RECURSION_DEPTH, block::outer, block::param1, parse_job_argument_list(), parser_current_line(), parser_find_end(), parser_keywords_is_block(), parser_keywords_is_switch(), parser_keywords_skip_arguments(), parser_pop_block(), parser_push_block(), proc_get_last_status(), proc_set_last_status(), RECURSION_ERR_MSG, block::skip, STATUS_NOT_EXECUTABLE, STATUS_UNKNOWN_COMMAND, SYNTAX_ERROR, tmp, tok_destroy(), TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_pos(), tok_has_next(), tok_init(), tok_last(), tok_last_type(), tok_next(), TOK_PIPE, block::tok_pos, TOK_REDIRECT_APPEND, TOK_REDIRECT_FD, TOK_REDIRECT_IN, TOK_REDIRECT_NOCLOB, TOK_REDIRECT_OUT, tok_set_pos(), tok_string(), TOK_STRING, TOP, block::type, process::type, UNKNOWN_BUILTIN_ERR_MSG, WHILE, block::while_state, WHILE_TEST_AGAIN, and WHILE_TEST_FIRST.
Referenced by eval_job(), and parse_job_argument_list().
| static void parse_job_argument_list | ( | process_t * | p, | |
| job_t * | j, | |||
| tokenizer * | tok, | |||
| array_list_t * | args | |||
| ) | [static] |
Parse options for the specified job.
| p | the process to parse options for | |
| j | the job to which the process belongs to | |
| tok | the tokenizer to read options from | |
| args | the argument list to insert options into |
References _, al_get(), al_get_count(), process::argv, process::count_help_magic, current_tokenizer_pos, debug(), DIE_MEM, err_pos, error, error_code, EXEC_ERR_MSG, EXPAND_ERROR, EXPAND_OK, expand_one(), expand_string(), EXPAND_WILDCARD_NO_MATCH, io_data::fd, io_data::filename, io_data::flags, halloc(), halloc_register(), halloc_wcsdup(), ILLEGAL_FD_ERR_MSG, INTERNAL_BUILTIN, INTERNAL_EXEC, job::io, io_add(), io_data::io_mode, is_block, is_interactive, JOB_FOREGROUND, job_get_flag(), job_set_flag(), JOB_SKIP, JOB_WILDCARD_ERROR, list_to_char_arr(), process::next, io_data::old_fd, io_data::param1, io_data::param2, parse_job(), parser_current_line(), parser_is_help(), process::pipe_write_fd, proc_set_last_status(), REDIRECT_TOKEN_ERR_MSG, block::skip, STATUS_UNMATCHED_WILDCARD, SWITCH, SYNTAX_ERROR, tmp, TOK_BACKGROUND, TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_pos(), tok_has_next(), tok_last(), tok_last_type(), tok_next(), TOK_PIPE, TOK_REDIRECT_APPEND, TOK_REDIRECT_FD, TOK_REDIRECT_IN, TOK_REDIRECT_NOCLOB, TOK_REDIRECT_OUT, TOK_STRING, block_lookup_entry::type, block::type, process::type, UNEXPECTED_TOKEN_ERR_MSG, and WILDCARD_ERR_MSG.
Referenced by parse_job().
| const wchar_t* parser_current_filename | ( | ) |
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.
References FUNCTION_CALL, block::function_call_name, function_get_definition_file(), block::outer, block::param1, reader_current_filename(), and block::type.
Referenced by builtin_status(), parser_current_line(), and parser_push_block().
| wchar_t* parser_current_line | ( | ) |
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
Example:
init.fish (line 127): ls|grep pancake
If we are not going to print a stack trace, at least print the line number and filename
References _, buffer::buff, current_tokenizer_pos, function_get_definition_offset(), is_function(), is_interactive, my_wcswidth(), parser_current_filename(), parser_stack_trace(), printed_width(), sb_clear(), sb_init(), sb_printf(), and tok_string().
Referenced by builtin_cd(), builtin_print_help(), eval(), parse_job(), parse_job_argument_list(), print_errors(), and print_errors_stderr().
| void parser_forbid_function | ( | wchar_t * | function | ) |
| const wchar_t* parser_get_block_command | ( | int | type | ) |
| int parser_get_block_type | ( | const wchar_t * | cmd | ) |
References block_lookup_entry::desc, block_lookup_entry::name, and block_lookup_entry::type.
Referenced by parser_test().
| int parser_is_help | ( | wchar_t * | s, | |
| int | min_match | |||
| ) |
This function checks if the specified string is a help option.
| s | the string to test | |
| min_match | is the minimum number of characters that must match in a long style option, i.e. the longest common prefix between --help and any other option. If less than 3, 3 will be assumed. |
Referenced by builtin_run(), parse_job_argument_list(), and parser_test().
| void parser_push_block | ( | int | type | ) |
Return the current number of block nestings.
Create block of specified type.
References env_pop(), env_push(), FAKE, FUNCTION_CALL, FUNCTION_DEF, halloc(), halloc_register_function_void(), intern(), LOOP_NORMAL, parser_current_filename(), parser_get_lineno(), block::skip, SUBST, TOP, and block::type.
Referenced by builtin_begin(), builtin_breakpoint(), builtin_for(), builtin_function(), builtin_source(), builtin_switch(), eval(), event_fire_internal(), exec(), parse_job(), and skipped_exec().
| int parser_test | ( | const wchar_t * | buff, | |
| int * | block_level, | |||
| string_buffer_t * | out, | |||
| const wchar_t * | prefix | |||
| ) |
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.
| buff | the text buffer to test | |
| block_level | if non-null, the block nesting level will be filled out into this array | |
| out | if non-null, any errors in the command will be filled out into this buffer | |
| prefix | the prefix string to prepend to each error message written to the out buffer |
References BLOCK_END_ERR_MSG, BLOCK_ERR_MSG, BLOCK_MAX_COUNT, BUILTIN_FOR_ERR_COUNT, BUILTIN_FOR_ERR_IN, builtin_help_get(), CHECK, CMD_AND_ERR_MSG, CMD_ERR_MSG, CMD_OR_ERR_MSG, COND_ERR_MSG, contains, current_tokenizer_pos, err(), error, error_code, EXEC_ERR_MSG, expand_is_clean(), expand_one(), EXPAND_SKIP_CMDSUBST, EXPAND_SKIP_VARIABLES, FOR, FUNCTION_DEF, halloc(), halloc_free(), IF, ILLEGAL_CMD_ERR_MSG, INVALID_CASE_ERR_MSG, INVALID_ELSE_ERR_MSG, INVALID_END_ERR_MSG, INVALID_LOOP_ERR_MSG, INVALID_REDIRECTION_ERR_MSG, INVALID_RETURN_ERR_MSG, parser_get_block_command(), parser_get_block_type(), parser_is_help(), parser_is_pipe_forbidden(), parser_keywords_is_block(), parser_keywords_is_subcommand(), parser_keywords_skip_arguments(), parser_test_argument(), print_errors(), sb_printf(), SWITCH, SYNTAX_ERROR, TOK_BACKGROUND, tok_destroy(), TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_error(), tok_get_pos(), tok_has_next(), tok_init(), tok_last(), tok_last_type(), tok_next(), TOK_PIPE, TOK_REDIRECT_APPEND, TOK_REDIRECT_FD, TOK_REDIRECT_IN, TOK_REDIRECT_NOCLOB, TOK_REDIRECT_OUT, tok_set_pos(), TOK_STRING, wcsvarname(), and WHILE.
Referenced by builtin_complete(), parser_test_argument(), read_ni(), reader_repaint(), reader_shell_test(), and test_parser().
| int parser_test_args | ( | const wchar_t * | buff, | |
| string_buffer_t * | out, | |||
| const wchar_t * | prefix | |||
| ) |
Test if the specified string can be parsed as an argument list, e.g.
sent to eval_args. The result has the first bit set if the string contains errors, and the second bit is set if the string contains an unclosed block.
References CHECK, current_tokenizer_pos, err(), error, error_code, parser_test_argument(), print_errors(), SYNTAX_ERROR, tok_destroy(), TOK_END, TOK_ERR_MSG, TOK_ERROR, tok_get_desc(), tok_get_pos(), tok_has_next(), tok_init(), tok_last(), tok_last_type(), tok_next(), TOK_STRING, and UNEXPECTED_TOKEN_ERR_MSG.
Referenced by builtin_complete().
| static int parser_test_argument | ( | const wchar_t * | arg, | |
| string_buffer_t * | out, | |||
| const wchar_t * | prefix, | |||
| int | offset | |||
| ) | [static] |
Test if this argument contains any errors.
Detected errors include syntax errors in command substitutions, improperly escaped characters and improper use of the variable expansion operator.
References buffer::buff, CHECK, err(), error, expand_variable_error(), INTERNAL_SEPARATOR, parse_util_locate_cmdsubst(), parser_test(), print_errors(), sb_append, sb_append_char(), sb_append_substring(), sb_init(), SYNTAX_ERROR, tmp, unescape(), VARIABLE_EXPAND, VARIABLE_EXPAND_SINGLE, and wcsvarchr().
Referenced by parser_test(), and parser_test_args().
| static void print_errors | ( | string_buffer_t * | target, | |
| const wchar_t * | prefix | |||
| ) | [static] |
Print error message to string_buffer_t if an error has occured while parsing.
| target | the buffer to write to | |
| prefix,: | The string token to prefix the ech line with. Usually the name of the command trying to parse something. |
References buffer::buff, CHECK, current_tokenizer_pos, err_pos, error_code, parser_current_line(), sb_printf(), and tmp.
Referenced by parser_test(), parser_test_args(), and parser_test_argument().
| static int printed_width | ( | const wchar_t * | str, | |
| int | len | |||
| ) | [static] |
Calculates the on-screen width of the specified substring of the specified string.
This function takes into account the width and allignment of the tab character, but other wise behaves like repeatedly calling wcwidth.
References CHECK.
Referenced by parser_current_line().
| static void skipped_exec | ( | job_t * | j | ) | [static] |
Do skipped execution of command.
This means that only limited execution of block level commands such as end and switch should be preformed.
| j | the job to execute |
References process::argv, exec(), FAKE, job::first_process, IF, block::if_state, INTERNAL_BUILTIN, job_free(), process::next, block::outer, block::param1, parser_pop_block(), parser_push_block(), block::skip, SWITCH, block::type, and process::type.
Referenced by eval_job().
int eval_level = -1 [static] |
Keeps track of how many recursive eval calls have been made.
Eval doesn't call itself directly, recursion happens on blocks and on command substitutions.
Referenced by eval(), and eval_job().
1.5.6