Exposed several strings as std::string on softlist objects, and fixed a few bugs

This commit is contained in:
Nathan Woods 2016-07-20 09:44:27 -04:00
parent 8e169de1cd
commit c86ab9dbac
11 changed files with 132 additions and 142 deletions

View File

@ -867,8 +867,7 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
while (swinfo != nullptr) while (swinfo != nullptr)
{ {
locationtag.append(swinfo->shortname()).append(breakstr); locationtag.append(swinfo->shortname()).append(breakstr);
const char *parentname = swinfo->parentname(); swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname().c_str()) : nullptr;
swinfo = (parentname != nullptr) ? swlist.find(parentname) : nullptr;
} }
// strip the final '%' // strip the final '%'
locationtag.erase(locationtag.length() - 1, 1); locationtag.erase(locationtag.length() - 1, 1);
@ -1008,7 +1007,7 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
if ( m_software_info_ptr ) if ( m_software_info_ptr )
{ {
// sanitize // sanitize
if (m_software_info_ptr->longname() == nullptr || m_software_info_ptr->publisher() == nullptr || m_software_info_ptr->year() == nullptr) if (m_software_info_ptr->longname().empty() || m_software_info_ptr->publisher().empty() || m_software_info_ptr->year().empty())
fatalerror("Each entry in an XML list must have all of the following fields: description, publisher, year!\n"); fatalerror("Each entry in an XML list must have all of the following fields: description, publisher, year!\n");
// store // store
@ -1352,7 +1351,7 @@ bool device_image_interface::load_software_part(const char *path, const software
// Load the software part // Load the software part
software_list_device &swlist = swpart->info().list(); software_list_device &swlist = swpart->info().list();
bool result = call_softlist_load(swlist, swpart->info().shortname(), swpart->romdata()); bool result = call_softlist_load(swlist, swpart->info().shortname().c_str(), swpart->romdata());
// Tell the world which part we actually loaded // Tell the world which part we actually loaded
std::string full_sw_name = string_format("%s:%s:%s", swlist.list_name(), swpart->info().shortname(), swpart->name()); std::string full_sw_name = string_format("%s:%s:%s", swlist.list_name(), swpart->info().shortname(), swpart->name());

View File

@ -1299,8 +1299,7 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list
while (swinfo != nullptr) while (swinfo != nullptr)
{ {
locationtag.append(swinfo->shortname()).append(breakstr); locationtag.append(swinfo->shortname()).append(breakstr);
const char *parentname = swinfo->parentname(); swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname().c_str()) : nullptr;
swinfo = (parentname != nullptr) ? swlist.find(parentname) : nullptr;
} }
// strip the final '%' // strip the final '%'
locationtag.erase(locationtag.length() - 1, 1); locationtag.erase(locationtag.length() - 1, 1);

View File

@ -44,7 +44,7 @@ private:
// internal parsing helpers // internal parsing helpers
const char *filename() const { return m_list.filename(); } const char *filename() const { return m_list.filename(); }
const char *infoname() const { return (m_current_info != nullptr) ? m_current_info->shortname() : "???"; } const char *infoname() const { return (m_current_info != nullptr) ? m_current_info->shortname().c_str() : "???"; }
int line() const { return XML_GetCurrentLineNumber(m_parser); } int line() const { return XML_GetCurrentLineNumber(m_parser); }
int column() const { return XML_GetCurrentColumnNumber(m_parser); } int column() const { return XML_GetCurrentColumnNumber(m_parser); }
const char *parser_error() const { return XML_ErrorString(XML_GetErrorCode(m_parser)); } const char *parser_error() const { return XML_ErrorString(XML_GetErrorCode(m_parser)); }
@ -55,7 +55,7 @@ private:
void unknown_attribute(const char *attrname) { parse_error("Unknown attribute: %s", attrname); } void unknown_attribute(const char *attrname) { parse_error("Unknown attribute: %s", attrname); }
// internal helpers // internal helpers
void parse_attributes(const char **attributes, int numattrs, const char *attrlist[], const char *outlist[]); std::vector<std::string> parse_attributes(const char **attributes, int numattrs, const char *attrlist[]);
void add_rom_entry(const char *name, const char *hashdata, UINT32 offset, UINT32 length, UINT32 flags); void add_rom_entry(const char *name, const char *hashdata, UINT32 offset, UINT32 length, UINT32 flags);
// expat callbacks // expat callbacks
@ -122,8 +122,8 @@ const char *software_part::feature(const char *feature_name) const
// scan the feature list for an entry matching feature_name and return the value // scan the feature list for an entry matching feature_name and return the value
for (const feature_list_item &feature : m_featurelist) for (const feature_list_item &feature : m_featurelist)
if (strcmp(feature.name(), feature_name) == 0) if (strcmp(feature.name().c_str(), feature_name) == 0)
return feature.value(); return feature.value().c_str();
return nullptr; return nullptr;
} }
@ -241,10 +241,7 @@ software_info::software_info(software_list_device &list, const std::string &name
m_list(list), m_list(list),
m_supported(SOFTWARE_SUPPORTED_YES), m_supported(SOFTWARE_SUPPORTED_YES),
m_shortname(name), m_shortname(name),
m_longname(nullptr), m_parentname(parent)
m_parentname(parent),
m_year(nullptr),
m_publisher(nullptr)
{ {
// handle the supported flag if provided // handle the supported flag if provided
if (supported != nullptr) if (supported != nullptr)
@ -272,7 +269,7 @@ const software_part *software_info::find_part(const char *partname, const char *
// look for the part by name and match against the interface if provided // look for the part by name and match against the interface if provided
for (const software_part &part : m_partdata) for (const software_part &part : m_partdata)
if (partname != nullptr && strcmp(partname, part.name()) == 0) if (partname != nullptr && strcmp(partname, part.name().c_str()) == 0)
{ {
if (interface == nullptr || part.matches_interface(interface)) if (interface == nullptr || part.matches_interface(interface))
return &part; return &part;
@ -318,7 +315,7 @@ software_list_device::software_list_device(const machine_config &mconfig, const
m_filter(nullptr), m_filter(nullptr),
m_parsed(false), m_parsed(false),
m_file(mconfig.options().hash_path(), OPEN_FLAG_READ), m_file(mconfig.options().hash_path(), OPEN_FLAG_READ),
m_description(nullptr) m_description("")
{ {
} }
@ -383,8 +380,8 @@ void software_list_device::find_approx_matches(const char *name, int matches, co
if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this) == SOFTWARE_IS_COMPATIBLE) if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this) == SOFTWARE_IS_COMPATIBLE)
{ {
// pick the best match between driver name and description // pick the best match between driver name and description
int longpenalty = driver_list::penalty_compare(name, swinfo.longname()); int longpenalty = driver_list::penalty_compare(name, swinfo.longname().c_str());
int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname()); int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname().c_str());
int curpenalty = MIN(longpenalty, shortpenalty); int curpenalty = MIN(longpenalty, shortpenalty);
// insert into the sorted table of matches // insert into the sorted table of matches
@ -416,7 +413,7 @@ void software_list_device::release()
{ {
osd_printf_verbose("Resetting %s\n", m_file.filename()); osd_printf_verbose("Resetting %s\n", m_file.filename());
m_parsed = false; m_parsed = false;
m_description = nullptr; m_description.clear();
m_errors.clear(); m_errors.clear();
m_infolist.reset(); m_infolist.reset();
} }
@ -470,7 +467,7 @@ void software_list_device::display_matches(const machine_config &config, const c
// print them out // print them out
for (auto & matche : matches) for (auto & matche : matches)
if (matche != nullptr) if (matche != nullptr)
osd_printf_error("%-18s%s\n", matche->shortname(), matche->longname()); osd_printf_error("%-18s%s\n", matche->shortname().c_str(), matche->longname().c_str());
osd_printf_error("\n"); osd_printf_error("\n");
} }
@ -494,7 +491,7 @@ const software_info *software_list_device::find(const char *look_for, const soft
// find a match (will cause a parse if needed when calling get_info) // find a match (will cause a parse if needed when calling get_info)
for (prev = (prev != nullptr) ? prev->next() : get_info().first(); prev != nullptr; prev = prev->next()) for (prev = (prev != nullptr) ? prev->next() : get_info().first(); prev != nullptr; prev = prev->next())
if ((iswild && core_strwildcmp(look_for, prev->shortname()) == 0) || core_stricmp(look_for, prev->shortname()) == 0) if ((iswild && core_strwildcmp(look_for, prev->shortname().c_str()) == 0) || core_stricmp(look_for, prev->shortname().c_str()) == 0)
break; break;
return prev; return prev;
@ -576,30 +573,30 @@ void software_list_device::internal_validity_check(validity_checker &valid)
// Now check if the xml data is valid: // Now check if the xml data is valid:
// Did we lost any description? // Did we lost any description?
if (swinfo.longname() == nullptr) if (swinfo.longname().empty())
{ {
osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname().c_str());
break; break;
} }
// Did we lost any year? // Did we lost any year?
if (swinfo.year() == nullptr) if (swinfo.year().empty())
{ {
osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname().c_str());
break; break;
} }
// Did we lost any publisher? // Did we lost any publisher?
if (swinfo.publisher() == nullptr) if (swinfo.publisher().empty())
{ {
osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname().c_str());
break; break;
} }
// Did we lost the software parts? // Did we lost the software parts?
if (swinfo.parts().empty()) if (swinfo.parts().empty())
{ {
osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname().c_str());
break; break;
} }
@ -609,57 +606,57 @@ void software_list_device::internal_validity_check(validity_checker &valid)
if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second)
{ {
software_info *match = names.find(swinfo.shortname())->second; software_info *match = names.find(swinfo.shortname())->second;
osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname(), match->shortname()); osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname().c_str(), match->shortname().c_str());
} }
// check for duplicate descriptions // check for duplicate descriptions
std::string longname = std::string(swinfo.longname()); std::string longname = std::string(swinfo.longname());
if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second)
osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname(), swinfo.shortname()); osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname().c_str(), swinfo.shortname().c_str());
bool is_clone = false; bool is_clone = false;
if (swinfo.parentname() != nullptr) if (swinfo.parentname().empty())
{ {
is_clone = true; is_clone = true;
if (strcmp(swinfo.parentname(), swinfo.shortname()) == 0) if (swinfo.parentname() == swinfo.shortname())
{ {
osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname().c_str());
break; break;
} }
// make sure the parent exists // make sure the parent exists
const software_info *swinfo2 = find(swinfo.parentname()); const software_info *swinfo2 = find(swinfo.parentname().c_str());
if (swinfo2 == nullptr) if (swinfo2 == nullptr)
osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname(), swinfo.shortname()); osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname().c_str(), swinfo.shortname().c_str());
else if (swinfo2->parentname() != nullptr) else if (swinfo2->parentname().empty())
osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname()); osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname().c_str());
} }
// make sure the driver name is 8 chars or less // make sure the driver name is 8 chars or less
if ((is_clone && strlen(swinfo.shortname()) > NAME_LEN_CLONE) || (!is_clone && strlen(swinfo.shortname()) > NAME_LEN_PARENT)) if ((is_clone && swinfo.shortname().length() > NAME_LEN_CLONE) || (!is_clone && swinfo.shortname().length() > NAME_LEN_PARENT))
osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname(), osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname().c_str(),
is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT);
// make sure the year is only digits, '?' or '+' // make sure the year is only digits, '?' or '+'
for (const char *s = swinfo.year(); *s != 0; s++) for (const char *s = swinfo.year().c_str(); *s != 0; s++)
if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') if (!isdigit((UINT8)*s) && *s != '?' && *s != '+')
{ {
osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname(), swinfo.year()); osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname().c_str(), swinfo.year().c_str());
break; break;
} }
softlist_map part_names; softlist_map part_names;
for (software_part &part : swinfo.parts()) for (software_part &part : swinfo.parts())
{ {
if (part.interface() == nullptr) if (part.interface().empty())
osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname(), part.name()); osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname().c_str(), part.name().c_str());
if (part.romdata() == nullptr) if (part.romdata() == nullptr)
osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname(), part.name()); osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname().c_str(), part.name().c_str());
if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second)
osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname(), part.name()); osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname().c_str(), part.name().c_str());
for (const rom_entry *data = part.romdata(); data->_name != nullptr; data++) for (const rom_entry *data = part.romdata(); data->_name != nullptr; data++)
if (data->_hashdata != nullptr) if (data->_hashdata != nullptr)
@ -667,7 +664,7 @@ void software_list_device::internal_validity_check(validity_checker &valid)
// make sure the hash is valid // make sure the hash is valid
hash_collection hashes; hash_collection hashes;
if (!hashes.from_internal_string(data->_hashdata)) if (!hashes.from_internal_string(data->_hashdata))
osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo.shortname(), data->_name, data->_hashdata); osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo.shortname().c_str(), data->_name, data->_hashdata);
} }
} }
} }
@ -750,8 +747,10 @@ inline void softlist_parser::parse_error(Format &&fmt, Params &&... args)
// attributes into a list of strings // attributes into a list of strings
//------------------------------------------------- //-------------------------------------------------
void softlist_parser::parse_attributes(const char **attributes, int numattrs, const char *attrlist[], const char *outlist[]) std::vector<std::string> softlist_parser::parse_attributes(const char **attributes, int numattrs, const char *attrlist[])
{ {
std::vector<std::string> outlist(numattrs);
// iterate over attribute/value pairs // iterate over attribute/value pairs
for( ; attributes[0]; attributes += 2) for( ; attributes[0]; attributes += 2)
{ {
@ -770,6 +769,8 @@ void softlist_parser::parse_attributes(const char **attributes, int numattrs, co
if (index == numattrs) if (index == numattrs)
unknown_attribute(attributes[0]); unknown_attribute(attributes[0]);
} }
return outlist;
} }
@ -793,16 +794,10 @@ void softlist_parser::add_rom_entry(const char *name, const char *hashdata, UINT
if (elem._name != nullptr && strcmp(elem._name, name) == 0) if (elem._name != nullptr && strcmp(elem._name, name) == 0)
parse_error("Duplicated dataarea %s in software %s", name, infoname()); parse_error("Duplicated dataarea %s in software %s", name, infoname());
// get our own copy of these strings (ideally rom_entry would use std::string)
m_current_part->m_romdata_strings.emplace_back(name);
name = m_current_part->m_romdata_strings.back().c_str();
m_current_part->m_romdata_strings.emplace_back(hashdata);
hashdata = m_current_part->m_romdata_strings.back().c_str();
// create the new entry and append it // create the new entry and append it
rom_entry entry; rom_entry entry;
entry._name = name; entry._name = m_list.add_string(name);
entry._hashdata = hashdata; entry._hashdata = m_list.add_string(hashdata);
entry._offset = offset; entry._offset = offset;
entry._length = length; entry._length = length;
entry._flags = flags; entry._flags = flags;
@ -918,10 +913,9 @@ void softlist_parser::parse_root_start(const char *tagname, const char **attribu
if (strcmp(tagname, "softwarelist") == 0) if (strcmp(tagname, "softwarelist") == 0)
{ {
static const char *attrnames[] = { "name", "description" }; static const char *attrnames[] = { "name", "description" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[1] != nullptr) if (!attrvalues[1].empty())
m_list.m_description = attrvalues[1]; m_list.m_description = attrvalues[1];
} }
else else
@ -940,11 +934,10 @@ void softlist_parser::parse_main_start(const char *tagname, const char **attribu
if (strcmp(tagname, "software") == 0) if (strcmp(tagname, "software") == 0)
{ {
static const char *attrnames[] = { "name", "cloneof", "supported" }; static const char *attrnames[] = { "name", "cloneof", "supported" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr) if (!attrvalues[0].empty())
m_current_info = &m_list.m_infolist.append(*global_alloc(software_info(m_list, attrvalues[0], attrvalues[1], attrvalues[2]))); m_current_info = &m_list.m_infolist.append(*global_alloc(software_info(m_list, attrvalues[0], attrvalues[1], attrvalues[2].c_str())));
else else
parse_error("No name defined for item"); parse_error("No name defined for item");
} }
@ -983,10 +976,9 @@ void softlist_parser::parse_soft_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "info") == 0) else if (strcmp(tagname, "info") == 0)
{ {
static const char *attrnames[] = { "name", "value" }; static const char *attrnames[] = { "name", "value" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr && attrvalues[1] != nullptr) if (!attrvalues[0].empty() && !attrvalues[1].empty())
m_current_info->m_other_info.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1]))); m_current_info->m_other_info.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1])));
else else
parse_error("Incomplete other_info definition"); parse_error("Incomplete other_info definition");
@ -996,10 +988,9 @@ void softlist_parser::parse_soft_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "sharedfeat") == 0) else if (strcmp(tagname, "sharedfeat") == 0)
{ {
static const char *attrnames[] = { "name", "value" }; static const char *attrnames[] = { "name", "value" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr && attrvalues[1] != nullptr) if (!attrvalues[0].empty() && !attrvalues[1].empty())
m_current_info->m_shared_info.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1]))); m_current_info->m_shared_info.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1])));
else else
parse_error("Incomplete sharedfeat definition"); parse_error("Incomplete sharedfeat definition");
@ -1009,10 +1000,9 @@ void softlist_parser::parse_soft_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "part" ) == 0) else if (strcmp(tagname, "part" ) == 0)
{ {
static const char *attrnames[] = { "name", "interface" }; static const char *attrnames[] = { "name", "interface" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr && attrvalues[1] != nullptr && strcmp(attrvalues[0], "") != 0 && strcmp(attrvalues[1], "") != 0) if (!attrvalues[0].empty() && !attrvalues[1].empty())
m_current_part = &m_current_info->m_partdata.append(*global_alloc(software_part(*m_current_info, attrvalues[0], attrvalues[1]))); m_current_part = &m_current_info->m_partdata.append(*global_alloc(software_part(*m_current_info, attrvalues[0], attrvalues[1])));
else else
parse_error("Incomplete part definition"); parse_error("Incomplete part definition");
@ -1040,14 +1030,13 @@ void softlist_parser::parse_part_start(const char *tagname, const char **attribu
if (strcmp(tagname, "dataarea") == 0) if (strcmp(tagname, "dataarea") == 0)
{ {
static const char *attrnames[] = { "name", "size", "width", "endianness" }; static const char *attrnames[] = { "name", "size", "width", "endianness" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr && attrvalues[1] != nullptr && strcmp(attrvalues[0], "") != 0 && strcmp(attrvalues[1], "") != 0) if (!attrvalues[0].empty() && !attrvalues[1].empty())
{ {
// handle region attributes // handle region attributes
const char *width = attrvalues[2]; const char *width = attrvalues[2].c_str();
const char *endianness = attrvalues[3]; const char *endianness = attrvalues[3].c_str();
UINT32 regionflags = ROMENTRYTYPE_REGION; UINT32 regionflags = ROMENTRYTYPE_REGION;
if (width != nullptr) if (width != nullptr)
@ -1073,7 +1062,7 @@ void softlist_parser::parse_part_start(const char *tagname, const char **attribu
parse_error("Invalid dataarea endianness"); parse_error("Invalid dataarea endianness");
} }
add_rom_entry(attrvalues[0], nullptr, 0, strtol(attrvalues[1], nullptr, 0), regionflags); add_rom_entry(attrvalues[0].c_str(), nullptr, 0, strtol(attrvalues[1].c_str(), nullptr, 0), regionflags);
} }
else else
parse_error("Incomplete dataarea definition"); parse_error("Incomplete dataarea definition");
@ -1083,11 +1072,10 @@ void softlist_parser::parse_part_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "diskarea") == 0) else if (strcmp(tagname, "diskarea") == 0)
{ {
static const char *attrnames[] = { "name" }; static const char *attrnames[] = { "name" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr) if (!attrvalues[0].empty())
add_rom_entry(attrvalues[0], nullptr, 0, 1, ROMENTRYTYPE_REGION | ROMREGION_DATATYPEDISK); add_rom_entry(attrvalues[0].c_str(), nullptr, 0, 1, ROMENTRYTYPE_REGION | ROMREGION_DATATYPEDISK);
else else
parse_error("Incomplete diskarea definition"); parse_error("Incomplete diskarea definition");
} }
@ -1096,10 +1084,9 @@ void softlist_parser::parse_part_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "feature") == 0) else if (strcmp(tagname, "feature") == 0)
{ {
static const char *attrnames[] = { "name", "value" }; static const char *attrnames[] = { "name", "value" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
if (attrvalues[0] != nullptr) if (!attrvalues[0].empty())
m_current_part->m_featurelist.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1]))); m_current_part->m_featurelist.append(*global_alloc(feature_list_item(attrvalues[0], attrvalues[1])));
else else
parse_error("Incomplete feature definition"); parse_error("Incomplete feature definition");
@ -1131,17 +1118,16 @@ void softlist_parser::parse_data_start(const char *tagname, const char **attribu
if (strcmp(tagname, "rom") == 0) if (strcmp(tagname, "rom") == 0)
{ {
static const char *attrnames[] = { "name", "size", "crc", "sha1", "offset", "value", "status", "loadflag" }; static const char *attrnames[] = { "name", "size", "crc", "sha1", "offset", "value", "status", "loadflag" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
const char *name = attrvalues[0]; const char *name = attrvalues[0].c_str();
const char *sizestr = attrvalues[1]; const char *sizestr = attrvalues[1].c_str();
const char *crc = attrvalues[2]; const char *crc = attrvalues[2].c_str();
const char *sha1 = attrvalues[3]; const char *sha1 = attrvalues[3].c_str();
const char *offsetstr = attrvalues[4]; const char *offsetstr = attrvalues[4].c_str();
const char *value = attrvalues[5]; const char *value = attrvalues[5].c_str();
const char *status = attrvalues[6]; const char *status = attrvalues[6].c_str();
const char *loadflag = attrvalues[7]; const char *loadflag = attrvalues[7].c_str();
if (sizestr != nullptr && offsetstr != nullptr) if (sizestr != nullptr && offsetstr != nullptr)
{ {
UINT32 length = strtol(sizestr, nullptr, 0); UINT32 length = strtol(sizestr, nullptr, 0);
@ -1154,7 +1140,10 @@ void softlist_parser::parse_data_start(const char *tagname, const char **attribu
else if (loadflag != nullptr && strcmp(loadflag, "continue") == 0) else if (loadflag != nullptr && strcmp(loadflag, "continue") == 0)
add_rom_entry(nullptr, nullptr, offset, length, ROMENTRYTYPE_CONTINUE | ROM_INHERITFLAGS); add_rom_entry(nullptr, nullptr, offset, length, ROMENTRYTYPE_CONTINUE | ROM_INHERITFLAGS);
else if (loadflag != nullptr && strcmp(loadflag, "fill") == 0) else if (loadflag != nullptr && strcmp(loadflag, "fill") == 0)
add_rom_entry(nullptr, (const char *)(FPTR)(strtol(value, nullptr, 0) & 0xff), offset, length, ROMENTRYTYPE_FILL); {
auto fill_string = string_format("%02X", strtol(value, nullptr, 0) & 0xff);
add_rom_entry(nullptr, fill_string.c_str(), offset, length, ROMENTRYTYPE_FILL);
}
else if (name != nullptr) else if (name != nullptr)
{ {
bool baddump = (status != nullptr && strcmp(status, "baddump") == 0); bool baddump = (status != nullptr && strcmp(status, "baddump") == 0);
@ -1206,13 +1195,12 @@ void softlist_parser::parse_data_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "disk") == 0) else if (strcmp(tagname, "disk") == 0)
{ {
static const char *attrnames[] = { "name", "sha1", "status", "writeable" }; static const char *attrnames[] = { "name", "sha1", "status", "writeable" };
const char *attrvalues[ARRAY_LENGTH(attrnames)] = { nullptr }; auto attrvalues = parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames);
parse_attributes(attributes, ARRAY_LENGTH(attrnames), attrnames, attrvalues);
const char *name = attrvalues[0]; const char *name = attrvalues[0].c_str();
const char *sha1 = attrvalues[1]; const char *sha1 = attrvalues[1].c_str();
const char *status = attrvalues[2]; const char *status = attrvalues[2].c_str();
const char *writeablestr = attrvalues[3]; const char *writeablestr = attrvalues[3].c_str();
if (name != nullptr && sha1 != nullptr) if (name != nullptr && sha1 != nullptr)
{ {
bool baddump = (status != nullptr && strcmp(status, "baddump") == 0); bool baddump = (status != nullptr && strcmp(status, "baddump") == 0);

View File

@ -89,8 +89,8 @@ public:
// getters // getters
feature_list_item *next() const { return m_next; } feature_list_item *next() const { return m_next; }
const char *name() const { return m_name.c_str(); } const std::string &name() const { return m_name; }
const char *value() const { return m_value.c_str(); } const std::string &value() const { return m_value; }
private: private:
// internal state // internal state
@ -115,8 +115,8 @@ public:
// getters // getters
software_part *next() const { return m_next; } software_part *next() const { return m_next; }
software_info &info() const { return m_info; } software_info &info() const { return m_info; }
const char *name() const { return m_name.c_str(); } const std::string &name() const { return m_name; }
const char *interface() const { return m_interface.c_str(); } const std::string &interface() const { return m_interface; }
const simple_list<feature_list_item> &featurelist() const { return m_featurelist; } const simple_list<feature_list_item> &featurelist() const { return m_featurelist; }
const rom_entry *romdata(unsigned int index = 0) const { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; } const rom_entry *romdata(unsigned int index = 0) const { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; }
@ -153,11 +153,11 @@ public:
// getters // getters
software_info *next() const { return m_next; } software_info *next() const { return m_next; }
software_list_device &list() const { return m_list; } software_list_device &list() const { return m_list; }
const char *shortname() const { return m_shortname.c_str(); } const std::string &shortname() const { return m_shortname; }
const char *longname() const { return m_longname.c_str(); } const std::string &longname() const { return m_longname; }
const char *parentname() const { return m_parentname.c_str(); } const std::string &parentname() const { return m_parentname; }
const char *year() const { return m_year.c_str(); } const std::string &year() const { return m_year; }
const char *publisher() const { return m_publisher.c_str(); } const std::string &publisher() const { return m_publisher; }
const simple_list<feature_list_item> &other_info() const { return m_other_info; } const simple_list<feature_list_item> &other_info() const { return m_other_info; }
const simple_list<feature_list_item> &shared_info() const { return m_shared_info; } const simple_list<feature_list_item> &shared_info() const { return m_shared_info; }
UINT32 supported() const { return m_supported; } UINT32 supported() const { return m_supported; }
@ -217,6 +217,9 @@ public:
void find_approx_matches(const char *name, int matches, const software_info **list, const char *interface); void find_approx_matches(const char *name, int matches, const software_info **list, const char *interface);
void release(); void release();
// string pool helpers
const char *add_string(const char *string) { return m_stringpool.add(string); }
// static helpers // static helpers
static software_list_device *find_by_name(const machine_config &mconfig, const char *name); static software_list_device *find_by_name(const machine_config &mconfig, const char *name);
static void display_matches(const machine_config &config, const char *interface, const char *name); static void display_matches(const machine_config &config, const char *interface, const char *name);
@ -241,6 +244,7 @@ protected:
std::string m_description; std::string m_description;
std::string m_errors; std::string m_errors;
simple_list<software_info> m_infolist; simple_list<software_info> m_infolist;
const_string_pool m_stringpool;
}; };

View File

@ -159,7 +159,7 @@ media_auditor::summary media_auditor::audit_software(const char *list_name, cons
std::string combinedpath(util::string_format("%s;%s%s%s", swinfo->shortname(), list_name, PATH_SEPARATOR, swinfo->shortname())); std::string combinedpath(util::string_format("%s;%s%s%s", swinfo->shortname(), list_name, PATH_SEPARATOR, swinfo->shortname()));
std::string locationtag(util::string_format("%s%%%s%%", list_name, swinfo->shortname())); std::string locationtag(util::string_format("%s%%%s%%", list_name, swinfo->shortname()));
if (swinfo->parentname() != nullptr) if (!swinfo->parentname().empty())
{ {
locationtag.append(swinfo->parentname()); locationtag.append(swinfo->parentname());
combinedpath.append(util::string_format(";%s;%s%s%s", swinfo->parentname(), list_name, PATH_SEPARATOR, swinfo->parentname())); combinedpath.append(util::string_format(";%s;%s%s%s", swinfo->parentname(), list_name, PATH_SEPARATOR, swinfo->parentname()));

View File

@ -385,7 +385,7 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length)
// output information about the match // output information about the match
if (found) if (found)
osd_printf_info(" "); osd_printf_info(" ");
osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev.list_name(), swinfo.shortname(), swinfo.longname()); osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev.list_name(), swinfo.shortname().c_str(), swinfo.longname().c_str());
found++; found++;
} }
} }
@ -1390,31 +1390,31 @@ void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlis
fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), xml_normalize_string(swlistdev.description())); fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), xml_normalize_string(swlistdev.description()));
for (software_info &swinfo : swlistdev.get_info()) for (software_info &swinfo : swlistdev.get_info())
{ {
fprintf(out, "\t\t<software name=\"%s\"", swinfo.shortname()); fprintf(out, "\t\t<software name=\"%s\"", swinfo.shortname().c_str());
if (swinfo.parentname() != nullptr) if (!swinfo.parentname().empty())
fprintf(out, " cloneof=\"%s\"", swinfo.parentname()); fprintf(out, " cloneof=\"%s\"", swinfo.parentname().c_str());
if (swinfo.supported() == SOFTWARE_SUPPORTED_PARTIAL) if (swinfo.supported() == SOFTWARE_SUPPORTED_PARTIAL)
fprintf(out, " supported=\"partial\""); fprintf(out, " supported=\"partial\"");
if (swinfo.supported() == SOFTWARE_SUPPORTED_NO) if (swinfo.supported() == SOFTWARE_SUPPORTED_NO)
fprintf(out, " supported=\"no\""); fprintf(out, " supported=\"no\"");
fprintf(out, ">\n" ); fprintf(out, ">\n" );
fprintf(out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo.longname())); fprintf(out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo.longname().c_str()));
fprintf(out, "\t\t\t<year>%s</year>\n", xml_normalize_string(swinfo.year())); fprintf(out, "\t\t\t<year>%s</year>\n", xml_normalize_string(swinfo.year().c_str()));
fprintf(out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string(swinfo.publisher())); fprintf(out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string(swinfo.publisher().c_str()));
for (feature_list_item &flist : swinfo.other_info()) for (feature_list_item &flist : swinfo.other_info())
fprintf( out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), xml_normalize_string( flist.value() ) ); fprintf( out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name().c_str(), xml_normalize_string( flist.value().c_str()) );
for (software_part &part : swinfo.parts()) for (software_part &part : swinfo.parts())
{ {
fprintf(out, "\t\t\t<part name=\"%s\"", part.name()); fprintf(out, "\t\t\t<part name=\"%s\"", part.name().c_str());
if (part.interface() != nullptr) if (!part.interface().empty())
fprintf(out, " interface=\"%s\"", part.interface()); fprintf(out, " interface=\"%s\"", part.interface().c_str());
fprintf(out, ">\n"); fprintf(out, ">\n");
for (feature_list_item &flist : part.featurelist()) for (feature_list_item &flist : part.featurelist())
fprintf(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name(), xml_normalize_string(flist.value())); fprintf(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name().c_str(), xml_normalize_string(flist.value().c_str()));
/* TODO: display rom region information */ /* TODO: display rom region information */
for (const rom_entry *region = part.romdata(); region; region = rom_next_region(region)) for (const rom_entry *region = part.romdata(); region; region = rom_next_region(region))

View File

@ -40,9 +40,9 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
if (image.filename()) if (image.filename())
{ {
m_list = strensure(image.software_list_name()); m_list = strensure(image.software_list_name());
m_short = strensure(image.software_entry()->shortname()); m_short = image.software_entry()->shortname();
m_long = strensure(image.software_entry()->longname()); m_long = image.software_entry()->longname();
m_parent = strensure(image.software_entry()->parentname()); m_parent = image.software_entry()->parentname();
} }
} }

