1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 23:25:00 +00:00

Ensures only _missing_ ROMs are reported.

This commit is contained in:
Thomas Harte
2021-06-05 21:09:35 -04:00
parent b6b3d845a3
commit b0f551c307
3 changed files with 53 additions and 11 deletions

View File

@@ -59,11 +59,50 @@ void Request::Node::add_descriptions(std::vector<Description> &result) const {
return; return;
} }
for(const auto &node: children) { for(const auto &child: children) {
node.add_descriptions(result); child.add_descriptions(result);
} }
} }
Request Request::subtract(const ROM::Map &map) const {
Request copy(*this);
if(copy.node.subtract(map)) {
copy.node.name = Name::None;
copy.node.type = Node::Type::One;
}
return copy;
}
bool Request::Node::subtract(const ROM::Map &map) {
switch(type) {
case Type::One:
return map.find(name) != map.end();
default: {
bool has_all = true;
bool has_any = false;
auto iterator = children.begin();
while(iterator != children.end()) {
const bool did_subtract = iterator->subtract(map);
has_all &= did_subtract;
has_any |= did_subtract;
if(did_subtract) {
iterator = children.erase(iterator);
} else {
++iterator;
}
}
return (type == Type::All && has_all) || (type == Type::Any && has_any);
}
}
}
bool Request::empty() {
return node.type == Node::Type::One && node.name == Name::None;
}
bool Request::Node::validate(Map &map) const { bool Request::Node::validate(Map &map) const {
// Leaf nodes are easy: check that the named ROM is present, // Leaf nodes are easy: check that the named ROM is present,
// unless it's optional, in which case it is always valid. // unless it's optional, in which case it is always valid.

View File

@@ -18,7 +18,7 @@
namespace ROM { namespace ROM {
enum Name { enum Name {
Invalid, None,
// Acorn. // Acorn.
AcornBASICII, AcornBASICII,
@@ -121,7 +121,7 @@ using Map = std::map<ROM::Name, std::vector<uint8_t>>;
struct Description { struct Description {
/// The ROM's enum name. /// The ROM's enum name.
Name name = Name::Invalid; Name name = Name::None;
/// The machine with which this ROM is associated, in a form that is safe for using as /// The machine with which this ROM is associated, in a form that is safe for using as
/// part of a file name. /// part of a file name.
std::string machine_name; std::string machine_name;
@@ -177,13 +177,16 @@ struct Request {
const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item
) const; ) const;
Request subtract(const ROM::Map &map) const;
bool empty();
private: private:
struct Node { struct Node {
enum class Type { enum class Type {
Any, All, One Any, All, One
}; };
Type type = Type::One; Type type = Type::One;
Name name = Name::Invalid; Name name = Name::None;
/// @c true if this ROM is optional for machine startup. Generally indicates something /// @c true if this ROM is optional for machine startup. Generally indicates something
/// that would make emulation more accurate, but not sufficiently so to make it /// that would make emulation more accurate, but not sufficiently so to make it
/// a necessity. /// a necessity.
@@ -197,6 +200,7 @@ struct Request {
const std::function<void(void)> &exit_list, const std::function<void(void)> &exit_list,
const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item
) const; ) const;
bool subtract(const ROM::Map &map);
}; };
Node node; Node node;

View File

@@ -694,12 +694,10 @@ int main(int argc, char *argv[]) {
// /usr/local/share/CLK/[system]; // /usr/local/share/CLK/[system];
// /usr/share/CLK/[system]; or // /usr/share/CLK/[system]; or
// [user-supplied path]/[system] // [user-supplied path]/[system]
ROM::Request requested_roms; ROM::Request missing_roms;
std::vector<std::string> checked_paths; std::vector<std::string> checked_paths;
ROMMachine::ROMFetcher rom_fetcher = [&requested_roms, &arguments, &checked_paths] ROMMachine::ROMFetcher rom_fetcher = [&missing_roms, &arguments, &checked_paths]
(const ROM::Request &roms) -> ROM::Map { (const ROM::Request &roms) -> ROM::Map {
requested_roms = roms;
std::vector<std::string> paths = { std::vector<std::string> paths = {
"/usr/local/share/CLK/", "/usr/local/share/CLK/",
"/usr/share/CLK/" "/usr/share/CLK/"
@@ -756,6 +754,7 @@ int main(int argc, char *argv[]) {
} }
} }
missing_roms = roms.subtract(results);
return results; return results;
}; };
@@ -775,7 +774,7 @@ int main(int argc, char *argv[]) {
default: break; default: break;
case ::Machine::Error::MissingROM: { case ::Machine::Error::MissingROM: {
std::cerr << "Could not find system ROMs; please install to /usr/local/share/CLK/ or /usr/share/CLK/, or provide a --rompath, e.g. --rompath=~/ROMs." << std::endl; std::cerr << "Could not find system ROMs; please install to /usr/local/share/CLK/ or /usr/share/CLK/, or provide a --rompath, e.g. --rompath=~/ROMs." << std::endl;
std::cerr << "Needed "; std::cerr << "Needed — but didn't find — ";
int indentation_level = 0; int indentation_level = 0;
const auto indent = [&indentation_level] { const auto indent = [&indentation_level] {
@@ -786,7 +785,7 @@ int main(int argc, char *argv[]) {
} }
}; };
requested_roms.visit([&indentation_level, indent] (ROM::Request::ListType type) { missing_roms.visit([&indentation_level, indent] (ROM::Request::ListType type) {
indent(); indent();
switch(type) { switch(type) {
default: default: