diff options
Diffstat (limited to 'src/emu/softlist.h')
-rw-r--r-- | src/emu/softlist.h | 187 |
1 files changed, 73 insertions, 114 deletions
diff --git a/src/emu/softlist.h b/src/emu/softlist.h index feab67448d3..634055a4bac 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -19,54 +19,71 @@ #include "corefile.h" #include <list> +#include <set> +#include <string> +#include <string_view> + + +//************************************************************************** +// FORWARD DECLARATIONS +//************************************************************************** + +namespace detail { class softlist_parser; } //************************************************************************** // CONSTANTS //************************************************************************** -#define SOFTWARE_SUPPORTED_YES 0 -#define SOFTWARE_SUPPORTED_PARTIAL 1 -#define SOFTWARE_SUPPORTED_NO 2 +enum class software_support +{ + SUPPORTED, + PARTIALLY_SUPPORTED, + UNSUPPORTED +}; //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// ======================> feature_list_item - // an item in a list of name/value pairs -class feature_list_item +class software_info_item { public: // construction/destruction - feature_list_item(std::string &&name, std::string &&value); - feature_list_item(const std::string &name, const std::string &value); - feature_list_item(feature_list_item const &) = delete; - feature_list_item(feature_list_item &&) = delete; - feature_list_item& operator=(feature_list_item const &) = delete; - feature_list_item& operator=(feature_list_item &&) = delete; + software_info_item(std::string &&name, std::string &&value); + software_info_item(const std::string &name, const std::string &value); + software_info_item(software_info_item const &) = default; + software_info_item(software_info_item &&) = default; + software_info_item& operator=(software_info_item const &) = default; + software_info_item& operator=(software_info_item &&) = default; // getters - feature_list_item *next() const { return m_next; } - const std::string &name() const { return m_name; } - const std::string &value() const { return m_value; } + const std::string &name() const noexcept { return m_name; } + const std::string &value() const noexcept { return m_value; } + + // collection + struct compare + { + using is_transparent = void; + bool operator()(const software_info_item &a, const software_info_item &b) const noexcept { return a.m_name < b.m_name; } + bool operator()(const software_info_item &a, const std::string_view &b) const noexcept { return a.m_name < b; } + bool operator()(const std::string_view &a, const software_info_item &b) const noexcept { return a < b.m_name; } + }; + using set = std::set<software_info_item, compare>; private: // internal state - feature_list_item * m_next; std::string m_name; std::string m_value; }; -// ======================> software_part - // a single part of a software item class software_part { - friend class softlist_parser; + friend class detail::softlist_parser; public: // construction/destruction @@ -77,38 +94,34 @@ public: software_part& operator=(software_part &&) = delete; // getters - software_part *next() const { return m_next; } - software_info &info() const { return m_info; } - const std::string &name() const { return m_name; } - const std::string &interface() const { return m_interface; } - const std::list<feature_list_item> &featurelist() const { return m_featurelist; } - const std::vector<rom_entry> &romdata() const { return m_romdata; } + software_info &info() const noexcept { return m_info; } + const std::string &name() const noexcept { return m_name; } + const std::string &interface() const noexcept { return m_interface; } + const software_info_item::set &features() const noexcept { return m_features; } + const std::vector<rom_entry> &romdata() const noexcept { return m_romdata; } // helpers - bool matches_interface(const char *interface) const; - const char *feature(const std::string &feature_name) const; + bool matches_interface(const char *interface_list) const noexcept; + const char *feature(std::string_view feature_name) const noexcept; private: // internal state - software_part * m_next; - software_info & m_info; - std::string m_name; - std::string m_interface; - std::list<feature_list_item> m_featurelist; - std::vector<rom_entry> m_romdata; + software_info & m_info; + std::string m_name; + std::string m_interface; + software_info_item::set m_features; + std::vector<rom_entry> m_romdata; }; -// ======================> software_info - // a single software item class software_info { - friend class softlist_parser; + friend class detail::softlist_parser; public: // construction/destruction - software_info(std::string &&name, std::string &&parent, const std::string &supported); + software_info(std::string &&name, std::string &&parent, std::string_view supported); software_info(software_info const &) = delete; software_info(software_info &&) = delete; software_info& operator=(software_info const &) = delete; @@ -120,96 +133,42 @@ public: const std::string &parentname() const { return m_parentname; } const std::string &year() const { return m_year; } const std::string &publisher() const { return m_publisher; } - const std::list<feature_list_item> &other_info() const { return m_other_info; } - const std::list<feature_list_item> &shared_info() const { return m_shared_info; } - u32 supported() const { return m_supported; } + const std::list<software_info_item> &info() const { return m_info; } + const software_info_item::set &shared_features() const { return m_shared_features; } + software_support supported() const { return m_supported; } const std::list<software_part> &parts() const { return m_partdata; } // additional operations - const software_part *find_part(const std::string &part_name, const char *interface = nullptr) const; + const software_part *find_part(std::string_view part_name, const char *interface = nullptr) const; bool has_multiple_parts(const char *interface) const; private: // internal state - u32 m_supported; - std::string m_shortname; - std::string m_longname; - std::string m_parentname; - std::string m_year; // Copyright year on title screen, actual release dates can be tracked in external resources - std::string m_publisher; - std::list<feature_list_item> m_other_info; // Here we store info like developer, serial #, etc. which belong to the software entry as a whole - std::list<feature_list_item> m_shared_info; // Here we store info like TV standard compatibility, or add-on requirements, etc. which get inherited - // by each part of this software entry (after loading these are stored in partdata->featurelist) + software_support m_supported; + std::string m_shortname; + std::string m_longname; + std::string m_parentname; + std::string m_year; // Copyright year on title screen, actual release dates can be tracked in external resources + std::string m_publisher; + std::list<software_info_item> m_info; // Here we store info like developer, serial #, etc. which belong to the software entry as a whole + software_info_item::set m_shared_features; // Here we store info like TV standard compatibility, or add-on requirements, etc. which get inherited + // by each part of this software entry (after loading these are stored in partdata->features) std::list<software_part> m_partdata; }; -// ======================> softlist_parser - -class softlist_parser -{ -public: - // construction (== execution) - softlist_parser(util::core_file &file, const std::string &filename, std::string &description, std::list<software_info> &infolist, std::ostringstream &errors); - -private: - enum parse_position - { - POS_ROOT, - POS_MAIN, - POS_SOFT, - POS_PART, - POS_DATA - }; - - // internal parsing helpers - const char *infoname() const { return (m_current_info != nullptr) ? m_current_info->shortname().c_str() : "???"; } - int line() const; - int column() const; - const char *parser_error() const; - - // internal error helpers - template <typename Format, typename... Params> void parse_error(Format &&fmt, Params &&... args); - void unknown_tag(const char *tagname) { parse_error("Unknown tag: %s", tagname); } - void unknown_attribute(const char *attrname) { parse_error("Unknown attribute: %s", attrname); } - - // internal helpers - template <typename T> std::vector<std::string> parse_attributes(const char **attributes, const T &attrlist); - bool parse_name_and_value(const char **attributes, std::string &name, std::string &value); - void add_rom_entry(std::string &&name, std::string &&hashdata, u32 offset, u32 length, u32 flags); - - // expat callbacks - static void start_handler(void *data, const char *tagname, const char **attributes); - static void data_handler(void *data, const char *s, int len); - static void end_handler(void *data, const char *name); - - // internal parsing - void parse_root_start(const char *tagname, const char **attributes); - void parse_main_start(const char *tagname, const char **attributes); - void parse_soft_start(const char *tagname, const char **attributes); - void parse_part_start(const char *tagname, const char **attributes); - void parse_data_start(const char *tagname, const char **attributes); - void parse_soft_end(const char *name); - - // internal parsing state - util::core_file & m_file; - std::string m_filename; - std::list<software_info> & m_infolist; - std::ostringstream & m_errors; - struct XML_ParserStruct * m_parser; - bool m_done; - std::string & m_description; - bool m_data_accum_expected; - std::string m_data_accum; - software_info * m_current_info; - software_part * m_current_part; - parse_position m_pos; -}; - - // ----- Helpers ----- +// parses a software list +void parse_software_list( + util::read_stream &file, + std::string_view filename, + std::string &listname, + std::string &description, + std::list<software_info> &infolist, + std::ostream &errors); + // parses a software identifier (e.g. - 'apple2e:agentusa:flop1') into its constituent parts (returns false if cannot parse) -bool software_name_parse(const std::string &identifier, std::string *list_name = nullptr, std::string *software_name = nullptr, std::string *part_name = nullptr); +bool software_name_parse(std::string_view identifier, std::string *list_name = nullptr, std::string *software_name = nullptr, std::string *part_name = nullptr); #endif // MAME_EMU_SOFTLIST_H |