xmlfile.cpp: Replace implementation of normalize_string with similar one in infoxml.cpp that returns a new std::string instead of a static buffer

This commit is contained in:
AJR 2023-02-12 19:15:55 -05:00
parent b952a5dde6
commit 0341f8ee4c
4 changed files with 64 additions and 81 deletions

View File

@ -1189,37 +1189,39 @@ const char cli_frontend::s_softlist_xml_dtd[] =
void cli_frontend::output_single_softlist(std::ostream &out, software_list_device &swlistdev)
{
util::stream_format(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), util::xml::normalize_string(swlistdev.description().c_str()));
using util::xml::normalize_string;
util::stream_format(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), normalize_string(swlistdev.description()));
for (const software_info &swinfo : swlistdev.get_info())
{
util::stream_format(out, "\t\t<software name=\"%s\"", util::xml::normalize_string(swinfo.shortname().c_str()));
util::stream_format(out, "\t\t<software name=\"%s\"", normalize_string(swinfo.shortname()));
if (!swinfo.parentname().empty())
util::stream_format(out, " cloneof=\"%s\"", util::xml::normalize_string(swinfo.parentname().c_str()));
util::stream_format(out, " cloneof=\"%s\"", normalize_string(swinfo.parentname()));
if (swinfo.supported() == software_support::PARTIALLY_SUPPORTED)
out << " supported=\"partial\"";
else if (swinfo.supported() == software_support::UNSUPPORTED)
out << " supported=\"no\"";
out << ">\n";
util::stream_format(out, "\t\t\t<description>%s</description>\n", util::xml::normalize_string(swinfo.longname().c_str()));
util::stream_format(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str()));
util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str()));
util::stream_format(out, "\t\t\t<description>%s</description>\n", normalize_string(swinfo.longname()));
util::stream_format(out, "\t\t\t<year>%s</year>\n", normalize_string(swinfo.year()));
util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", normalize_string(swinfo.publisher()));
for (const auto &flist : swinfo.info())
util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), normalize_string(flist.value()));
for (const auto &flist : swinfo.shared_features())
util::stream_format(out, "\t\t\t<sharedfeat name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
util::stream_format(out, "\t\t\t<sharedfeat name=\"%s\" value=\"%s\"/>\n", flist.name(), normalize_string(flist.value()));
for (const software_part &part : swinfo.parts())
{
util::stream_format(out, "\t\t\t<part name=\"%s\"", util::xml::normalize_string(part.name().c_str()));
util::stream_format(out, "\t\t\t<part name=\"%s\"", normalize_string(part.name()));
if (!part.interface().empty())
util::stream_format(out, " interface=\"%s\"", util::xml::normalize_string(part.interface().c_str()));
util::stream_format(out, " interface=\"%s\"", normalize_string(part.interface()));
out << ">\n";
for (const auto &flist : part.features())
util::stream_format(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
util::stream_format(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name(), normalize_string(flist.value()));
// TODO: display ROM region information
for (const rom_entry *region = part.romdata().data(); region; region = rom_next_region(region))
@ -1227,18 +1229,18 @@ void cli_frontend::output_single_softlist(std::ostream &out, software_list_devic
int is_disk = ROMREGION_ISDISKDATA(region);
if (!is_disk)
util::stream_format(out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", util::xml::normalize_string(region->name().c_str()), region->get_length());
util::stream_format(out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", normalize_string(region->name()), region->get_length());
else
util::stream_format(out, "\t\t\t\t<diskarea name=\"%s\">\n", util::xml::normalize_string(region->name().c_str()));
util::stream_format(out, "\t\t\t\t<diskarea name=\"%s\">\n", normalize_string(region->name()));
for (const rom_entry *rom = rom_first_file(region); rom && !ROMENTRY_ISREGIONEND(rom); rom++)
{
if (ROMENTRY_ISFILE(rom))
{
if (!is_disk)
util::stream_format(out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", util::xml::normalize_string(ROM_GETNAME(rom)), rom_file_size(rom));
util::stream_format(out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", normalize_string(ROM_GETNAME(rom)), rom_file_size(rom));
else
util::stream_format(out, "\t\t\t\t\t<disk name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(rom)));
util::stream_format(out, "\t\t\t\t\t<disk name=\"%s\"", normalize_string(ROM_GETNAME(rom)));
// dump checksum information only if there is a known dump
util::hash_collection hashes(rom->hashdata());

View File

@ -104,9 +104,6 @@ private:
typedef std::set<std::add_pointer_t<device_type>, device_type_compare> device_type_set;
std::string normalize_string(const char *string);
std::string normalize_string(std::string_view string);
// internal helper
void output_header(std::ostream &out, bool dtd);
void output_footer(std::ostream &out);
@ -580,39 +577,6 @@ void info_xml_creator::output(std::ostream &out, const std::function<bool(const
namespace
{
//-------------------------------------------------
// normalize_string
//-------------------------------------------------
std::string normalize_string(const char *string)
{
if (string)
return normalize_string(std::string_view(string));
else
return std::string();
}
std::string normalize_string(std::string_view string)
{
std::string result;
result.reserve(string.length());
for (char ch : string)
{
switch (ch)
{
case '\"': result.append("&quot;"); break;
case '&': result.append("&amp;"); break;
case '<': result.append("&lt;"); break;
case '>': result.append("&gt;"); break;
default: result.append(1, ch); break;
}
}
return result;
}
//-------------------------------------------------
// device_filter::filter - apply the filter, if
// present
@ -669,6 +633,7 @@ void output_header(std::ostream &out, bool dtd)
}
// top-level tag
assert(emulator_info::get_build_version() != nullptr);
util::stream_format(out,
"<%s build=\"%s\" debug=\""
#ifdef MAME_DEBUG
@ -678,7 +643,7 @@ void output_header(std::ostream &out, bool dtd)
#endif
"\" mameconfig=\"%d\">\n",
XML_ROOT,
normalize_string(emulator_info::get_build_version()),
util::xml::normalize_string(emulator_info::get_build_version()),
configuration_manager::CONFIG_VERSION);
}
@ -701,6 +666,8 @@ void output_footer(std::ostream &out)
void output_one(std::ostream &out, driver_enumerator &drivlist, const game_driver &driver, device_type_set *devtypes)
{
using util::xml::normalize_string;
machine_config config(driver, drivlist.options());
device_enumerator iter(config.root_device());
@ -821,6 +788,8 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag)
{
using util::xml::normalize_string;
bool has_speaker = false, has_input = false;
// check if the device adds speakers to the system
sound_interface_enumerator snditer(device);
@ -939,7 +908,7 @@ void output_device_refs(std::ostream &out, device_t &root)
{
for (device_t &device : device_enumerator(root))
if (&device != &root)
util::stream_format(out, "\t\t<device_ref name=\"%s\"/>\n", normalize_string(device.shortname()));
util::stream_format(out, "\t\t<device_ref name=\"%s\"/>\n", util::xml::normalize_string(device.shortname()));
}
@ -956,7 +925,7 @@ void output_sampleof(std::ostream &out, device_t &device)
samples_iterator sampiter(samples);
if (sampiter.altbasename() != nullptr)
{
util::stream_format(out, " sampleof=\"%s\"", normalize_string(sampiter.altbasename()));
util::stream_format(out, " sampleof=\"%s\"", util::xml::normalize_string(sampiter.altbasename()));
// must stop here, as there can only be one attribute of the same name
return;
@ -984,8 +953,8 @@ void output_bios(std::ostream &out, device_t const &device)
{
// output extracted name and descriptions'
out << "\t\t<biosset";
util::stream_format(out, " name=\"%s\"", normalize_string(bios.get_name()));
util::stream_format(out, " description=\"%s\"", normalize_string(bios.get_description()));
util::stream_format(out, " name=\"%s\"", util::xml::normalize_string(bios.get_name()));
util::stream_format(out, " description=\"%s\"", util::xml::normalize_string(bios.get_description()));
if (defaultname && !std::strcmp(defaultname, bios.get_name()))
out << " default=\"yes\"";
out << "/>\n";
@ -1056,6 +1025,8 @@ void output_rom(std::ostream &out, machine_config &config, driver_list const *dr
tiny_rom_entry const *region(nullptr);
for (tiny_rom_entry const *rom = device.rom_region(); rom && !ROMENTRY_ISEND(rom); ++rom)
{
using util::xml::normalize_string;
if (ROMENTRY_ISREGION(rom))
region = rom;
else if (ROMENTRY_ISSYSTEM_BIOS(rom))
@ -1150,7 +1121,7 @@ void output_sample(std::ostream &out, device_t &device)
continue;
// output the sample name
util::stream_format(out, "\t\t<sample name=\"%s\"/>\n", normalize_string(samplename));
util::stream_format(out, "\t\t<sample name=\"%s\"/>\n", util::xml::normalize_string(samplename));
}
}
}
@ -1163,6 +1134,8 @@ void output_sample(std::ostream &out, device_t &device)
void output_chips(std::ostream &out, device_t &device, const char *root_tag)
{
using util::xml::normalize_string;
// iterate over executable devices
for (device_execute_interface &exec : execute_interface_enumerator(device))
{
@ -1215,7 +1188,7 @@ void output_display(std::ostream &out, device_t &device, machine_flags::type con
std::string newtag(screendev.tag()), oldtag(":");
newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length());
util::stream_format(out, "\t\t<display tag=\"%s\"", normalize_string(newtag));
util::stream_format(out, "\t\t<display tag=\"%s\"", util::xml::normalize_string(newtag));
switch (screendev.screen_type())
{
@ -1327,7 +1300,7 @@ void output_ioport_condition(std::ostream &out, const ioport_condition &conditio
case ioport_condition::NOTLESSTHAN: rel = "ge"; break;
}
util::stream_format(out, "<condition tag=\"%s\" mask=\"%u\" relation=\"%s\" value=\"%u\"/>\n", normalize_string(condition.tag()), condition.mask(), rel, condition.value());
util::stream_format(out, "<condition tag=\"%s\" mask=\"%u\" relation=\"%s\" value=\"%u\"/>\n", util::xml::normalize_string(condition.tag()), condition.mask(), rel, condition.value());
}
//-------------------------------------------------
@ -1743,6 +1716,8 @@ void output_input(std::ostream &out, const ioport_list &portlist)
for (auto & elem : control_info)
if (elem.type != nullptr)
{
using util::xml::normalize_string;
//printf("type %s - player %d - buttons %d\n", elem.type, elem.player, elem.nbuttons);
if (elem.analog)
{
@ -1836,10 +1811,13 @@ void output_switches(std::ostream &out, const ioport_list &portlist, const char
for (ioport_field const &field : port.second->fields())
if (field.type() == type)
{
using util::xml::normalize_string;
std::string newtag(port.second->tag()), oldtag(":");
newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length());
// output the switch name information
assert(field.specific_name() != nullptr);
std::string const normalized_field_name(normalize_string(field.specific_name()));
std::string const normalized_newtag(normalize_string(newtag));
util::stream_format(out, "\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name, normalized_newtag, field.mask());
@ -1887,7 +1865,7 @@ void output_ports(std::ostream &out, const ioport_list &portlist)
// cycle through ports
for (auto &port : portlist)
{
util::stream_format(out, "\t\t<port tag=\"%s\">\n", normalize_string(port.second->tag()));
util::stream_format(out, "\t\t<port tag=\"%s\">\n", util::xml::normalize_string(port.second->tag()));
for (ioport_field const &field : port.second->fields())
{
if (field.is_analog())
@ -1910,7 +1888,7 @@ void output_adjusters(std::ostream &out, const ioport_list &portlist)
for (ioport_field const &field : port.second->fields())
if (field.type() == IPT_ADJUSTER)
{
util::stream_format(out, "\t\t<adjuster name=\"%s\" default=\"%d\"/>\n", normalize_string(field.specific_name()), field.defvalue());
util::stream_format(out, "\t\t<adjuster name=\"%s\" default=\"%d\"/>\n", util::xml::normalize_string(field.specific_name()), field.defvalue());
}
}
@ -2016,11 +1994,14 @@ void output_images(std::ostream &out, device_t &device, const char *root_tag)
{
if (strcmp(imagedev.device().tag(), device.tag()))
{
using util::xml::normalize_string;
bool loadable = imagedev.user_loadable();
std::string newtag(imagedev.device().tag()), oldtag(":");
newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length());
// print m_output device type
assert(imagedev.image_type_name() != nullptr);
util::stream_format(out, "\t\t<device type=\"%s\"", normalize_string(imagedev.image_type_name()));
// does this device have a tag?
@ -2080,6 +2061,8 @@ void output_slots(std::ostream &out, machine_config &config, device_t &device, c
if (devtypes || listed)
{
using util::xml::normalize_string;
machine_config::token const tok(config.begin_configuration(slot.device()));
std::string newtag(slot.device().tag()), oldtag(":");
newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length());
@ -2128,6 +2111,8 @@ void output_software_lists(std::ostream &out, device_t &root, const char *root_t
{
for (const software_list_device &swlist : software_list_device_enumerator(root))
{
using util::xml::normalize_string;
if (&static_cast<const device_t &>(swlist) == &root)
{
assert(swlist.list_name().empty());
@ -2165,11 +2150,11 @@ void output_ramoptions(std::ostream &out, device_t &root)
{
assert(!havedefault);
havedefault = true;
util::stream_format(out, "\t\t<ramoption name=\"%s\" default=\"yes\">%u</ramoption>\n", normalize_string(option.first), option.second);
util::stream_format(out, "\t\t<ramoption name=\"%s\" default=\"yes\">%u</ramoption>\n", util::xml::normalize_string(option.first), option.second);
}
else
{
util::stream_format(out, "\t\t<ramoption name=\"%s\">%u</ramoption>\n", normalize_string(option.first), option.second);
util::stream_format(out, "\t\t<ramoption name=\"%s\">%u</ramoption>\n", util::xml::normalize_string(option.first), option.second);
}
}
if (!havedefault)

View File

@ -782,29 +782,24 @@ void data_node::set_attribute_float(const char *name, float value)
// to ensure it doesn't contain embedded tags
//-------------------------------------------------
const char *normalize_string(const char *string)
std::string normalize_string(std::string_view string)
{
static char buffer[1024];
char *d = &buffer[0];
std::string result;
result.reserve(string.length());
if (string != nullptr)
for (char ch : string)
{
while (*string)
switch (ch)
{
switch (*string)
{
case '\"' : d += sprintf(d, "&quot;"); break;
case '&' : d += sprintf(d, "&amp;"); break;
case '<' : d += sprintf(d, "&lt;"); break;
case '>' : d += sprintf(d, "&gt;"); break;
default:
*d++ = *string;
}
++string;
case '\"': result.append("&quot;"); break;
case '&': result.append("&amp;"); break;
case '<': result.append("&lt;"); break;
case '>': result.append("&gt;"); break;
default: result.append(1, ch); break;
}
}
*d++ = 0;
return buffer;
return result;
}

View File

@ -16,6 +16,7 @@
#include <list>
#include <string>
#include <string_view>
#include <utility>
@ -245,7 +246,7 @@ private:
/* ----- miscellaneous interfaces ----- */
/* normalize a string into something that can be written to an XML file */
const char *normalize_string(const char *string);
std::string normalize_string(std::string_view string);
} // namespace util::xml