• 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 #ifndef PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
17 #define PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
18 
19 #include "verification/debug/parser/parser.h"
20 #include "verifier_messages.h"
21 
22 namespace panda::verifier::debug {
23 
24 template <typename Context, typename String>
NameHandler()25 const auto &NameHandler()
26 {
27     using panda::parser::action;
28 
29     static const auto NAME_HANDLER = [](action a, Context &c, auto from, auto to) {
30         if (a == action::PARSED) {
31             auto name = String {from, to};
32             size_t num = static_cast<size_t>(panda::verifier::StringToVerifierMessage(name));
33             c.stack.push_back(std::make_pair(num, num));
34         }
35         return true;
36     };
37 
38     return NAME_HANDLER;
39 }
40 
41 template <typename Context>
NumHandler()42 const auto &NumHandler()
43 {
44     using panda::parser::action;
45 
46     static const auto NUM_HANDLER = [](action a, Context &c, auto from) {
47         if (a == action::PARSED) {
48             size_t num = std::strtol(from, nullptr, 0);
49             c.stack.push_back(std::make_pair(num, num));
50         }
51         return true;
52     };
53 
54     return NUM_HANDLER;
55 }
56 
57 template <typename Context>
RangeHandler()58 const auto &RangeHandler()
59 {
60     using panda::parser::action;
61 
62     static const auto RANGE_HANDLER = [](action a, Context &c) {
63         if (a == action::PARSED) {
64             auto num_end = c.stack.back();
65             c.stack.pop_back();
66             auto num_start = c.stack.back();
67             c.stack.pop_back();
68 
69             c.stack.push_back(std::make_pair(num_start.first, num_end.first));
70         }
71         return true;
72     };
73 
74     return RANGE_HANDLER;
75 }
76 
77 template <typename Context>
ItemHandler()78 const auto &ItemHandler()
79 {
80     using panda::parser::action;
81 
82     static const auto ITEM_HANDLER = [](action a, Context &c) {
83         if (a == action::START) {
84             c.stack.clear();
85         }
86         if (a == action::PARSED) {
87             auto range = c.stack.back();
88             c.stack.pop_back();
89 
90             for (auto i = range.first; i <= range.second; ++i) {
91                 c.nums.insert(i);
92             }
93         }
94         return true;
95     };
96 
97     return ITEM_HANDLER;
98 }
99 
100 template <typename Context, typename String>
MessageSetParser()101 const auto &MessageSetParser()
102 {
103     using panda::parser::action;
104     using panda::parser::charset;
105     using panda::parser::parser;
106 
107     using p = parser<Context, const char, const char *>;
108     using p1 = typename p::p;
109     using p2 = typename p1::p;
110     using p3 = typename p2::p;
111     using p4 = typename p3::p;
112 
113     static const auto WS = p::of_charset(" \t\r\n");
114     static const auto COMMA = p1::of_charset(",");
115     static const auto DEC = p2::of_charset("0123456789");
116 
117     static const auto NAME = p3::of_charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") |=
118         NameHandler<Context, String>();
119 
120     static const auto NUM = DEC |= NumHandler<Context>();
121 
122     static const auto MSG = NUM | NAME;
123 
124     static const auto RANGE_DELIM = ~WS >> p4::of_string("-") >> ~WS;
125 
126     static const auto MSG_RANGE = MSG >> RANGE_DELIM >> MSG |= RangeHandler<Context>();
127 
128     static const auto ITEM = (~WS >> MSG_RANGE >> ~WS | ~WS >> MSG >> ~WS |= ItemHandler<Context>()) >> ~COMMA;
129 
130     // here should be ITEMS = *ITEM, but due to clang-tidy bug, used lambda instead
131     static const auto ITEMS = [](Context &c, const char *&start, const char *end) {
132         while (true) {
133             auto saved = start;
134             if (!ITEM(c, start, end)) {
135                 start = saved;
136                 break;
137             }
138         }
139         return true;
140     };
141 
142     return ITEMS;
143 }
144 
145 }  // namespace panda::verifier::debug
146 
147 #endif  // PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
148