View File

@ -81,7 +81,7 @@ void menu_file_manager::fill_image_line(device_image_interface *img, std::string
if (img->part_entry() != nullptr) if (img->part_entry() != nullptr)
{ {
const software_part *tmp = img->part_entry(); const software_part *tmp = img->part_entry();
if (tmp->name() != nullptr) if (!tmp->name().empty())
{ {
filename.append(" ("); filename.append(" (");
filename.append(tmp->name()); filename.append(tmp->name());

View File

@ -192,7 +192,7 @@ void menu_control_device_image::handle()
case START_OTHER_PART: case START_OTHER_PART:
m_submenu_result.swparts = menu_software_parts::result::INVALID; m_submenu_result.swparts = menu_software_parts::result::INVALID;
menu::stack_push<menu_software_parts>(ui(), container(), m_swi, m_swp->interface(), &m_swp, true, m_submenu_result.swparts); menu::stack_push<menu_software_parts>(ui(), container(), m_swi, m_swp->interface().c_str(), &m_swp, true, m_submenu_result.swparts);
m_state = SELECT_OTHER_PART; m_state = SELECT_OTHER_PART;
break; break;

View File

@ -194,20 +194,20 @@ void favorite_manager::add_favorite_game()
auto swinfo = image.software_entry(); auto swinfo = image.software_entry();
auto part = image.part_entry(); auto part = image.part_entry();
ui_software_info tmpmatches; ui_software_info tmpmatches;
tmpmatches.shortname = strensure(swinfo->shortname()); tmpmatches.shortname = swinfo->shortname();
tmpmatches.longname = strensure(image.longname()); tmpmatches.longname = strensure(image.longname());
tmpmatches.parentname = strensure(swinfo->parentname()); tmpmatches.parentname = swinfo->parentname();
tmpmatches.year = strensure(image.year()); tmpmatches.year = strensure(image.year());
tmpmatches.publisher = strensure(image.manufacturer()); tmpmatches.publisher = strensure(image.manufacturer());
tmpmatches.supported = image.supported(); tmpmatches.supported = image.supported();
tmpmatches.part = strensure(part->name()); tmpmatches.part = part->name();
tmpmatches.driver = &machine().system(); tmpmatches.driver = &machine().system();
tmpmatches.listname = strensure(image.software_list_name()); tmpmatches.listname = strensure(image.software_list_name());
tmpmatches.interface = strensure(part->interface()); tmpmatches.interface = part->interface();
tmpmatches.instance = strensure(image.instance_name()); tmpmatches.instance = strensure(image.instance_name());
tmpmatches.startempty = 0; tmpmatches.startempty = 0;
tmpmatches.parentlongname.clear(); tmpmatches.parentlongname.clear();
if (swinfo->parentname()) if (!swinfo->parentname().empty())
{ {
auto swlist = software_list_device::find_by_name(machine().config(), image.software_list_name()); auto swlist = software_list_device::find_by_name(machine().config(), image.software_list_name());
for (software_info &c_swinfo : swlist->get_info()) for (software_info &c_swinfo : swlist->get_info())
@ -223,7 +223,7 @@ void favorite_manager::add_favorite_game()
tmpmatches.usage.clear(); tmpmatches.usage.clear();
for (feature_list_item &flist : swinfo->other_info()) for (feature_list_item &flist : swinfo->other_info())
if (!strcmp(flist.name(), "usage")) if (!strcmp(flist.name().c_str(), "usage"))
tmpmatches.usage = flist.value(); tmpmatches.usage = flist.value();
tmpmatches.devicetype = strensure(image.image_type_name()); tmpmatches.devicetype = strensure(image.image_type_name());

View File

@ -552,23 +552,23 @@ void menu_select_software::build_software_list()
if (instance_name == nullptr || type_name == nullptr) if (instance_name == nullptr || type_name == nullptr)
continue; continue;
tmpmatches.shortname = strensure(swinfo.shortname()); tmpmatches.shortname = swinfo.shortname();
tmpmatches.longname = strensure(swinfo.longname()); tmpmatches.longname = swinfo.longname();
tmpmatches.parentname = strensure(swinfo.parentname()); tmpmatches.parentname = swinfo.parentname();
tmpmatches.year = strensure(swinfo.year()); tmpmatches.year = swinfo.year();
tmpmatches.publisher = strensure(swinfo.publisher()); tmpmatches.publisher = swinfo.publisher();
tmpmatches.supported = swinfo.supported(); tmpmatches.supported = swinfo.supported();
tmpmatches.part = strensure(part->name()); tmpmatches.part = part->name();
tmpmatches.driver = m_driver; tmpmatches.driver = m_driver;
tmpmatches.listname = strensure(swlist.list_name()); tmpmatches.listname = strensure(swlist.list_name());
tmpmatches.interface = strensure(part->interface()); tmpmatches.interface = part->interface();
tmpmatches.startempty = 0; tmpmatches.startempty = 0;
tmpmatches.parentlongname.clear(); tmpmatches.parentlongname.clear();
tmpmatches.usage.clear(); tmpmatches.usage.clear();
tmpmatches.available = false; tmpmatches.available = false;
for (feature_list_item &flist : swinfo.other_info()) for (feature_list_item &flist : swinfo.other_info())
if (!strcmp(flist.name(), "usage")) if (!strcmp(flist.name().c_str(), "usage"))
tmpmatches.usage = flist.value(); tmpmatches.usage = flist.value();
m_swinfo.push_back(tmpmatches); m_swinfo.push_back(tmpmatches);