checking.hh (009e81b16465ea457c0e63fd49fe77f47cc27a5a) checking.hh (bbe31b709a653884e18995a1c97cdafd7392999a)
1/*-
2 * Copyright (c) 2013 David Chisnall
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *

--- 18 unchanged lines hidden (view full) ---

27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#ifndef _CHECKING_HH_
34#define _CHECKING_HH_
1/*-
2 * Copyright (c) 2013 David Chisnall
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *

--- 18 unchanged lines hidden (view full) ---

27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#ifndef _CHECKING_HH_
34#define _CHECKING_HH_
35#include "string.hh"
35#include <string>
36#include "fdt.hh"
37
38namespace dtc
39{
40namespace fdt
41{
42namespace checking
43{

--- 9 unchanged lines hidden (view full) ---

53 /**
54 * The path to the current node being checked. This is used for
55 * printing error messages.
56 */
57 device_tree::node_path path;
58 /**
59 * The name of the checker. This is used for printing error messages
60 * and for enabling / disabling specific checkers from the command
36#include "fdt.hh"
37
38namespace dtc
39{
40namespace fdt
41{
42namespace checking
43{

--- 9 unchanged lines hidden (view full) ---

53 /**
54 * The path to the current node being checked. This is used for
55 * printing error messages.
56 */
57 device_tree::node_path path;
58 /**
59 * The name of the checker. This is used for printing error messages
60 * and for enabling / disabling specific checkers from the command
61 * line.
61 * line.
62 */
63 const char *checker_name;
64 /**
65 * Visits each node, calling the checker functions on properties and
66 * nodes.
67 */
68 bool visit_node(device_tree *tree, const node_ptr &n);
69 protected:

--- 43 unchanged lines hidden (view full) ---

