Modernize core_strwildcmp() and core_iswildstr() (#10344)

* Modernize core_strwildcmp() and core_iswildstr()

- Changed parameters from 'const char *' to 'std::string_view'
- Removed 16-character limit in core_strwildcmp()
This commit is contained in:
npwoods 2022-10-16 13:59:28 -04:00 committed by GitHub
parent 2aca0b2484
commit 7ce32ff944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 69 deletions

View File

@ -1054,7 +1054,7 @@ image_option &emu_options::image_option(const std::string &device_name)
void emu_options::command_argument_processed()
{
// some command line arguments require that the system name be set, so we can get slot options
if (command_arguments().size() == 1 && !core_iswildstr(command_arguments()[0].c_str()) &&
if (command_arguments().size() == 1 && !core_iswildstr(command_arguments()[0]) &&
(command() == "listdevices" || (command() == "listslots") || (command() == "listmedia") || (command() == "listsoftware")))
{
set_system_name(command_arguments()[0]);

View File

@ -250,7 +250,7 @@ void software_list_device::display_matches(const machine_config &config, const c
// from an intermediate point
//-------------------------------------------------
const software_info *software_list_device::find(const std::string &look_for)
const software_info *software_list_device::find(std::string_view look_for)
{
// empty search returns nothing
if (look_for.empty())
@ -265,8 +265,8 @@ const software_info *software_list_device::find(const std::string &look_for)
info_list.end(),
[&look_for, iswild] (const software_info &info)
{
const char *shortname = info.shortname().c_str();
return (iswild && core_strwildcmp(look_for.c_str(), shortname) == 0)
std::string_view shortname = info.shortname();
return (iswild && core_strwildcmp(look_for, shortname) == 0)
|| util::streqlower(look_for, shortname);
});

View File

@ -121,7 +121,7 @@ public:
const std::list<software_info> &get_info() { if (!m_parsed) parse(); return m_infolist; }
// operations
const software_info *find(const std::string &look_for);
const software_info *find(std::string_view look_for);
void find_approx_matches(std::string_view name, int matches, const software_info **list, const char *interface);
void release();
software_compatibility is_compatible(const software_part &part) const;

View File

@ -300,7 +300,7 @@ int cli_frontend::execute(std::vector<std::string> &args)
// reason for failure, offer some suggestions
if (m_result == EMU_ERR_NO_SUCH_SYSTEM
&& !m_options.attempted_system_name().empty()
&& !core_iswildstr(m_options.attempted_system_name().c_str())
&& !core_iswildstr(m_options.attempted_system_name())
&& mame_options::system(m_options) == nullptr)
{
// get the top 16 approximate matches
@ -911,7 +911,7 @@ void cli_frontend::listmedia(const std::vector<std::string> &args)
//-------------------------------------------------
void cli_frontend::verifyroms(const std::vector<std::string> &args)
{
bool const iswild((1U != args.size()) || core_iswildstr(args[0].c_str()));
bool const iswild((1U != args.size()) || core_iswildstr(args[0]));
std::vector<bool> matched(args.size(), false);
unsigned matchcount = 0;
auto const included = [&args, &matched, &matchcount] (char const *name) -> bool
@ -926,7 +926,7 @@ void cli_frontend::verifyroms(const std::vector<std::string> &args)
auto it = matched.begin();
for (std::string const &pat : args)
{
if (!core_strwildcmp(pat.c_str(), name))
if (!core_strwildcmp(pat, name))
{
++matchcount;
result = true;
@ -1395,7 +1395,7 @@ void cli_frontend::getsoftlist(const std::vector<std::string> &args)
{
for (software_list_device &swlistdev : software_list_device_enumerator(root))
{
if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second)
if (core_strwildcmp(gamename, swlistdev.list_name()) == 0 && list_map.insert(swlistdev.list_name()).second)
{
if (!swlistdev.get_info().empty())
{
@ -1440,7 +1440,7 @@ void cli_frontend::verifysoftlist(const std::vector<std::string> &args)
{
for (software_list_device &swlistdev : software_list_device_enumerator(drivlist.config()->root_device()))
{
if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second)
if (core_strwildcmp(gamename, swlistdev.list_name()) == 0 && list_map.insert(swlistdev.list_name()).second)
{
if (!swlistdev.get_info().empty())
{
@ -1536,7 +1536,7 @@ void cli_frontend::romident(const std::vector<std::string> &args)
template <typename T, typename U> void cli_frontend::apply_action(const std::vector<std::string> &args, T &&drvact, U &&devact)
{
bool const iswild((1U != args.size()) || core_iswildstr(args[0].c_str()));
bool const iswild((1U != args.size()) || core_iswildstr(args[0]));
std::vector<bool> matched(args.size(), false);
auto const included = [&args, &matched] (char const *name) -> bool
{
@ -1547,7 +1547,7 @@ template <typename T, typename U> void cli_frontend::apply_action(const std::vec
auto it = matched.begin();
for (std::string const &pat : args)
{
if (!core_strwildcmp(pat.c_str(), name))
if (!core_strwildcmp(pat, name))
{
result = true;
*it = true;

View File

@ -388,7 +388,7 @@ void info_xml_creator::output(std::ostream &out, const std::vector<std::string>
auto it = matched.begin();
for (const std::string &pat : patterns)
{
if (!core_strwildcmp(pat.c_str(), shortname))
if (!core_strwildcmp(pat, shortname))
{
// this driver matches the pattern - tell the caller
result = true;
@ -397,7 +397,7 @@ void info_xml_creator::output(std::ostream &out, const std::vector<std::string>
if (!*it)
{
*it = true;
if (!core_iswildstr(pat.c_str()))
if (!core_iswildstr(pat))
{
exact_matches++;

View File

@ -63,70 +63,42 @@ int core_strnicmp(const char *s1, const char *s2, size_t n)
/*-------------------------------------------------
core_strwildcmp - case-insensitive wildcard
string compare (up to 16 characters at the
moment)
string compare
-------------------------------------------------*/
int core_strwildcmp(const char *sp1, const char *sp2)
int core_strwildcmp(std::string_view s1, std::string_view s2)
{
char s1[17], s2[17];
size_t i, l1, l2;
char *p;
//assert(strlen(sp1) < 16);
//assert(strlen(sp2) < 16);
if (sp1[0] == 0) strcpy(s1, "*");
else { strncpy(s1, sp1, 16); s1[16] = 0; }
if (sp2[0] == 0) strcpy(s2, "*");
else { strncpy(s2, sp2, 16); s2[16] = 0; }
p = strchr(s1, '*');
if (p)
// slight tweak of core_stricmp() logic
auto s1_iter = s1.begin();
auto s2_iter = s2.begin();
while (true)
{
for (i = p - s1; i < 16; i++) s1[i] = '?';
s1[16] = 0;
}
if ((s1.end() != s1_iter && *s1_iter == '*')
|| (s2.end() != s2_iter && *s2_iter == '*'))
return 0;
p = strchr(s2, '*');
if (p)
{
for (i = p - s2; i < 16; i++) s2[i] = '?';
s2[16] = 0;
}
if (s1.end() == s1_iter)
return (s2.end() == s2_iter) ? 0 : -1;
else if (s2.end() == s2_iter)
return 1;
l1 = strlen(s1);
if (l1 < 16)
{
for (i = l1 + 1; i < 16; i++) s1[i] = ' ';
s1[16] = 0;
const int c1 = tolower(uint8_t(*s1_iter++));
const int c2 = tolower(uint8_t(*s2_iter++));
const int diff = (c1 != '?' && c2 != '?')
? c1 - c2
: 0;
if (diff)
return diff;
}
l2 = strlen(s2);
if (l2 < 16)
{
for (i = l2 + 1; i < 16; i++) s2[i] = ' ';
s2[16] = 0;
}
for (i = 0; i < 16; i++)
{
if (s1[i] == '?' && s2[i] != '?') s1[i] = s2[i];
if (s2[i] == '?' && s1[i] != '?') s2[i] = s1[i];
}
return core_stricmp(s1, s2);
}
bool core_iswildstr(const char *sp)
bool core_iswildstr(std::string_view s)
{
for ( ; sp && *sp; sp++)
auto iter = std::find_if(s.begin(), s.end(), [](char c)
{
if (('?' == *sp) || ('*' == *sp))
return true;
}
return false;
return c == '?' || c == '*';
});
return iter != s.end();
}

View File

@ -49,8 +49,8 @@ int core_strnicmp(const char *s1, const char *s2, size_t n);
/* additional string compare helper (up to 16 characters at the moment) */
int core_strwildcmp(const char *sp1, const char *sp2);
bool core_iswildstr(const char *sp);
int core_strwildcmp(std::string_view s1, std::string_view s2);
bool core_iswildstr(std::string_view s);
/* trim functions */
template <typename TPred>