Branch data Line data Source code
1 : : /* This file is part of GCC.
2 : :
3 : : GCC is free software; you can redistribute it and/or modify
4 : : it under the terms of the GNU General Public License as published by
5 : : the Free Software Foundation; either version 3, or (at your option)
6 : : any later version.
7 : :
8 : : GCC is distributed in the hope that it will be useful,
9 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
10 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 : : GNU General Public License for more details.
12 : :
13 : : You should have received a copy of the GNU General Public License
14 : : along with GCC; see the file COPYING3. If not see
15 : : <http://www.gnu.org/licenses/>. */
16 : :
17 : : #include "rust-cfg-parser.h"
18 : : #include "rust-lex.h"
19 : : #include "rust-parse.h"
20 : : #include "rust-session-manager.h"
21 : : #include "selftest.h"
22 : :
23 : : namespace Rust {
24 : : bool
25 : 76 : parse_cfg_option (std::string &input, std::string &key, std::string &value)
26 : : {
27 : 76 : key.clear ();
28 : 76 : value.clear ();
29 : :
30 : 76 : auto lexer = Lexer (input, nullptr);
31 : 76 : auto parser = Parser<Lexer> (lexer);
32 : :
33 : 76 : auto token = parser.peek_current_token ();
34 : 76 : if (token->get_id () != IDENTIFIER)
35 : : {
36 : : return false;
37 : : }
38 : :
39 : 74 : key = token->get_str ();
40 : :
41 : 74 : rust_assert (parser.skip_token (IDENTIFIER));
42 : 74 : token = parser.peek_current_token ();
43 : :
44 : 74 : switch (token->get_id ())
45 : : {
46 : : case END_OF_FILE:
47 : : // we're done parsing, we had a valid key, return happily
48 : : return true;
49 : 9 : case EQUAL:
50 : : // We have an equal sign: Skip the token and parse an identifier
51 : 9 : {
52 : 9 : rust_assert (parser.skip_token (EQUAL));
53 : :
54 : 9 : auto value_expr = parser.parse_literal_expr ();
55 : : // We had an equal sign but no value, error out
56 : 9 : if (!value_expr)
57 : : return false;
58 : :
59 : 7 : if (value_expr->get_lit_type () != AST::Literal::LitType::STRING)
60 : : return false;
61 : :
62 : 3 : value = value_expr->get_literal ().as_string ();
63 : 3 : return true;
64 : 9 : }
65 : : default:
66 : : return false;
67 : : }
68 : 152 : }
69 : : } // namespace Rust
70 : :
71 : : #if CHECKING_P
72 : :
73 : : namespace selftest {
74 : :
75 : : void
76 : 1 : rust_cfg_parser_test (void)
77 : : {
78 : 1 : std::string key;
79 : 1 : std::string value;
80 : :
81 : 1 : auto input = std::string ("key_no_value");
82 : :
83 : 1 : ASSERT_TRUE (Rust::parse_cfg_option (input, key, value));
84 : 1 : ASSERT_EQ (key, "key_no_value");
85 : 1 : ASSERT_TRUE (value.empty ());
86 : :
87 : 1 : input = std::string ("k=\"v\"");
88 : :
89 : 1 : ASSERT_TRUE (Rust::parse_cfg_option (input, key, value));
90 : 1 : ASSERT_EQ (key, "k");
91 : 1 : ASSERT_EQ (value, "v");
92 : :
93 : : // values should be between double quotes
94 : 1 : input = std::string ("k=v");
95 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
96 : :
97 : : // No value is an error if there is an equal sign
98 : 1 : input = std::string ("k=");
99 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
100 : :
101 : : // No key is an error
102 : 1 : input = std::string ("=");
103 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
104 : :
105 : 1 : input = std::string ("=value");
106 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
107 : :
108 : : // values that are not string literals are an error
109 : 1 : input = std::string ("key=b\"a\"");
110 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
111 : :
112 : 1 : input = std::string ("key='v'");
113 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
114 : :
115 : 1 : input = std::string ("key=155");
116 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
117 : :
118 : 1 : input = std::string ("key=3.14");
119 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
120 : :
121 : : // kebab case is not valid for an identifier
122 : 1 : input = std::string ("key-no-value");
123 : 1 : ASSERT_FALSE (Rust::parse_cfg_option (input, key, value));
124 : 1 : }
125 : : } // namespace selftest
126 : :
127 : : #endif // CHECKING_P
|