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:
@@ -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.
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
Reference in New Issue
Block a user