1 /**
2 * Copyright (c) 2021-2024 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 ark::verifier::test {
23
24 // CC-OFFNXT(G.FUN.01, huge_method) solid logic
EnvOptions(const char * envVarName)25 EnvOptions::EnvOptions(const char *envVarName)
26 {
27 using ark::parser::Action;
28 using ark::parser::Charset;
29 using ark::parser::Parser;
30
31 struct Context {
32 std::string name;
33 OptionValue value;
34 };
35
36 using Par = Parser<Context, const char, const char *>::Next<EnvOptions>;
37
38 static const auto WS = Par::OfCharset(" \t\r\n"); // NOLINT(readability-static-accessed-through-instance)
39 static const auto DELIM = Par::OfString(";"); // NOLINT(readability-static-accessed-through-instance)
40 static const auto NAME_HANDLER = [](auto a, Context &c, auto s, auto e, [[maybe_unused]] auto end) {
41 if (a == Action::PARSED) {
42 c.name = std::string {s, e};
43 }
44 return true;
45 };
46 static const auto NAME =
47 WS.OfCharset("abcdefghijklmnopqrstuvwxyz_") // NOLINT(readability-static-accessed-through-instance)
48 |= NAME_HANDLER;
49 static const auto EQ = NAME.OfString("="); // NOLINT(readability-static-accessed-through-instance)
50 static const auto BOOL_TRUE = EQ.OfString("true"); // NOLINT(readability-static-accessed-through-instance)
51 static const auto BOOL_FALSE = BOOL_TRUE.OfString("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.OfCharset("0123456789"); // NOLINT(readability-static-accessed-through-instance)
65 static const auto HEX = DEC.OfString("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.OfString("\""); // NOLINT(readability-static-accessed-through-instance)
74 static const auto NON_QUOTES =
75 QUOTES.OfCharset(!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(envVarName);
98 if (s == nullptr) {
99 return;
100 }
101
102 Context c;
103
104 if (!OPTIONS(c, s, s + strlen(s))) { // NOLINT
105 // NOTE(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 ark::verifier::test
119