113 * the matching name. To define simple property checkers, just subclass this
114 * and override the check() method.
115 */
116class property_checker : public checker
117{
118 /**
119 * The name of the property that this checker is looking for.
120 */
62 */
63 const char *checker_name;
64 /**
65 * Visits each node, calling the checker functions on properties and
66 * nodes.
67 */
68 bool visit_node(device_tree *tree, const node_ptr &n);
69 protected:

--- 43 unchanged lines hidden (view full) ---

113 * the matching name. To define simple property checkers, just subclass this
114 * and override the check() method.
115 */
116class property_checker : public checker
117{
118 /**
119 * The name of the property that this checker is looking for.
120 */
121 string key;
121 std::string key;
122 public:
123 /**
124 * Implementation of the generic property-checking method that checks
122 public:
123 /**
124 * Implementation of the generic property-checking method that checks
125 * for a property with the name specified in the constructor
125 * for a property with the name specified in the constructor.
126 */
127 virtual bool check_property(device_tree *tree, const node_ptr &n, property_ptr p);
128 /**
129 * Constructor. Takes the name of the checker and the name of the
130 * property to check.
131 */
126 */
127 virtual bool check_property(device_tree *tree, const node_ptr &n, property_ptr p);
128 /**
129 * Constructor. Takes the name of the checker and the name of the
130 * property to check.
131 */
132 property_checker(const char* name, string property_name)
132 property_checker(const char* name, const std::string &property_name)
133 : checker(name), key(property_name) {}
134 /**
135 * The check method, which subclasses should implement.
136 */
137 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
138};
139
140/**
141 * Property type checker.
142 */
143template<property_value::value_type T>
144struct property_type_checker : public property_checker
145{
146 /**
147 * Constructor, takes the name of the checker and the name of the
148 * property to check as arguments.
149 */
133 : checker(name), key(property_name) {}
134 /**
135 * The check method, which subclasses should implement.
136 */
137 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
138};
139
140/**
141 * Property type checker.
142 */
143template<property_value::value_type T>
144struct property_type_checker : public property_checker
145{
146 /**
147 * Constructor, takes the name of the checker and the name of the
148 * property to check as arguments.
149 */
150 property_type_checker(const char* name, string property_name) :
150 property_type_checker(const char* name, const std::string &property_name) :
151 property_checker(name, property_name) {}
152 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
153};
154
155/**
156 * Empty property checker. This checks that the property has no value.
157 */
158template<>
159struct property_type_checker <property_value::EMPTY> : public property_checker
160{
151 property_checker(name, property_name) {}
152 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
153};
154
155/**
156 * Empty property checker. This checks that the property has no value.
157 */
158template<>
159struct property_type_checker <property_value::EMPTY> : public property_checker
160{
161 property_type_checker(const char* name, string property_name) :
161 property_type_checker(const char* name, const std::string &property_name) :
162 property_checker(name, property_name) {}
163 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
164 {
165 return p->begin() == p->end();
166 }
167};
168
169/**
170 * String property checker. This checks that the property has exactly one
171 * value, which is a string.
172 */
173template<>
174struct property_type_checker <property_value::STRING> : public property_checker
175{
162 property_checker(name, property_name) {}
163 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
164 {
165 return p->begin() == p->end();
166 }
167};
168
169/**
170 * String property checker. This checks that the property has exactly one
171 * value, which is a string.
172 */
173template<>
174struct property_type_checker <property_value::STRING> : public property_checker
175{
176 property_type_checker(const char* name, string property_name) :
176 property_type_checker(const char* name, const std::string &property_name) :
177 property_checker(name, property_name) {}
178 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
179 {
180 return (p->begin() + 1 == p->end()) && p->begin()->is_string();
181 }
182};
183/**
184 * String list property checker. This checks that the property has at least
185 * one value, all of which are strings.
186 */
187template<>
188struct property_type_checker <property_value::STRING_LIST> :
189 public property_checker
190{
177 property_checker(name, property_name) {}
178 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
179 {
180 return (p->begin() + 1 == p->end()) && p->begin()->is_string();
181 }
182};
183/**
184 * String list property checker. This checks that the property has at least
185 * one value, all of which are strings.
186 */
187template<>
188struct property_type_checker <property_value::STRING_LIST> :
189 public property_checker
190{
191 property_type_checker(const char* name, string property_name) :
191 property_type_checker(const char* name, const std::string &property_name) :
192 property_checker(name, property_name) {}
193 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
194 {
195 for (property::value_iterator i=p->begin(),e=p->end() ; i!=e ;
196 ++i)
197 {
198 if (!(i->is_string() || i->is_string_list()))
199 {

--- 6 unchanged lines hidden (view full) ---

206
207/**
208 * Phandle property checker. This checks that the property has exactly one
209 * value, which is a valid phandle.
210 */
211template<>
212struct property_type_checker <property_value::PHANDLE> : public property_checker
213{
192 property_checker(name, property_name) {}
193 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
194 {
195 for (property::value_iterator i=p->begin(),e=p->end() ; i!=e ;
196 ++i)
197 {
198 if (!(i->is_string() || i->is_string_list()))
199 {

--- 6 unchanged lines hidden (view full) ---

206
207/**
208 * Phandle property checker. This checks that the property has exactly one
209 * value, which is a valid phandle.
210 */
211template<>
212struct property_type_checker <property_value::PHANDLE> : public property_checker
213{
214 property_type_checker(const char* name, string property_name) :
214 property_type_checker(const char* name, const std::string &property_name) :
215 property_checker(name, property_name) {}
216 virtual bool check(device_tree *tree, const node_ptr &, property_ptr p)
217 {
215 property_checker(name, property_name) {}
216 virtual bool check(device_tree *tree, const node_ptr &, property_ptr p)
217 {
218 return (p->begin() + 1 == p->end()) &&
218 return (p->begin() + 1 == p->end()) &&
219 (tree->referenced_node(*p->begin()) != 0);
220 }
221};
222
223/**
224 * Check that a property has the correct size.
225 */
226struct property_size_checker : public property_checker
227{
228 /**
229 * The expected size of the property.
230 */
231 uint32_t size;
232 public:
233 /**
234 * Constructor, takes the name of the checker, the name of the property
235 * to check, and its expected size as arguments.
236 */
219 (tree->referenced_node(*p->begin()) != 0);
220 }
221};
222
223/**
224 * Check that a property has the correct size.
225 */
226struct property_size_checker : public property_checker
227{
228 /**
229 * The expected size of the property.
230 */
231 uint32_t size;
232 public:
233 /**
234 * Constructor, takes the name of the checker, the name of the property
235 * to check, and its expected size as arguments.
236 */
237 property_size_checker(const char* name, string property_name, uint32_t bytes)
237 property_size_checker(const char* name,
238 const std::string &property_name,
239 uint32_t bytes)
238 : property_checker(name, property_name), size(bytes) {}
239 /**
240 * Check, validates that the property has the correct size.
241 */
242 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p);
243};
244
245
246/**
247 * The check manager is the interface to running the checks. This allows
248 * default checks to be enabled, non-default checks to be enabled, and so on.
249 */
250class check_manager
251{
252 /**
253 * The enabled checkers, indexed by their names. The name is used when
254 * disabling checkers from the command line. When this manager runs,
255 * it will only run the checkers from this map.
256 */
240 : property_checker(name, property_name), size(bytes) {}
241 /**
242 * Check, validates that the property has the correct size.
243 */
244 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p);
245};
246
247
248/**
249 * The check manager is the interface to running the checks. This allows
250 * default checks to be enabled, non-default checks to be enabled, and so on.
251 */
252class check_manager
253{
254 /**
255 * The enabled checkers, indexed by their names. The name is used when
256 * disabling checkers from the command line. When this manager runs,
257 * it will only run the checkers from this map.
258 */
257 std::unordered_map<string, checker*> checkers;
259 std::unordered_map<std::string, checker*> checkers;
258 /**
259 * The disabled checkers. Moving checkers to this list disables them,
260 * but allows them to be easily moved back.
261 */
260 /**
261 * The disabled checkers. Moving checkers to this list disables them,
262 * but allows them to be easily moved back.
263 */
262 std::unordered_map<string, checker*> disabled_checkers;
264 std::unordered_map<std::string, checker*> disabled_checkers;
263 /**
264 * Helper function for adding a property value checker.
265 */
266 template<property_value::value_type T>
265 /**
266 * Helper function for adding a property value checker.
267 */
268 template<property_value::value_type T>
267 void add_property_type_checker(const char *name, string prop);
269 void add_property_type_checker(const char *name, const std::string &prop);
268 /**
269 * Helper function for adding a simple type checker.
270 */
270 /**
271 * Helper function for adding a simple type checker.
272 */
271 void add_property_type_checker(const char *name, string prop);
273 void add_property_type_checker(const char *name, const std::string &prop);
272 /**
273 * Helper function for adding a property value checker.
274 */
275 void add_property_size_checker(const char *name,
274 /**
275 * Helper function for adding a property value checker.
276 */
277 void add_property_size_checker(const char *name,
276 string prop,
278 const std::string &prop,
277 uint32_t size);
278 public:
279 /**
280 * Delete all of the checkers that are part of this checker manager.
281 */
282 ~check_manager();
283 /**
284 * Default constructor, creates check manager containing all of the
285 * default checks.
286 */
287 check_manager();
288 /**
289 * Run all of the checks on the specified tree.
290 */
291 bool run_checks(device_tree *tree, bool keep_going);
292 /**
293 * Disables the named checker.
294 */
279 uint32_t size);
280 public:
281 /**
282 * Delete all of the checkers that are part of this checker manager.
283 */
284 ~check_manager();
285 /**
286 * Default constructor, creates check manager containing all of the
287 * default checks.
288 */
289 check_manager();
290 /**
291 * Run all of the checks on the specified tree.
292 */
293 bool run_checks(device_tree *tree, bool keep_going);
294 /**
295 * Disables the named checker.
296 */
295 bool disable_checker(string name);
297 bool disable_checker(const std::string &name);
296 /**
298 /**
297 * Enables the named checker.
299 * Enables the named checker.
298 */
300 */
299 bool enable_checker(string name);
301 bool enable_checker(const std::string &name);
300};
301
302} // namespace checking
303
304} // namespace fdt
305
306} // namespace dtc
307
308#endif // !_CHECKING_HH_
302};
303
304} // namespace checking
305
306} // namespace fdt
307
308} // namespace dtc
309
310#endif // !_CHECKING_HH_