From 31eabb5619c2237f539210dc4dab72a860a214cc Mon Sep 17 00:00:00 2001 From: Dieter Baron Date: Wed, 26 Jun 2024 13:42:40 +0200 Subject: [PATCH] Fix mia-games when updating ROM databases. --- src/DatRepository.cc | 6 ++++-- src/MkMameDB.h | 17 ++++++++++------ src/Parser.cc | 41 +++++++++++++++++++++++++++---------- src/Parser.h | 14 ++++++------- src/ParserCm.h | 7 ++++--- src/ParserDir.h | 4 +++- src/ParserRc.h | 2 +- src/ParserXml.h | 2 +- src/mkmamedb.cc | 48 ++++++++++++++++++-------------------------- src/update_romdb.cc | 4 +--- 10 files changed, 81 insertions(+), 64 deletions(-) diff --git a/src/DatRepository.cc b/src/DatRepository.cc index 52795f2b..79f2ea1e 100644 --- a/src/DatRepository.cc +++ b/src/DatRepository.cc @@ -159,7 +159,8 @@ void DatRepository::update_directory(const std::string &directory, const DatDBPt auto output = OutputContextHeader(); auto source = std::make_shared(filepath, zip_archive, entry_name); - auto parser = Parser::create(source, {}, nullptr, &output, {}); + auto parser_options = Parser::Options{{}, false}; + auto parser = Parser::create(source, {}, nullptr, &output, parser_options); if (parser) { if (parser->parse_header()) { auto header = output.get_header(); @@ -176,7 +177,8 @@ void DatRepository::update_directory(const std::string &directory, const DatDBPt auto output = OutputContextHeader(); auto source = std::make_shared(filepath); - auto parser = Parser::create(source, {}, nullptr, &output, {}); + auto parser_options = Parser::Options{{}, false}; + auto parser = Parser::create(source, {}, nullptr, &output, parser_options); if (parser) { if (parser->parse_header() && output.close()) { diff --git a/src/MkMameDB.h b/src/MkMameDB.h index 1591cc72..bb27a1f6 100644 --- a/src/MkMameDB.h +++ b/src/MkMameDB.h @@ -36,6 +36,7 @@ #include "Command.h" #include "OutputContext.h" +#include "Parser.h" class MkMameDB : public Command { public: @@ -46,19 +47,23 @@ class MkMameDB : public Command { bool global_cleanup() override; private: + bool process_file(const std::string &fname, OutputContext *out); + bool process_stdin(OutputContext *out); + + Parser::Options parser_options{{}}; std::string dbname, dbname_real; std::unordered_set exclude; std::vector file_patterns; std::unordered_set skip_files; DatEntry dat; - int flags; - OutputContext::Format fmt; + int flags{0}; + OutputContext::Format fmt{OutputContext::FORMAT_DB}; std::string detector_name; - bool force; - bool runtest; + bool force{false}; + bool runtest{false}; - bool list_available_dats; - bool list_dats; + bool list_available_dats{false}; + bool list_dats{false}; }; #endif // MKMAMEDB_H diff --git a/src/Parser.cc b/src/Parser.cc index bfe32acb..373e4376 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -86,7 +86,7 @@ std::string Parser::state_name(parser_state_t state) { } ParserPtr Parser::create(const ParserSourcePtr& source, const std::unordered_set& exclude, - const DatEntry* dat, OutputContext* output_context, Options options) { + const DatEntry* dat, OutputContext* output_context, const Options& options) { size_t length = 0; for (const auto& pair : format_start) { length = std::max(pair.first.length(), length); @@ -112,19 +112,19 @@ ParserPtr Parser::create(const ParserSourcePtr& source, const std::unordered_set return {}; case CLRMAMEPRO: - return std::shared_ptr(new ParserCm(source, exclude, dat, output_context, std::move(options))); + return std::shared_ptr(new ParserCm(source, exclude, dat, output_context, options)); case ROMCENTER: - return std::shared_ptr(new ParserRc(source, exclude, dat, output_context, std::move(options))); + return std::shared_ptr(new ParserRc(source, exclude, dat, output_context, options)); case XML: - return std::shared_ptr(new ParserXml(source, exclude, dat, output_context, std::move(options))); + return std::shared_ptr(new ParserXml(source, exclude, dat, output_context, options)); } return {}; } bool Parser::parse(const ParserSourcePtr& source, const std::unordered_set& exclude, const DatEntry* dat, - OutputContext* out, Options options) { - auto parser = create(source, exclude, dat, out, std::move(options)); + OutputContext* out, const Options& options) { + auto parser = create(source, exclude, dat, out, options); if (!parser) { output.file_error("unknown dat format"); @@ -516,8 +516,8 @@ bool Parser::prog_version(const std::string& attr) { Parser::Parser(ParserSourcePtr source, std::unordered_set exclude, const DatEntry* dat, - OutputContext* output_context_, Options options) - : options(std::move(options)), + OutputContext* output_context_, const Options& options) + : options(options), lineno(0), header_only(false), ignore(std::move(exclude)), @@ -525,6 +525,7 @@ Parser::Parser(ParserSourcePtr source, std::unordered_set exclude, ps(std::move(source)), flags(0), header_set(false), + error(false), state(PARSE_IN_HEADER) { dat_default.merge(dat, nullptr); for (auto& i : r) { @@ -610,15 +611,15 @@ void Parser::rom_end(filetype_t ft) { } else { std::string name; - size_t n = 1; + size_t i = 1; while (true) { auto path = std::filesystem::path(r[ft]->name); - name = path.stem().string() + " (" + std::to_string(n) + ")" + path.extension().string(); + name = path.stem().string() + " (" + std::to_string(i) + ")" + path.extension().string(); if (std::none_of(g->files[ft].begin(), g->files[ft].end(), [&name](const Rom& rom) { return name == rom.name; })) { break; } - n += 1; + i += 1; } output.line_error(lineno, "warning: two different ROMs with same name '%s', renamed to '%s'", r[ft]->name.c_str(), name.c_str()); @@ -642,3 +643,21 @@ void Parser::rom_end(filetype_t ft) { } } } + +Parser::Options::Options(std::optional dat_name, bool use_configuration) { + if (!use_configuration) { + return; + } + + if (dat_name) { + game_name_suffix = configuration.dat_game_name_suffix(*dat_name); + use_description_as_name = configuration.dat_use_description_as_name(*dat_name); + } + else { + use_description_as_name = configuration.use_description_as_name; + } + if (!configuration.mia_games.empty()) { + auto list = slurp_lines(configuration.mia_games); + mia_games.insert(list.begin(), list.end()); + } +} \ No newline at end of file diff --git a/src/Parser.h b/src/Parser.h index 4fdd6d9f..c0b60055 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -60,21 +60,21 @@ class Parser { public: class Options { public: - Options() : full_archive_names(false), use_description_as_name(false) {} + Options(std::optional dat_name, bool use_configuration = true); - bool full_archive_names; + bool full_archive_names = false; std::string game_name_suffix; - bool use_description_as_name; + bool use_description_as_name = false; std::unordered_set mia_games; }; static ParserPtr create(const ParserSourcePtr& source, const std::unordered_set& exclude, - const DatEntry* dat, OutputContext* output, Options options); + const DatEntry* dat, OutputContext* output, const Options& options); static bool parse(const ParserSourcePtr& source, const std::unordered_set& exclude, - const DatEntry* dat, OutputContext* output, Options options); + const DatEntry* dat, OutputContext* output, const Options& options); - Options options; + const Options& options; /* TODO: move out of context */ size_t lineno; /* current line number in input file */ @@ -112,7 +112,7 @@ class Parser { bool prog_version(const std::string& attr); Parser(ParserSourcePtr source, std::unordered_set exclude, const DatEntry* dat, OutputContext* output_, - Options options); + const Options& options); virtual ~Parser() = default; protected: diff --git a/src/ParserCm.h b/src/ParserCm.h index de7f9143..25580960 100644 --- a/src/ParserCm.h +++ b/src/ParserCm.h @@ -37,14 +37,15 @@ #include "Parser.h" #include +#include class ParserCm : public Parser { public: bool parse() override; ParserCm(ParserSourcePtr source, const std::unordered_set& exclude, const DatEntry* dat, - OutputContext* output, Options options) - : Parser(source, exclude, dat, output, std::move(options)), ignoring_line(false) {} + OutputContext* output, const Options& options) + : Parser(std::move(source), exclude, dat, output, options), ignoring_line(false) {} ~ParserCm() override = default; private: @@ -52,7 +53,7 @@ class ParserCm : public Parser { class Tokenizer { public: - explicit Tokenizer(const std::string& s) : string(s), position(0) {} + explicit Tokenizer(std::string s) : string(std::move(s)), position(0) {} std::string get(); diff --git a/src/ParserDir.h b/src/ParserDir.h index e2de2b26..4b1f140a 100644 --- a/src/ParserDir.h +++ b/src/ParserDir.h @@ -34,12 +34,14 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "Archive.h" #include "Parser.h" class ParserDir : public Parser { public: - ParserDir(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, Options options, const std::string &dname, int hashtypes_, bool runtest_ = false) : Parser(source, exclude, dat, output, std::move(options)), directory_name(dname), hashtypes(hashtypes_), runtest(runtest_) { } + ParserDir(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, const Options& options, std::string dname, int hashtypes_, bool runtest_ = false) : Parser(std::move(source), exclude, dat, output, options), directory_name(std::move(dname)), hashtypes(hashtypes_), runtest(runtest_) { } ~ParserDir() override = default; bool parse() override; diff --git a/src/ParserRc.h b/src/ParserRc.h index 16e43004..41bd9c5a 100644 --- a/src/ParserRc.h +++ b/src/ParserRc.h @@ -40,7 +40,7 @@ class ParserRc : public Parser { public: - ParserRc(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, Options options) : Parser(std::move(source), exclude, dat, output, std::move(options)) {} + ParserRc(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, const Options& options) : Parser(std::move(source), exclude, dat, output, options) {} ~ParserRc() override = default; bool parse() override; diff --git a/src/ParserXml.h b/src/ParserXml.h index e3d62638..a4912f70 100644 --- a/src/ParserXml.h +++ b/src/ParserXml.h @@ -41,7 +41,7 @@ class ParserXml : public Parser { public: - ParserXml(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, Options options) : Parser(std::move(source), exclude, dat, output, std::move(options)) { } + ParserXml(ParserSourcePtr source, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *output, const Options& options) : Parser(std::move(source), exclude, dat, output, options) { } ~ParserXml() override = default; bool parse() override; diff --git a/src/mkmamedb.cc b/src/mkmamedb.cc index a1361caa..e30e488b 100644 --- a/src/mkmamedb.cc +++ b/src/mkmamedb.cc @@ -51,7 +51,6 @@ #include "RomDB.h" #include "globals.h" #include "update_romdb.h" -#include "util.h" std::vector mkmamedb_options = { Commandline::Option("detector", "xml-file", "use header detector"), @@ -78,12 +77,8 @@ std::unordered_set mkmamedb_used_variables = { #define DEFAULT_FILE_PATTERNS "*.dat" -static bool process_file(const std::string &fname, const std::unordered_set &exclude, const DatEntry *dat, const std::vector &file_patterns, const std::unordered_set &files_skip, OutputContext *out, int flags); -static bool process_stdin(const std::unordered_set &exclude, const DatEntry *dat, OutputContext *out); - static int hashtypes; static bool cache_directory; -static Parser::Options parser_options; int main(int argc, char **argv) { auto command = MkMameDB(); @@ -92,8 +87,7 @@ int main(int argc, char **argv) { } -MkMameDB::MkMameDB() : Command("mkmamedb", "[rominfo-file ...]", mkmamedb_options, mkmamedb_used_variables), flags(0), fmt(OutputContext::FORMAT_DB), force(false), runtest(false), list_available_dats(false), list_dats(false) { -} +MkMameDB::MkMameDB() : Command("mkmamedb", "[rominfo-file ...]", mkmamedb_options, mkmamedb_used_variables) {} void MkMameDB::global_setup(const ParsedCommandline &commandline) { @@ -181,25 +175,18 @@ void MkMameDB::global_setup(const ParsedCommandline &commandline) { } bool MkMameDB::execute(const std::vector &arguments) { - parser_options.use_description_as_name = configuration.use_description_as_name; - - if (!configuration.mia_games.empty()) { - auto list = slurp_lines(configuration.mia_games); - parser_options.mia_games.insert(list.begin(), list.end()); - } - if (list_available_dats) { // TODO: store in set, output in cleanup() so every dat is listed only once auto repository = DatRepository(configuration.dat_directories); - for (const auto &dat : repository.list_dats()) { - output.message(dat); + for (const auto & dat_name : repository.list_dats()) { + output.message(dat_name); } return true; } if (list_dats) { - for (const auto &dat : configuration.dats) { - output.message(dat); + for (const auto & dat_name : configuration.dats) { + output.message(dat_name); } return true; } @@ -207,7 +194,6 @@ bool MkMameDB::execute(const std::vector &arguments) { if (runtest) { fmt = OutputContext::FORMAT_MTREE; flags |= OUTPUT_FL_RUNTEST; - parser_options.full_archive_names = true; cache_directory = false; if (dbname.empty()) { // TODO: make this work on Windows @@ -239,6 +225,10 @@ bool MkMameDB::execute(const std::vector &arguments) { dbname = configuration.rom_db; } + parser_options = Parser::Options({}); + if (runtest) { + parser_options.full_archive_names = true; + } auto ok = true; try { @@ -264,7 +254,7 @@ bool MkMameDB::execute(const std::vector &arguments) { for (auto name : arguments) { if (name == "-") { - if (!process_stdin(exclude, &dat, out.get())) { + if (!process_stdin(out.get())) { out->error_occurred(); ok = false; } @@ -278,7 +268,7 @@ bool MkMameDB::execute(const std::vector &arguments) { name.resize(last + 1); } - if (!process_file(name, exclude, &dat, file_patterns, skip_files, out.get(), flags)) { + if (!process_file(name, out.get())) { out->error_occurred(); ok = false; } @@ -304,12 +294,12 @@ bool MkMameDB::global_cleanup() { } -static bool process_file(const std::string &fname, const std::unordered_set &exclude, const DatEntry *dat, const std::vector &file_patterns, const std::unordered_set &files_skip, OutputContext *out, int flags) { +bool MkMameDB::process_file(const std::string &fname, OutputContext *out) { struct zip *za; try { auto mdb = std::make_unique(fname, DBH_READ); - return mdb->export_db(exclude, dat, out); + return mdb->export_db(exclude, &dat, out); } catch (std::exception &e) { /* that's fine */ @@ -322,7 +312,7 @@ static bool process_file(const std::string &fname, const std::unordered_set(zip_get_num_entries(za, 0)); i++) { name = zip_get_name(za, i, 0); - if (files_skip.find(name) != files_skip.end()) { + if (skip_files.find(name) != skip_files.end()) { continue; } auto skip = true; @@ -338,7 +328,7 @@ static bool process_file(const std::string &fname, const std::unordered_set(fname, za, name); - if (!Parser::parse(ps, exclude, dat, out, parser_options)) { + if (!Parser::parse(ps, exclude, &dat, out, parser_options)) { ok = false; } } @@ -363,7 +353,7 @@ static bool process_file(const std::string &fname, const std::unordered_setregister_directory(fname, FILE_ROMSET); } - auto ctx = ParserDir(nullptr, exclude, dat, out, parser_options, fname, hashtypes, flags & OUTPUT_FL_RUNTEST); + auto ctx = ParserDir(nullptr, exclude, &dat, out, parser_options, fname, hashtypes, flags & OUTPUT_FL_RUNTEST); ok = ctx.parse(); } else { @@ -376,7 +366,7 @@ static bool process_file(const std::string &fname, const std::unordered_set(fname); - ok = Parser::parse(ps, exclude, dat, out, parser_options); + ok = Parser::parse(ps, exclude, &dat, out, parser_options); } catch (std::exception &exception) { fprintf(stderr, "%s: can't process %s: %s\n", ProgramName::get().c_str(), fname.c_str(), exception.what()); ok = false; @@ -391,11 +381,11 @@ static bool process_file(const std::string &fname, const std::unordered_set &exclude, const DatEntry *dat, OutputContext *out) { +bool MkMameDB::process_stdin(OutputContext *out) { try { auto ps = std::make_shared(""); - return Parser::parse(ps, exclude, dat, out, parser_options); + return Parser::parse(ps, exclude, &dat, out, parser_options); } catch (std::exception &exception) { fprintf(stderr, "%s: can't process stdin: %s\n", ProgramName::get().c_str(), exception.what()); diff --git a/src/update_romdb.cc b/src/update_romdb.cc index f7cab6b3..6665cb7b 100644 --- a/src/update_romdb.cc +++ b/src/update_romdb.cc @@ -127,9 +127,7 @@ bool update_romdb(bool force) { source = std::make_shared(dat.file_name, zip_archive, dat.entry_name); } - auto options = Parser::Options(); - options.game_name_suffix = configuration.dat_game_name_suffix(dat.name); - options.use_description_as_name = configuration.dat_use_description_as_name(dat.name); + auto options = Parser::Options(dat.name); if (!Parser::parse(source, {}, nullptr, output.get(), options)) { auto message = "can't parse '" + dat.file_name + "'"; if (!dat.entry_name.empty()) {