• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "config_parse.h"
17 #include "verification/debug/parser/parser.h"
18 #include "runtime/include/mem/panda_string.h"
19 
20 #include <vector>
21 
22 namespace panda::verifier::config {
23 
24 using panda::parser::action;
25 using panda::parser::parser;
26 using panda::verifier::config::Section;
27 
28 namespace {
29 
30 struct Context {
31     Section current;
32     std::vector<Section> sections;
33 };
34 
35 }  // namespace
36 
37 using p = panda::parser::parser<Context, const char, const char *>;
38 
39 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_FUNCTION_SIZE)
ParseConfig(const char * str,Section & cfg)40 bool ParseConfig(const char *str, Section &cfg)
41 {
42     using panda::parser::charset;
43     using p1 = p::p;
44     using p2 = p1::p;
45     using p3 = p2::p;
46     using p4 = p3::p;
47     using p5 = p4::p;
48     using p6 = p5::p;
49 
50     static const auto WS = p::of_charset(" \t\r\n");
51     static const auto NL = p1::of_charset("\r\n");
52     static const auto SP = p2::of_charset(" \t");
53     static const auto NAME_HANDLER = [](auto a, Context &c, auto from, auto to) {
54         if (a == action::PARSED) {
55             c.current.name = PandaString {from, to};
56         }
57         return true;
58     };
59     static const auto NAME = p3::of_charset("abcdefghijklmnopqrstuvwxyz_") |= NAME_HANDLER;
60 
61     static const auto LCURL = p4::of_string("{");
62     static const auto RCURL = p5::of_string("}");
63 
64     static const auto LINE_HANDLER = [](auto a, Context &c, auto from, auto to) {
65         if (a == action::PARSED) {
66             c.current.items.push_back(PandaString {from, to});
67         }
68         return true;
69     };
70 
71     static const auto LINE = p6::of_charset(!charset {"\r\n"}) |= LINE_HANDLER;
72 
73     static const auto SECTION_END = ~SP >> RCURL >> ~SP >> NL;
74     static const auto SECTION_START = ~SP >> NAME >> ~SP >> LCURL >> ~SP >> NL;
75     static const auto ITEM = (!SECTION_END) & (~SP >> LINE >> NL);
76 
77     static const auto SECTION_HANDLER = [](auto a, Context &c) {
78         if (a == action::START) {
79             c.sections.push_back(c.current);
80             c.current.sections.clear();
81         }
82         if (a == action::CANCEL) {
83             c.current = c.sections.back();
84             c.sections.pop_back();
85         }
86         if (a == action::PARSED) {
87             c.sections.back().sections.push_back(c.current);
88             c.current = c.sections.back();
89             c.sections.pop_back();
90         }
91         return true;
92     };
93 
94     static p::p section_rec;
95 
96     static const auto SECTION = ~WS >> SECTION_START >> ~WS >> *section_rec >> *ITEM >> SECTION_END >> ~WS |=
97         SECTION_HANDLER;  // NOLINT
98 
99     section_rec = SECTION;
100 
101     Context context;
102 
103     context.current.name = "config";
104 
105     if (SECTION(context, str, &str[std::strlen(str)])) {  // NOLINT
106         cfg = context.current;
107         return true;
108     }
109 
110     return false;
111 }
112 
113 }  // namespace panda::verifier::config
114