mavtables  0.2.1
MAVLink router and firewall.
config_grammar.cpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #include <cstdlib>
19 #include <iomanip>
20 #include <memory>
21 #include <optional>
22 #include <stdexcept>
23 #include <string>
24 
25 #include "config_grammar.hpp"
26 #include "Filesystem.hpp"
27 #include "parse_tree.hpp"
28 
29 
30 /** \defgroup config Configuration functions.
31  *
32  * These functions are used to parse the configuration file.
33  */
34 
35 
36 // custom error messages
37 namespace config
38 {
39 
40 /// @cond INTERNAL
41 
42 #ifdef __clang__
43  #pragma clang diagnostic push
44  #pragma clang diagnostic ignored "-Wglobal-constructors"
45  #pragma clang diagnostic ignored "-Wexit-time-destructors"
46 #endif
47 
48  template<>
49  const std::string error<eos>::error_message =
50  "expected end of statement ';' character";
51 
52  template<>
53  const std::string error<opening_brace>::error_message =
54  "expected opening brace '{'";
55 
56  template<>
57  const std::string error<closing_brace>::error_message =
58  "expected closing brace '}'";
59 
60  template<>
61  const std::string error<unsupported_statement>::error_message =
62  "unsupported statement";
63 
64  template<>
65  const std::string error<default_action_option>::error_message =
66  "expected 'accept' or 'reject'";
67 
68  template<>
69  const std::string error<port>::error_message =
70  "expected a valid port number";
71 
72  template<>
73  const std::string error<address>::error_message =
74  "expected a valid IP address";
75 
76  template<>
77  const std::string error<max_bitrate>::error_message =
78  "expected a valid bitrate";
79 
80  template<>
81  const std::string error<device>::error_message =
82  "expected a valid serial port device name";
83 
84  template<>
85  const std::string error<baudrate>::error_message =
86  "expected a valid baud rate";
87 
88  template<>
89  const std::string error<flow_control>::error_message =
90  "expected 'yes' or 'no'";
91 
92  template<>
93  const std::string error<preload>::error_message =
94  "expected a valid MAVLink address";
95 
96  template<>
97  const std::string error<chain_name>::error_message =
98  "expected a valid chain name";
99 
100  template<>
101  const std::string error<chain>::error_message =
102  "expected a valid chain name";
103 
104  template<>
105  const std::string error<call>::error_message =
106  "expected a valid chain name";
107 
108  template<>
109  const std::string error<goto_>::error_message =
110  "expected a valid chain name";
111 
112  template<>
113  const std::string error<invalid_rule>::error_message =
114  "expected a valid rule";
115 
116  template<>
117  const std::string error<condition_value>::error_message =
118  "condition is empty or invalid";
119 
120  template<>
121  const std::string error<dest>::error_message =
122  "expected a valid MAVLink subnet";
123 
124  template<>
125  const std::string error<source>::error_message =
126  "expected a valid MAVLink subnet";
127 
128  template<>
129  const std::string error<mavaddr>::error_message =
130  "expected a valid MAVLink address";
131 
132  template<>
133  const std::string error<integer>::error_message =
134  "expected an integer";
135 
136  template<>
137  const std::string error<priority>::error_message =
138  "expected priority level";
139 
140  template<>
141  const std::string error<priority_keyword>::error_message =
142  "'with' keyword must be followed by the 'priority' keyword";
143 
144  template<>
145  const std::string error<elements>::error_message =
146  "expected at least one valid statement or block";
147 
148 #ifdef __clang__
149  #pragma clang diagnostic pop
150 #endif
151 
152 /// @endcond
153 
154 
155  /** Print an AST node and all its children.
156  *
157  * \ingroup config
158  * \param os The output stream to print to.
159  * \param node The node to print, also prints it's children.
160  * \param print_location Set to true to print file and line numbers of each
161  * AST node.
162  * \param prefix A string to prefix to each AST element. This is reserved
163  * for internal use.
164  * \returns The output stream.
165  */
166  std::ostream &print_node(
167  std::ostream &os,
168  const config::parse_tree::node &node,
169  bool print_location, const std::string &prefix)
170  {
171  auto new_prefix = prefix;
172 
173  // If not the root node.
174  if (!node.is_root())
175  {
176  // Add 2 spaces to the indent.
177  new_prefix = prefix + "| ";
178  // Remove "config::" prefix from node name.
179  auto node_name = node.name();
180  node_name.erase(0, 8);
181  const auto begin = node_name.find_first_not_of("_");
182  const auto end = node_name.find_last_not_of("_");
183  node_name = node_name.substr(begin, end - begin + 1);
184 
185  // Print location.
186  if (print_location)
187  {
188  os << ":" << std::setfill('0') << std::setw(3)
189  << node.begin().line << ": ";
190  }
191 
192  // Print name.
193  os << prefix << node_name;
194 
195  // Print node content.
196  if (node.has_content())
197  {
198  os << " " << node.content() << "";
199  }
200 
201  os << std::endl;
202  }
203 
204  // Print all child nodes
205  if (!node.children.empty())
206  {
207  for (auto &up : node.children)
208  {
209  print_node(os, *up, print_location, new_prefix);
210  }
211  }
212 
213  return os;
214  }
215 
216 }
217 
218 
219 /** Print AST node to the given output stream.
220  *
221  * This is the same as calling \ref config::print_node with the location option
222  * set to true.
223  *
224  * \ingroup config
225  * \param os The output stream to print to.
226  * \param node The node to print, also prints it's children.
227  * \returns The output stream.
228  */
229 std::ostream &operator<<(
230  std::ostream &os, const config::parse_tree::node &node)
231 {
232  return config::print_node(os, node, true);
233 }
std::ostream & print_node(std::ostream &os, const config::parse_tree::node &node, bool print_location, const std::string &prefix)
std::ostream & operator<<(std::ostream &os, const Action &action)
Definition: Action.cpp:188