2016-05-02 16:09:46 -07:00
|
|
|
// Programmatic representation of fish code.
|
2013-07-25 15:24:22 -07:00
|
|
|
#ifndef FISH_PARSE_PRODUCTIONS_H
|
|
|
|
#define FISH_PARSE_PRODUCTIONS_H
|
2013-05-26 12:12:16 -07:00
|
|
|
|
2015-07-25 23:14:25 +08:00
|
|
|
#include <stddef.h>
|
2017-02-12 20:24:22 -08:00
|
|
|
#include <stdint.h>
|
2016-04-20 23:00:54 -07:00
|
|
|
#include <sys/types.h>
|
2017-02-13 20:37:27 -08:00
|
|
|
|
2020-06-20 15:27:10 -07:00
|
|
|
#include <deque>
|
2016-05-02 16:09:46 -07:00
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
2013-05-26 12:12:16 -07:00
|
|
|
|
2020-07-07 16:16:45 -07:00
|
|
|
#include "ast.h"
|
2013-05-26 12:12:16 -07:00
|
|
|
#include "common.h"
|
2018-01-07 19:50:34 -08:00
|
|
|
#include "maybe.h"
|
2013-12-08 21:54:06 -08:00
|
|
|
#include "parse_constants.h"
|
2016-05-02 16:09:46 -07:00
|
|
|
#include "tokenizer.h"
|
2013-06-11 09:37:51 -07:00
|
|
|
|
2014-03-25 20:06:34 -07:00
|
|
|
typedef uint32_t source_offset_t;
|
|
|
|
|
2017-01-26 17:28:46 -08:00
|
|
|
constexpr source_offset_t SOURCE_OFFSET_INVALID = static_cast<source_offset_t>(-1);
|
2014-03-25 20:06:34 -07:00
|
|
|
|
2016-05-02 16:09:46 -07:00
|
|
|
/// A struct representing the token type that we use internally.
|
|
|
|
struct parse_token_t {
|
|
|
|
enum parse_token_type_t type; // The type of the token as represented by the parser
|
2020-06-09 15:13:02 -07:00
|
|
|
enum parse_keyword_t keyword {
|
|
|
|
parse_keyword_t::none
|
2020-07-12 12:20:38 -07:00
|
|
|
}; // Any keyword represented by this token
|
|
|
|
bool has_dash_prefix{false}; // Hackish: whether the source contains a dash prefix
|
|
|
|
bool is_help_argument{false}; // Hackish: whether the source looks like '-h' or '--help'
|
|
|
|
bool is_newline{false}; // Hackish: if TOK_END, whether the source is a newline.
|
Support FOO=bar syntax for passing variables to individual commands
This adds initial support for statements with prefixed variable assignments.
Statments like this are supported:
a=1 b=$a echo $b # outputs 1
Just like in other shells, the left-hand side of each assignment must
be a valid variable identifier (no quoting/escaping). Array indexing
(PATH[1]=/bin ls $PATH) is *not* yet supported, but can be added fairly
easily.
The right hand side may be any valid string token, like a command
substitution, or a brace expansion.
Since `a=* foo` is equivalent to `begin set -lx a *; foo; end`,
the assignment, like `set`, uses nullglob behavior, e.g. below command
can safely be used to check if a directory is empty.
x=/nothing/{,.}* test (count $x) -eq 0
Generic file completion is done after the equal sign, so for example
pressing tab after something like `HOME=/` completes files in the
root directory
Subcommand completion works, so something like
`GIT_DIR=repo.git and command git ` correctly calls git completions
(but the git completion does not use the variable as of now).
The variable assignment is highlighted like an argument.
Closes #6048
2019-10-23 03:13:29 +02:00
|
|
|
bool may_be_variable_assignment{false}; // Hackish: whether this token is a string like FOO=bar
|
2020-07-12 12:20:38 -07:00
|
|
|
tokenizer_error_t tok_error{
|
|
|
|
tokenizer_error_t::none}; // If this is a tokenizer error, that error.
|
2018-05-07 15:22:09 -07:00
|
|
|
source_offset_t source_start{SOURCE_OFFSET_INVALID};
|
|
|
|
source_offset_t source_length{0};
|
2013-08-11 00:35:00 -07:00
|
|
|
|
2020-06-20 15:27:10 -07:00
|
|
|
/// \return the source range.
|
2020-07-01 21:06:58 -07:00
|
|
|
/// Note the start may be invalid.
|
2020-07-12 12:20:38 -07:00
|
|
|
source_range_t range() const { return source_range_t{source_start, source_length}; }
|
2020-06-20 15:27:10 -07:00
|
|
|
|
|
|
|
/// \return whether we are a string with the dash prefix set.
|
|
|
|
bool is_dash_prefix_string() const {
|
2020-07-08 11:12:15 -07:00
|
|
|
return type == parse_token_type_t::string && has_dash_prefix;
|
2020-06-20 15:27:10 -07:00
|
|
|
}
|
|
|
|
|
2013-10-12 02:46:49 -07:00
|
|
|
wcstring describe() const;
|
2014-01-01 00:04:02 -08:00
|
|
|
wcstring user_presentable_description() const;
|
2018-05-07 15:22:09 -07:00
|
|
|
|
|
|
|
constexpr parse_token_t(parse_token_type_t type) : type(type) {}
|
2013-08-11 00:35:00 -07:00
|
|
|
};
|
|
|
|
|
2016-04-10 19:08:07 -07:00
|
|
|
const wchar_t *token_type_description(parse_token_type_t type);
|
|
|
|
const wchar_t *keyword_description(parse_keyword_t type);
|
2013-06-23 02:09:46 -07:00
|
|
|
|
2020-06-20 15:27:10 -07:00
|
|
|
parse_error_code_t parse_error_from_tokenizer_error(tokenizer_error_t err);
|
|
|
|
|
2020-07-03 11:16:51 -07:00
|
|
|
namespace ast {
|
|
|
|
class ast_t;
|
|
|
|
}
|
|
|
|
|
2017-12-22 14:40:15 -08:00
|
|
|
/// A type wrapping up a parse tree and the original source behind it.
|
|
|
|
struct parsed_source_t {
|
|
|
|
wcstring src;
|
2020-07-07 16:16:45 -07:00
|
|
|
ast::ast_t ast;
|
2017-12-22 14:40:15 -08:00
|
|
|
|
2020-07-12 13:55:51 -07:00
|
|
|
parsed_source_t(wcstring &&s, ast::ast_t &&ast);
|
2020-07-03 11:16:51 -07:00
|
|
|
~parsed_source_t();
|
2017-12-22 14:40:15 -08:00
|
|
|
|
|
|
|
parsed_source_t(const parsed_source_t &) = delete;
|
|
|
|
void operator=(const parsed_source_t &) = delete;
|
2020-07-03 11:16:51 -07:00
|
|
|
parsed_source_t(parsed_source_t &&) = delete;
|
|
|
|
parsed_source_t &operator=(parsed_source_t &&) = delete;
|
2017-12-22 14:40:15 -08:00
|
|
|
};
|
2020-07-03 11:16:51 -07:00
|
|
|
|
2017-12-22 14:40:15 -08:00
|
|
|
/// Return a shared pointer to parsed_source_t, or null on failure.
|
2020-07-03 11:16:51 -07:00
|
|
|
/// If parse_flag_continue_after_error is not set, this will return null on any error.
|
2017-12-22 15:44:14 -08:00
|
|
|
using parsed_source_ref_t = std::shared_ptr<const parsed_source_t>;
|
2020-07-12 13:55:51 -07:00
|
|
|
parsed_source_ref_t parse_source(wcstring &&src, parse_tree_flags_t flags,
|
2020-06-28 16:53:58 -07:00
|
|
|
parse_error_list_t *errors);
|
2017-12-22 14:40:15 -08:00
|
|
|
|
2019-11-25 12:47:33 +01:00
|
|
|
/// Error message for improper use of the exec builtin.
|
|
|
|
#define EXEC_ERR_MSG _(L"The '%ls' command can not be used in a pipeline")
|
|
|
|
|
2013-05-26 12:12:16 -07:00
|
|
|
#endif
|