checking.cc (009e81b16465ea457c0e63fd49fe77f47cc27a5a) checking.cc (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 *

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

28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#include "checking.hh"
34#include <stdio.h>
35
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 *

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

28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#include "checking.hh"
34#include <stdio.h>
35
36using std::string;
36
37
37
38namespace dtc
39{
40namespace fdt
41{
42namespace checking
43{
44
45namespace
46{
38namespace dtc
39{
40namespace fdt
41{
42namespace checking
43{
44
45namespace
46{
47 struct deleted_node_checker : public checker
48 {
49 deleted_node_checker(const char *name) : checker(name) {}
50 virtual bool check_node(device_tree *, const node_ptr &n)
51 {
52 auto &deleted = n->deleted_child_nodes();
53 if (deleted.empty())
54 {
55 return true;
56 }
57 bool plural = deleted.size() > 1;
58 string errmsg("Attempts to delete ");
59 errmsg += plural ? "nodes" : "node";
60 errmsg += " that ";
61 errmsg += plural ? "were" : "was";
62 errmsg += " not added in merge: ";
63 for (auto &d : deleted)
64 {
65 errmsg += d;
66 }
67 report_error(errmsg.c_str());
68 return false;
69 }
70 };
47 /**
48 * Checker that verifies that every node that has children has
49 * #address-cells and #size-cells properties.
50 */
51 struct address_cells_checker : public checker
52 {
53 address_cells_checker(const char *name) : checker(name) {}
54 virtual bool check_node(device_tree *, const node_ptr &n)

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

68 found_address = ((*i)->get_key() == "#address-cells");
69 }
70 if (!found_size)
71 {
72 found_size = ((*i)->get_key() == "#size-cells");
73 }
74 if (found_size && found_address)
75 {
71 /**
72 * Checker that verifies that every node that has children has
73 * #address-cells and #size-cells properties.
74 */
75 struct address_cells_checker : public checker
76 {
77 address_cells_checker(const char *name) : checker(name) {}
78 virtual bool check_node(device_tree *, const node_ptr &n)

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

92 found_address = ((*i)->get_key() == "#address-cells");
93 }
94 if (!found_size)
95 {
96 found_size = ((*i)->get_key() == "#size-cells");
97 }
98 if (found_size && found_address)
99 {
76 break;
100 break;
77 }
78 }
79 if (!found_address)
80 {
101 }
102 }
103 if (!found_address)
104 {
81 report_error("Missing #address-cells property");
105 report_error("Missing #address-cells property");
82 }
83 if (!found_size)
84 {
106 }
107 if (!found_size)
108 {
85 report_error("Missing #size-cells property");
109 report_error("Missing #size-cells property");
86 }
87 return found_address && found_size;
88 }
89 };
90} // anonymous namespace
91
92bool
93checker::visit_node(device_tree *tree, const node_ptr &n)

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

121
122void
123checker::report_error(const char *errmsg)
124{
125 fprintf(stderr, "Error: %s, while checking node: ", errmsg);
126 for (auto &p : path)
127 {
128 putc('/', stderr);
110 }
111 return found_address && found_size;
112 }
113 };
114} // anonymous namespace
115
116bool
117checker::visit_node(device_tree *tree, const node_ptr &n)

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

145
146void
147checker::report_error(const char *errmsg)
148{
149 fprintf(stderr, "Error: %s, while checking node: ", errmsg);
150 for (auto &p : path)
151 {
152 putc('/', stderr);
129 p.first.dump();
153 puts(p.first.c_str());
130 if (!(p.second.empty()))
131 {
132 putc('@', stderr);
154 if (!(p.second.empty()))
155 {
156 putc('@', stderr);
133 p.second.dump();
157 puts(p.second.c_str());
134 }
135 }
136 fprintf(stderr, " [-W%s]\n", checker_name);
137}
138
139bool
140property_checker::check_property(device_tree *tree, const node_ptr &n, property_ptr p)
141{

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

162 }
163 psize += i->byte_data.size();
164 }
165 return psize == size;
166}
167
168template<property_value::value_type T>
169void
158 }
159 }
160 fprintf(stderr, " [-W%s]\n", checker_name);
161}
162
163bool
164property_checker::check_property(device_tree *tree, const node_ptr &n, property_ptr p)
165{

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

186 }
187 psize += i->byte_data.size();
188 }
189 return psize == size;
190}
191
192template<property_value::value_type T>
193void
170check_manager::add_property_type_checker(const char *name, string prop)
194check_manager::add_property_type_checker(const char *name, const string &prop)
171{
172 checkers.insert(std::make_pair(string(name),
173 new property_type_checker<T>(name, prop)));
174}
175
176void
177check_manager::add_property_size_checker(const char *name,
195{
196 checkers.insert(std::make_pair(string(name),
197 new property_type_checker<T>(name, prop)));
198}
199
200void
201check_manager::add_property_size_checker(const char *name,
178 string prop,
202 const string &prop,
179 uint32_t size)
180{
181 checkers.insert(std::make_pair(string(name),
182 new property_size_checker(name, prop, size)));
183}
184
185check_manager::~check_manager()
186{

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

202 // in the man page!
203 add_property_type_checker<property_value::STRING_LIST>(
204 "type-compatible", string("compatible"));
205 add_property_type_checker<property_value::STRING>(
206 "type-model", string("model"));
207 add_property_size_checker("type-phandle", string("phandle"), 4);
208 disabled_checkers.insert(std::make_pair(string("cells-attributes"),
209 new address_cells_checker("cells-attributes")));
203 uint32_t size)
204{
205 checkers.insert(std::make_pair(string(name),
206 new property_size_checker(name, prop, size)));
207}
208
209check_manager::~check_manager()
210{

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

226 // in the man page!
227 add_property_type_checker<property_value::STRING_LIST>(
228 "type-compatible", string("compatible"));
229 add_property_type_checker<property_value::STRING>(
230 "type-model", string("model"));
231 add_property_size_checker("type-phandle", string("phandle"), 4);
232 disabled_checkers.insert(std::make_pair(string("cells-attributes"),
233 new address_cells_checker("cells-attributes")));
234 checkers.insert(std::make_pair(string("deleted-nodes"),
235 new deleted_node_checker("deleted-nodes")));
210}
211
212bool
213check_manager::run_checks(device_tree *tree, bool keep_going)
214{
215 bool success = true;
216 for (auto &i : checkers)
217 {
218 success &= i.second->check_tree(tree);
219 if (!(success || keep_going))
220 {
221 break;
222 }
223 }
224 return success;
225}
226
227bool
236}
237
238bool
239check_manager::run_checks(device_tree *tree, bool keep_going)
240{
241 bool success = true;
242 for (auto &i : checkers)
243 {
244 success &= i.second->check_tree(tree);
245 if (!(success || keep_going))
246 {
247 break;
248 }
249 }
250 return success;
251}
252
253bool
228check_manager::disable_checker(string name)
254check_manager::disable_checker(const string &name)
229{
230 auto checker = checkers.find(name);
231 if (checker != checkers.end())
232 {
233 disabled_checkers.insert(std::make_pair(name,
234 checker->second));
235 checkers.erase(checker);
236 return true;
237 }
238 return false;
239}
240
241bool
255{
256 auto checker = checkers.find(name);
257 if (checker != checkers.end())
258 {
259 disabled_checkers.insert(std::make_pair(name,
260 checker->second));
261 checkers.erase(checker);
262 return true;
263 }
264 return false;
265}
266
267bool
242check_manager::enable_checker(string name)
268check_manager::enable_checker(const string &name)
243{
244 auto checker = disabled_checkers.find(name);
245 if (checker != disabled_checkers.end())
246 {
247 checkers.insert(std::make_pair(name, checker->second));
248 disabled_checkers.erase(checker);
249 return true;
250 }
251 return false;
252}
253
254} // namespace checking
255
256} // namespace fdt
257
258} // namespace dtc
259
269{
270 auto checker = disabled_checkers.find(name);
271 if (checker != disabled_checkers.end())
272 {
273 checkers.insert(std::make_pair(name, checker->second));
274 disabled_checkers.erase(checker);
275 return true;
276 }
277 return false;
278}
279
280} // namespace checking
281
282} // namespace fdt
283
284} // namespace dtc
285