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