2016-05-03 07:53:10 +08:00
|
|
|
// Various mostly unrelated utility functions related to parsing, loading and evaluating fish code.
|
2006-01-31 00:51:50 +08:00
|
|
|
#ifndef FISH_PARSE_UTIL_H
|
|
|
|
#define FISH_PARSE_UTIL_H
|
|
|
|
|
2015-07-25 23:14:25 +08:00
|
|
|
#include <stddef.h>
|
2017-02-14 12:37:27 +08:00
|
|
|
|
2015-07-25 23:14:25 +08:00
|
|
|
#include <vector>
|
2016-04-21 14:00:54 +08:00
|
|
|
|
2015-07-25 23:14:25 +08:00
|
|
|
#include "common.h"
|
2017-12-23 06:40:15 +08:00
|
|
|
#include "parse_tree.h"
|
2016-04-21 14:00:54 +08:00
|
|
|
#include "tokenizer.h"
|
2012-01-24 03:42:41 +08:00
|
|
|
|
2020-07-02 12:06:58 +08:00
|
|
|
namespace ast {
|
|
|
|
struct argument_t;
|
|
|
|
}
|
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Same as parse_util_locate_cmdsubst, but handles square brackets [ ].
|
|
|
|
int parse_util_locate_slice(const wchar_t *in, wchar_t **begin, wchar_t **end,
|
2014-02-04 06:13:42 +08:00
|
|
|
bool accept_incomplete);
|
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Alternative API. Iterate over command substitutions.
|
|
|
|
///
|
|
|
|
/// \param str the string to search for subshells
|
|
|
|
/// \param inout_cursor_offset On input, the location to begin the search. On output, either the end
|
|
|
|
/// of the string, or just after the closed-paren.
|
|
|
|
/// \param out_contents On output, the contents of the command substitution
|
|
|
|
/// \param out_start On output, the offset of the start of the command substitution (open paren)
|
|
|
|
/// \param out_end On output, the offset of the end of the command substitution (close paren), or
|
|
|
|
/// the end of the string if it was incomplete
|
|
|
|
/// \param accept_incomplete whether to permit missing closing parenthesis
|
|
|
|
/// \return -1 on syntax error, 0 if no subshells exist and 1 on success
|
|
|
|
int parse_util_locate_cmdsubst_range(const wcstring &str, size_t *inout_cursor_offset,
|
|
|
|
wcstring *out_contents, size_t *out_start, size_t *out_end,
|
2014-01-15 17:40:40 +08:00
|
|
|
bool accept_incomplete);
|
2013-10-09 09:41:35 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Find the beginning and end of the command substitution under the cursor. If no subshell is
|
|
|
|
/// found, the entire string is returned. If the current command substitution is not ended, i.e. the
|
|
|
|
/// closing parenthesis is missing, then the string from the beginning of the substitution to the
|
|
|
|
/// end of the string is returned.
|
|
|
|
///
|
|
|
|
/// \param buff the string to search for subshells
|
|
|
|
/// \param cursor_pos the position of the cursor
|
|
|
|
/// \param a the start of the searched string
|
|
|
|
/// \param b the end of the searched string
|
|
|
|
void parse_util_cmdsubst_extent(const wchar_t *buff, size_t cursor_pos, const wchar_t **a,
|
2012-11-19 08:30:30 +08:00
|
|
|
const wchar_t **b);
|
2006-01-31 00:51:50 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Find the beginning and end of the process definition under the cursor
|
|
|
|
///
|
|
|
|
/// \param buff the string to search for subshells
|
|
|
|
/// \param cursor_pos the position of the cursor
|
2019-10-29 20:32:26 +08:00
|
|
|
/// \param a the start of the process
|
|
|
|
/// \param b the end of the process
|
|
|
|
/// \param tokens the tokens in the process
|
2016-05-03 07:53:10 +08:00
|
|
|
void parse_util_process_extent(const wchar_t *buff, size_t cursor_pos, const wchar_t **a,
|
2019-10-29 20:32:26 +08:00
|
|
|
const wchar_t **b, std::vector<tok_t> *tokens);
|
2006-01-31 00:51:50 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Find the beginning and end of the job definition under the cursor
|
|
|
|
///
|
|
|
|
/// \param buff the string to search for subshells
|
|
|
|
/// \param cursor_pos the position of the cursor
|
|
|
|
/// \param a the start of the searched string
|
|
|
|
/// \param b the end of the searched string
|
|
|
|
void parse_util_job_extent(const wchar_t *buff, size_t cursor_pos, const wchar_t **a,
|
2012-11-19 08:30:30 +08:00
|
|
|
const wchar_t **b);
|
2006-01-31 00:51:50 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Find the beginning and end of the token under the cursor and the token before the current token.
|
|
|
|
/// Any combination of tok_begin, tok_end, prev_begin and prev_end may be null.
|
|
|
|
///
|
|
|
|
/// \param buff the string to search for subshells
|
|
|
|
/// \param cursor_pos the position of the cursor
|
|
|
|
/// \param tok_begin the start of the current token
|
|
|
|
/// \param tok_end the end of the current token
|
|
|
|
/// \param prev_begin the start o the token before the current token
|
|
|
|
/// \param prev_end the end of the token before the current token
|
|
|
|
void parse_util_token_extent(const wchar_t *buff, size_t cursor_pos, const wchar_t **tok_begin,
|
|
|
|
const wchar_t **tok_end, const wchar_t **prev_begin,
|
2012-11-19 08:30:30 +08:00
|
|
|
const wchar_t **prev_end);
|
2006-01-31 00:51:50 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Get the linenumber at the specified character offset.
|
2019-11-19 08:54:36 +08:00
|
|
|
int parse_util_lineno(const wchar_t *str, size_t offset);
|
2006-02-05 21:10:35 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Calculate the line number of the specified cursor position.
|
2012-11-19 08:30:30 +08:00
|
|
|
int parse_util_get_line_from_offset(const wcstring &str, size_t pos);
|
2007-09-21 22:05:49 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Get the offset of the first character on the specified line.
|
2012-11-19 08:30:30 +08:00
|
|
|
size_t parse_util_get_offset_from_line(const wcstring &str, int line);
|
2007-09-21 22:05:49 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Return the total offset of the buffer for the cursor position nearest to the specified poition.
|
2012-11-19 08:30:30 +08:00
|
|
|
size_t parse_util_get_offset(const wcstring &str, int line, long line_offset);
|
2007-09-21 22:05:49 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Return the given string, unescaping wildcard characters but not performing any other character
|
|
|
|
/// transformation.
|
2019-11-19 08:54:36 +08:00
|
|
|
wcstring parse_util_unescape_wildcards(const wcstring &str);
|
2006-02-19 09:14:32 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Checks if the specified string is a help option.
|
2021-02-15 05:15:29 +08:00
|
|
|
bool parse_util_argument_is_help(const wcstring &s);
|
2014-03-19 05:42:38 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Calculates information on the parameter at the specified index.
|
|
|
|
///
|
|
|
|
/// \param cmd The command to be analyzed
|
|
|
|
/// \param pos An index in the string which is inside the parameter
|
|
|
|
/// \param quote If not NULL, store the type of quote this parameter has, can be either ', " or \\0,
|
|
|
|
/// meaning the string is not quoted.
|
|
|
|
/// \param offset If not NULL, get_param will store the offset to the beginning of the parameter.
|
2016-06-06 09:46:04 +08:00
|
|
|
/// \param out_type If not NULL, get_param will store the token type.
|
2016-05-03 07:53:10 +08:00
|
|
|
void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_t *quote,
|
2019-10-14 07:06:16 +08:00
|
|
|
size_t *offset, token_type_t *out_type);
|
2016-05-03 07:53:10 +08:00
|
|
|
|
|
|
|
/// Attempts to escape the string 'cmd' using the given quote type, as determined by the quote
|
|
|
|
/// character. The quote can be a single quote or double quote, or L'\0' to indicate no quoting (and
|
2018-02-18 06:36:43 +08:00
|
|
|
/// thus escaping should be with backslashes). Optionally do not escape tildes.
|
|
|
|
wcstring parse_util_escape_string_with_quote(const wcstring &cmd, wchar_t quote,
|
|
|
|
bool no_tilde = false);
|
2007-04-22 17:50:26 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Given a string, parse it as fish code and then return the indents. The return value has the same
|
|
|
|
/// size as the string.
|
2013-12-09 05:41:12 +08:00
|
|
|
std::vector<int> parse_util_compute_indents(const wcstring &src);
|
2007-04-22 17:50:26 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// Given a string, detect parse errors in it. If allow_incomplete is set, then if the string is
|
|
|
|
/// incomplete (e.g. an unclosed quote), an error is not returned and the PARSER_TEST_INCOMPLETE bit
|
|
|
|
/// is set in the return value. If allow_incomplete is not set, then incomplete strings result in an
|
2020-12-21 05:36:56 +08:00
|
|
|
/// error.
|
2016-05-03 07:53:10 +08:00
|
|
|
parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
2019-11-19 10:34:50 +08:00
|
|
|
parse_error_list_t *out_errors = nullptr,
|
2020-07-13 04:55:51 +08:00
|
|
|
bool allow_incomplete = false);
|
|
|
|
|
|
|
|
/// Like parse_util_detect_errors but accepts an already-parsed ast.
|
|
|
|
/// The top of the ast is assumed to be a job list.
|
|
|
|
parser_test_error_bits_t parse_util_detect_errors(const ast::ast_t &ast, const wcstring &buff_src,
|
|
|
|
parse_error_list_t *out_errors);
|
2016-05-03 07:53:10 +08:00
|
|
|
|
2019-08-05 05:49:56 +08:00
|
|
|
/// Detect errors in the specified string when parsed as an argument list. Returns the text of an
|
|
|
|
/// error, or none if no error occurred.
|
|
|
|
maybe_t<wcstring> parse_util_detect_errors_in_argument_list(const wcstring &arg_list_src,
|
|
|
|
const wcstring &prefix = {});
|
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
/// 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. This does NOT currently detect unterminated quotes.
|
2020-07-02 12:06:58 +08:00
|
|
|
|
2016-05-03 07:53:10 +08:00
|
|
|
parser_test_error_bits_t parse_util_detect_errors_in_argument(
|
2020-07-02 12:06:58 +08:00
|
|
|
const ast::argument_t &arg, const wcstring &arg_src, parse_error_list_t *out_errors = nullptr);
|
2016-05-03 07:53:10 +08:00
|
|
|
|
|
|
|
/// Given a string containing a variable expansion error, append an appropriate error to the errors
|
|
|
|
/// list. The global_token_pos is the offset of the token in the larger source, and the dollar_pos
|
|
|
|
/// is the offset of the offending dollar sign within the token.
|
|
|
|
void parse_util_expand_variable_error(const wcstring &token, size_t global_token_pos,
|
|
|
|
size_t dollar_pos, parse_error_list_t *out_errors);
|
2015-04-30 07:53:02 +08:00
|
|
|
|
2006-01-31 00:51:50 +08:00
|
|
|
#endif
|