diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-03-01 17:26:07 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-01 17:26:07 +0000 |
commit | 6cf9f8c99c5813a23d7cec473fedf00683f409e4 (patch) | |
tree | cd590bc5f7b266c043499899e0529ff4c16cc5ec /gcc/rust/parse | |
parent | e82b59dfc9319d72f891bac099bfa0f46d8b8c99 (diff) | |
parent | f7ff6020f8c68e4fb54c17c4460aa7f8a31f85bd (diff) | |
download | gcc-6cf9f8c99c5813a23d7cec473fedf00683f409e4.zip gcc-6cf9f8c99c5813a23d7cec473fedf00683f409e4.tar.gz gcc-6cf9f8c99c5813a23d7cec473fedf00683f409e4.tar.bz2 |
Merge #983
983: Parse proper cfg values r=CohenArthur a=CohenArthur
Closes #936
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc/rust/parse')
-rw-r--r-- | gcc/rust/parse/rust-cfg-parser.cc | 102 | ||||
-rw-r--r-- | gcc/rust/parse/rust-cfg-parser.h | 3 |
2 files changed, 70 insertions, 35 deletions
diff --git a/gcc/rust/parse/rust-cfg-parser.cc b/gcc/rust/parse/rust-cfg-parser.cc index a6f34b6..f98419b 100644 --- a/gcc/rust/parse/rust-cfg-parser.cc +++ b/gcc/rust/parse/rust-cfg-parser.cc @@ -1,45 +1,55 @@ #include "rust-cfg-parser.h" +#include "rust-lex.h" +#include "rust-parse.h" +#include "rust-session-manager.h" #include "selftest.h" namespace Rust { bool -parse_cfg_option (const std::string &input, std::string &key, - std::string &value) +parse_cfg_option (std::string &input, std::string &key, std::string &value) { key.clear (); value.clear (); - auto equal = input.find ('='); + auto lexer = Lexer::lex_string (input); + auto parser = Parser<Lexer> (std::move (lexer)); - // If there is no equal sign, it means there is no value. Clean up the key - // and return - if (equal == std::string::npos) + auto token = parser.peek_current_token (); + if (token->get_id () != IDENTIFIER) { - key = input; - - // FIXME: Make sure key is a proper identifier - - return true; + return false; } - key = input.substr (0, equal); - - auto remaining_input = input.substr (equal + 1); - if (remaining_input[0] != '"' || remaining_input.back () != '"') - return false; - - // Remove the quotes around the value, by advancing one character - value = remaining_input.substr (1); - // And trimming the rightmost character. This is fine since we've already - // checked that both the first and last characters were quotes. - value.resize (value.size () - 1); + key = token->get_str (); - // FIXME: We need to sanitize here and make sure that both key and value - // are proper identifiers + rust_assert (parser.skip_token (IDENTIFIER)); + token = parser.peek_current_token (); - return true; + switch (token->get_id ()) + { + case END_OF_FILE: + // we're done parsing, we had a valid key, return happily + return true; + case EQUAL: + // We have an equal sign: Skip the token and parse an identifier + { + rust_assert (parser.skip_token (EQUAL)); + + auto value_expr = parser.parse_literal_expr (); + // We had an equal sign but no value, error out + if (!value_expr) + return false; + + if (value_expr->get_lit_type () != AST::Literal::LitType::STRING) + return false; + + value = value_expr->get_literal ().as_string (); + return true; + } + default: + return false; + } } - } // namespace Rust #if CHECKING_P @@ -52,23 +62,49 @@ rust_cfg_parser_test (void) std::string key; std::string value; - ASSERT_TRUE (Rust::parse_cfg_option ("key-no-value", key, value)); - ASSERT_EQ (key, "key-no-value"); + auto input = std::string ("key_no_value"); + + ASSERT_TRUE (Rust::parse_cfg_option (input, key, value)); + ASSERT_EQ (key, "key_no_value"); ASSERT_TRUE (value.empty ()); - ASSERT_TRUE (Rust::parse_cfg_option ("k=\"v\"", key, value)); + input = std::string ("k=\"v\""); + + ASSERT_TRUE (Rust::parse_cfg_option (input, key, value)); ASSERT_EQ (key, "k"); ASSERT_EQ (value, "v"); // values should be between double quotes - ASSERT_FALSE (Rust::parse_cfg_option ("k=v", key, value)); + input = std::string ("k=v"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); // No value is an error if there is an equal sign - ASSERT_FALSE (Rust::parse_cfg_option ("k=", key, value)); + input = std::string ("k="); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); // No key is an error - ASSERT_FALSE (Rust::parse_cfg_option ("=", key, value)); - ASSERT_FALSE (Rust::parse_cfg_option ("=value", key, value)); + input = std::string ("="); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + input = std::string ("=value"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + // values that are not string literals are an error + input = std::string ("key=b\"a\""); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + input = std::string ("key='v'"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + input = std::string ("key=155"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + input = std::string ("key=3.14"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); + + // kebab case is not valid for an identifier + input = std::string ("key-no-value"); + ASSERT_FALSE (Rust::parse_cfg_option (input, key, value)); } } // namespace selftest diff --git a/gcc/rust/parse/rust-cfg-parser.h b/gcc/rust/parse/rust-cfg-parser.h index a4b860f..bf4ed4d 100644 --- a/gcc/rust/parse/rust-cfg-parser.h +++ b/gcc/rust/parse/rust-cfg-parser.h @@ -41,8 +41,7 @@ namespace Rust { * @return false if the given input was invalid, true otherwise */ bool -parse_cfg_option (const std::string &input, std::string &key, - std::string &value); +parse_cfg_option (std::string &input, std::string &key, std::string &value); } // namespace Rust #if CHECKING_P |