From b0b048c03930b826ab3dbf88b56fd664fca26886 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 22 May 2020 15:32:31 +0300 Subject: Add script command redirect aliases --- libbuild2/script/lexer.hxx | 53 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) (limited to 'libbuild2/script/lexer.hxx') diff --git a/libbuild2/script/lexer.hxx b/libbuild2/script/lexer.hxx index c0d617d..bdeba66 100644 --- a/libbuild2/script/lexer.hxx +++ b/libbuild2/script/lexer.hxx @@ -33,21 +33,58 @@ namespace build2 lexer_mode (base_type v): base_type (v) {} }; + // Redirects the <, <<, <<<, >, >>, and >>> aliases resolve to. + // + struct redirect_aliases + { + optional l; // < + optional ll; // << + optional lll; // <<< + optional g; // > + optional gg; // >> + optional ggg; // >>> + + // If the token type is a redirect alias then return the token type + // it resolves to and the passed type otherwise. It's the caller's + // responsibility to make sure that the corresponding alias is present. + // + token_type + resolve (token_type t) const noexcept + { + switch (t) + { + case token_type::in_l: assert (l); return *l; + case token_type::in_ll: assert (ll); return *ll; + case token_type::in_lll: assert (lll); return *lll; + case token_type::out_g: assert (g); return *g; + case token_type::out_gg: assert (gg); return *gg; + case token_type::out_ggg: assert (ggg); return *ggg; + } + + return t; + } + }; + class lexer: public build2::lexer { public: using base_lexer = build2::lexer; using base_mode = build2::lexer_mode; - // Note that neither the name nor escape arguments are copied. + using redirect_aliases_type = script::redirect_aliases; + + // Note that none of the name, redirect aliases, and escape arguments + // are copied. // lexer (istream& is, const path_name& name, lexer_mode m, + const redirect_aliases_type& ra, const char* escapes = nullptr) : base_lexer (is, name, 1 /* line */, nullptr /* escapes */, - false /* set_mode */) + false /* set_mode */), + redirect_aliases (ra) { mode (m, '\0', escapes); } @@ -69,19 +106,23 @@ namespace build2 virtual token next () override; + public: + const redirect_aliases_type& redirect_aliases; + protected: lexer (istream& is, const path_name& name, uint64_t line, const char* escapes, - bool set_mode) - : base_lexer (is, name, line, escapes, set_mode) {} + bool set_mode, + const redirect_aliases_type& ra) + : base_lexer (is, name, line, escapes, set_mode), + redirect_aliases (ra) {} // Return the next token if it is a command operator (|, ||, &&, // redirect, or cleanup) and nullopt otherwise. // optional next_cmd_op (const xchar&, // The token first character (last got char). - bool sep, // The token is separated. - lexer_mode); // The current (potentially "expired") mode. + bool sep); // The token is separated. private: token -- cgit v1.1