• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "util/tests/environment.h"
17 
18 #include "util/parser/parser.h"
19 
20 #include <cstring>
21 
22 namespace panda::verifier::test {
23 
EnvOptions(const char * env_var_name)24 EnvOptions::EnvOptions(const char *env_var_name)
25 {
26     using panda::parser::action;
27     using panda::parser::charset;
28     using panda::parser::parser;
29 
30     struct Context {
31         std::string name;
32         OptionValue value;
33     };
34 
35     using par = parser<Context, const char, const char *>::next<EnvOptions>;
36 
37     static const auto WS = par::of_charset(" \t\r\n");  // NOLINT(readability-static-accessed-through-instance)
38     static const auto DELIM = par::of_string(";");      // NOLINT(readability-static-accessed-through-instance)
39     static const auto NAME_HANDLER = [](auto a, Context &c, auto s, auto e, [[maybe_unused]] auto end) {
40         if (a == action::PARSED) {
41             c.name = std::string {s, e};
42         }
43         return true;
44     };
45     static const auto NAME =
46         WS.of_charset("abcdefghijklmnopqrstuvwxyz_")  // NOLINT(readability-static-accessed-through-instance)
47         |= NAME_HANDLER;
48     static const auto EQ = NAME.of_string("=");          // NOLINT(readability-static-accessed-through-instance)
49     static const auto BOOL_TRUE = EQ.of_string("true");  // NOLINT(readability-static-accessed-through-instance)
50     static const auto BOOL_FALSE =
51         BOOL_TRUE.of_string("false");  // NOLINT(readability-static-accessed-through-instance)
52     static const auto BOOL_HANDLER = [](auto a, Context &c, auto s, [[maybe_unused]] auto to,
53                                         [[maybe_unused]] auto end) {
54         if (a == action::PARSED) {
55             if (*s == 'f') {
56                 c.value = false;
57             } else {
58                 c.value = true;
59             }
60         }
61         return true;
62     };
63     static const auto BOOL = BOOL_FALSE | BOOL_TRUE |= BOOL_HANDLER;
64     static const auto DEC = BOOL.of_charset("0123456789");  // NOLINT(readability-static-accessed-through-instance)
65     static const auto HEX = DEC.of_string("0x") >> DEC;     // NOLINT(readability-static-accessed-through-instance)
66     static const auto NUM_HANDLER = [](auto a, Context &c, auto s, auto e, [[maybe_unused]] auto end) {
67         if (a == action::PARSED) {
68             c.value = std::stoi(std::string {s, e}, nullptr, 0);
69         }
70         return true;
71     };
72     static const auto NUM = HEX | DEC |= NUM_HANDLER;
73     static const auto QUOTES = HEX.of_string("\"");  // NOLINT(readability-static-accessed-through-instance)
74     static const auto NON_QUOTES =
75         QUOTES.of_charset(!charset("\""));  // NOLINT(readability-static-accessed-through-instance)
76     static const auto STRING_HANDLER = [](auto a, Context &c, auto s, auto e, [[maybe_unused]] auto end) {
77         if (a == action::PARSED) {
78             c.value = std::string {s, e};
79         }
80         return true;
81     };
82     static const auto STRING = QUOTES >> (*NON_QUOTES |= STRING_HANDLER) >> QUOTES;
83 
84     static const auto VALUE = STRING | NUM | BOOL;
85 
86     static const auto KV_PAIR_HANDLER = [this](auto a, Context &c, [[maybe_unused]] auto f, [[maybe_unused]] auto t,
87                                                [[maybe_unused]] auto e) {
88         if (a == action::PARSED) {
89             Options_[c.name] = c.value;
90         }
91         return true;
92     };
93 
94     static const auto KV_PAIR = ~WS >> NAME >> ~WS >> EQ >> ~WS >> VALUE >> ~WS >> DELIM |= KV_PAIR_HANDLER;
95     static const auto OPTIONS = *KV_PAIR;
96 
97     const char *s = std::getenv(env_var_name);
98     if (s == nullptr) {
99         return;
100     }
101 
102     Context c;
103 
104     if (!OPTIONS(c, s, s + strlen(s))) {  // NOLINT
105         // TODO(vdyadov): warning that some options were not parsed
106     }
107 }
108 
operator [](const std::string & name) const109 std::optional<OptionValue> EnvOptions::operator[](const std::string &name) const
110 {
111     auto it = Options_.find(name);
112     if (it != Options_.end()) {
113         return it->second;
114     }
115     return {};
116 }
117 
118 }  // namespace panda::verifier::test
119