Merge pull request #1279 from npwoods/yet_more_softlist_cleanups

Yet more softlist cleanups
This commit is contained in:
R. Belmont 2016-08-26 08:18:23 -04:00 committed by GitHub
commit a9025d1f53
4 changed files with 62 additions and 61 deletions

View File

@ -1027,7 +1027,7 @@ image_init_result device_image_interface::load(const std::string &path)
// load_software - loads a softlist item by name
//-------------------------------------------------
image_init_result device_image_interface::load_software(const std::string &softlist_name)
image_init_result device_image_interface::load_software(const std::string &software_identifier)
{
// Prepare to load
unload();
@ -1036,7 +1036,7 @@ image_init_result device_image_interface::load_software(const std::string &softl
// Check if there's a software list defined for this device and use that if we're not creating an image
std::string list_name;
bool softload = load_software_part(softlist_name, m_software_part_ptr, &list_name);
bool softload = load_software_part(software_identifier, m_software_part_ptr, &list_name);
if (!softload)
{
m_is_loading = false;
@ -1088,9 +1088,9 @@ image_init_result device_image_interface::load_software(const std::string &softl
if (!m_init_phase)
{
if (device().machine().phase() == MACHINE_PHASE_RUNNING)
device().popmessage("Image '%s' was successfully loaded.", softlist_name);
device().popmessage("Image '%s' was successfully loaded.", software_identifier);
else
osd_printf_info("Image '%s' was successfully loaded.\n", softlist_name.c_str());
osd_printf_info("Image '%s' was successfully loaded.\n", software_identifier.c_str());
}
}
@ -1256,27 +1256,27 @@ void device_image_interface::update_names(const device_type device_type, const c
// find_software_item
//-------------------------------------------------
const software_part *device_image_interface::find_software_item(const std::string &path, bool restrict_to_interface, software_list_device **dev) const
const software_part *device_image_interface::find_software_item(const std::string &identifier, bool restrict_to_interface, software_list_device **dev) const
{
// split full software name into software list name and short software name
std::string swlist_name, swinfo_name, swpart_name;
if (!software_name_parse(path, &swlist_name, &swinfo_name, &swpart_name))
std::string list_name, software_name, part_name;
if (!software_name_parse(identifier, &list_name, &software_name, &part_name))
return nullptr;
// determine interface
const char *interface = nullptr;
if (restrict_to_interface)
interface = image_interface();
const char *interface = restrict_to_interface
? image_interface()
: nullptr;
// find the software list if explicitly specified
for (software_list_device &swlistdev : software_list_device_iterator(device().mconfig().root_device()))
{
if (swlist_name.compare(swlistdev.list_name())==0 || !(swlist_name.length() > 0))
if (list_name.empty() || (list_name == swlistdev.list_name()))
{
const software_info *info = swlistdev.find(swinfo_name);
const software_info *info = swlistdev.find(software_name);
if (info != nullptr)
{
const software_part *part = info->find_part(swpart_name, interface);
const software_part *part = info->find_part(part_name, interface);
if (part != nullptr)
{
if (dev != nullptr)
@ -1286,13 +1286,13 @@ const software_part *device_image_interface::find_software_item(const std::strin
}
}
if (swinfo_name == swlistdev.list_name())
if (software_name == swlistdev.list_name())
{
// ad hoc handling for the case path = swlist_name:swinfo_name (e.g.
// gameboy:sml) which is not handled properly by software_name_split
// since the function cannot distinguish between this and the case
// path = swinfo_name:swpart_name
const software_info *info = swlistdev.find(swpart_name);
const software_info *info = swlistdev.find(part_name);
if (info != nullptr)
{
const software_part *part = info->find_part("", interface);
@ -1336,14 +1336,14 @@ const software_list_loader &device_image_interface::get_software_list_loader() c
// sw_info and sw_part are also set.
//-------------------------------------------------
bool device_image_interface::load_software_part(const std::string &path, const software_part *&swpart, std::string *list_name)
bool device_image_interface::load_software_part(const std::string &identifier, const software_part *&swpart, std::string *list_name)
{
// if no match has been found, we suggest similar shortnames
software_list_device *swlist;
swpart = find_software_item(path, true, &swlist);
swpart = find_software_item(identifier, true, &swlist);
if (swpart == nullptr)
{
software_list_device::display_matches(device().machine().config(), image_interface(), path);
software_list_device::display_matches(device().machine().config(), image_interface(), identifier);
return false;
}

View File

@ -229,7 +229,7 @@ public:
image_init_result load(const std::string &path);
// loads a softlist item by name
image_init_result load_software(const std::string &softlist_name);
image_init_result load_software(const std::string &software_identifier);
bool open_image_file(emu_options &options);
image_init_result finish_load();
@ -271,8 +271,8 @@ protected:
void image_checkhash();
void update_names(const device_type device_type = nullptr, const char *inst = nullptr, const char *brief = nullptr);
const software_part *find_software_item(const std::string &path, bool restrict_to_interface, software_list_device **device = nullptr) const;
bool load_software_part(const std::string &path, const software_part *&swpart, std::string *list_name = nullptr);
const software_part *find_software_item(const std::string &identifier, bool restrict_to_interface, software_list_device **device = nullptr) const;
bool load_software_part(const std::string &identifier, const software_part *&swpart, std::string *list_name = nullptr);
std::string software_get_default_slot(const char *default_card_slot) const;
void add_format(std::unique_ptr<image_device_format> &&format);

View File

@ -129,22 +129,23 @@ software_info::software_info(std::string &&name, std::string &&parent, const std
// optional interface match
//-------------------------------------------------
const software_part *software_info::find_part(const std::string &partname, const char *interface) const
const software_part *software_info::find_part(const std::string &part_name, const char *interface) const
{
// if neither partname nor interface supplied, then we just return the first entry
if (partname.empty() && interface == nullptr)
return &m_partdata.front();
// look for the part by name and match against the interface if provided
for (const software_part &part : m_partdata)
if (!partname.empty() && (partname == part.name()))
auto iter = std::find_if(
m_partdata.begin(),
m_partdata.end(),
[&](const software_part &part)
{
if (interface == nullptr || part.matches_interface(interface))
return &part;
}
else if (partname.empty() && part.matches_interface(interface))
return &part;
return nullptr;
// try to match the part_name (or all parts if part_name is empty), and then try
// to match the interface (or all interfaces if interface is nullptr)
return (part_name.empty() || part_name == part.name())
&& (interface == nullptr || part.matches_interface(interface));
});
return iter != m_partdata.end()
? &*iter
: nullptr;
}
@ -821,8 +822,8 @@ void softlist_parser::parse_soft_end(const char *tagname)
//-------------------------------------------------
// software_name_parse - helper that splits a
// software_list:software:part string into
// separate software_list, software, and part
// software identifier (software_list:software:part)
// string into separate software_list, software, and part
// strings.
//
// str1:str2:str3 => swlist_name - str1, swname - str2, swpart - str3
@ -835,47 +836,47 @@ void softlist_parser::parse_soft_end(const char *tagname)
// case.
//-------------------------------------------------
bool software_name_parse(const std::string &text, std::string *swlist_name, std::string *swname, std::string *swpart)
bool software_name_parse(const std::string &identifier, std::string *list_name, std::string *software_name, std::string *part_name)
{
// first, sanity check the arguments
if (!std::regex_match(text, s_potenial_softlist_regex))
if (!std::regex_match(identifier, s_potenial_softlist_regex))
return false;
// reset all output parameters (if specified of course)
if (swlist_name != nullptr)
swlist_name->clear();
if (swname != nullptr)
swname->clear();
if (swpart != nullptr)
swpart->clear();
if (list_name != nullptr)
list_name->clear();
if (software_name != nullptr)
software_name->clear();
if (part_name != nullptr)
part_name->clear();
// if no colon, this is the swname by itself
auto split1 = text.find_first_of(':');
auto split1 = identifier.find_first_of(':');
if (split1 == std::string::npos)
{
if (swname != nullptr)
*swname = text;
if (software_name != nullptr)
*software_name = identifier;
return true;
}
// if one colon, it is the swname and swpart alone
auto split2 = text.find_first_of(':', split1 + 1);
auto split2 = identifier.find_first_of(':', split1 + 1);
if (split2 == std::string::npos)
{
if (swname != nullptr)
*swname = text.substr(0, split1);
if (swpart != nullptr)
*swpart = text.substr(split1 + 1);
if (software_name != nullptr)
*software_name = identifier.substr(0, split1);
if (part_name != nullptr)
*part_name = identifier.substr(split1 + 1);
return true;
}
// if two colons present, split into 3 parts
if (swlist_name != nullptr)
*swlist_name = text.substr(0, split1);
if (swname != nullptr)
*swname = text.substr(split1 + 1, split2 - (split1 + 1));
if (swpart != nullptr)
*swpart = text.substr(split2 + 1);
if (list_name != nullptr)
*list_name = identifier.substr(0, split1);
if (software_name != nullptr)
*software_name = identifier.substr(split1 + 1, split2 - (split1 + 1));
if (part_name != nullptr)
*part_name = identifier.substr(split2 + 1);
return true;
}

View File

@ -124,7 +124,7 @@ public:
const std::list<software_part> &parts() const { return m_partdata; }
// additional operations
const software_part *find_part(const std::string &partname, const char *interface = nullptr) const;
const software_part *find_part(const std::string &part_name, const char *interface = nullptr) const;
bool has_multiple_parts(const char *interface) const;
private:
@ -207,8 +207,8 @@ private:
// ----- Helpers -----
// parses a software name (e.g. - 'apple2e:agentusa:flop1') into its consituent parts (returns false if cannot parse)
bool software_name_parse(const std::string &text, std::string *swlist_name = nullptr, std::string *swname = nullptr, std::string *swpart = nullptr);
// parses a software identifier (e.g. - 'apple2e:agentusa:flop1') into its consituent 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);
#endif // __SOFTLIST_H_