From e4ff184280ac4942842f3cbd73a263f1f6024a64 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 15 Feb 2020 12:54:04 -0600 Subject: [PATCH] check-structures-sanity: add -lowmem argument to use depth-first search instead of readth-first search add progress indicator if called from the console --- plugins/devel/check-structures-sanity.cpp | 58 ++++++++++++++++------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/plugins/devel/check-structures-sanity.cpp b/plugins/devel/check-structures-sanity.cpp index cb147edb7..dc32c52c3 100644 --- a/plugins/devel/check-structures-sanity.cpp +++ b/plugins/devel/check-structures-sanity.cpp @@ -14,7 +14,7 @@ #include #endif -#include +#include #include #include @@ -37,13 +37,14 @@ DFhackCExport command_result plugin_init(color_ostream &, std::vector mapped; std::set seen_addr; public: - std::queue queue; + std::deque queue; + size_t num_checked; bool enums; bool sizes; + bool lowmem; private: bool ok; @@ -125,6 +128,7 @@ static command_result command(color_ostream & out, std::vector & pa } BOOL_PARAM(enums); BOOL_PARAM(sizes); + BOOL_PARAM(lowmem); #undef BOOL_PARAM if (parameters.size() > 1) @@ -139,7 +143,7 @@ static command_result command(color_ostream & out, std::vector & pa global.ptr = nullptr; global.identity = &df::global::_identity; - checker.queue.push(std::move(global)); + checker.queue.push_back(std::move(global)); } else { @@ -170,7 +174,7 @@ static command_result command(color_ostream & out, std::vector & pa return CR_FAILURE; } - checker.queue.push(std::move(ref)); + checker.queue.push_back(std::move(ref)); } return checker.check() ? CR_OK : CR_FAILURE; @@ -187,16 +191,34 @@ Checker::Checker(color_ostream & out) : bool Checker::check() { seen_addr.clear(); + num_checked = 0; ok = true; while (!queue.empty()) { - ToCheck current = std::move(queue.front()); - queue.pop(); + ToCheck current; + if (lowmem) + { + current = std::move(queue.back()); + queue.pop_back(); + } + else + { + current = std::move(queue.front()); + queue.pop_front(); + } check_dispatch(current); + + num_checked++; + if (out.is_console() && num_checked % 1000 == 0) + { + out << "checked " << num_checked << " fields\r" << std::flush; + } } + out << "checked " << num_checked << " fields" << std::endl; + return ok; } @@ -356,7 +378,7 @@ void Checker::queue_field(ToCheck && item, const struct_field_info *field) UNEXPECTED; break; case struct_field_info::PRIMITIVE: - queue.push(std::move(item)); + queue.push_back(std::move(item)); break; case struct_field_info::STATIC_STRING: // TODO: check static strings? @@ -364,21 +386,21 @@ void Checker::queue_field(ToCheck && item, const struct_field_info *field) case struct_field_info::POINTER: item.temp_identity = std::unique_ptr(new df::pointer_identity(field->type)); item.identity = item.temp_identity.get(); - queue.push(std::move(item)); + queue.push_back(std::move(item)); break; case struct_field_info::STATIC_ARRAY: queue_static_array(item, item.ptr, field->type, field->count, false, field->eid); break; case struct_field_info::SUBSTRUCT: - queue.push(std::move(item)); + queue.push_back(std::move(item)); break; case struct_field_info::CONTAINER: - queue.push(std::move(item)); + queue.push_back(std::move(item)); break; case struct_field_info::STL_VECTOR_PTR: item.temp_identity = std::unique_ptr(new df::stl_ptr_vector_identity(field->type, field->eid)); item.identity = item.temp_identity.get(); - queue.push(std::move(item)); + queue.push_back(std::move(item)); break; case struct_field_info::OBJ_METHOD: case struct_field_info::CLASS_METHOD: @@ -429,7 +451,7 @@ void Checker::queue_static_array(const ToCheck & array, void *base, type_identit item.temp_identity = std::unique_ptr(new pointer_identity(type)); item.identity = item.temp_identity.get(); } - queue.push(std::move(item)); + queue.push_back(std::move(item)); } } @@ -621,7 +643,7 @@ void Checker::check_pointer(const ToCheck & item) return; } - queue.push(ToCheck(item, "", *reinterpret_cast(item.ptr), static_cast(item.identity)->getTarget())); + queue.push_back(ToCheck(item, "", *reinterpret_cast(item.ptr), static_cast(item.identity)->getTarget())); } void Checker::check_bitfield(const ToCheck & item)