int fuzzy_substring(std::string s_needle, std::string s_haystack) { if (s_needle.empty()) return s_haystack.size(); if (s_haystack.empty()) return s_needle.size(); strmakelower(s_needle); strmakelower(s_haystack); if (s_needle == s_haystack) return 0; if (s_haystack.find(s_needle) != std::string::npos) return 0; auto *row1 = global_alloc_array_clear<int>(s_haystack.size() + 2); auto *row2 = global_alloc_array_clear<int>(s_haystack.size() + 2); for (int i = 0; i < s_needle.size(); ++i) { row2[0] = i + 1; for (int j = 0; j < s_haystack.size(); ++j) { int cost = (s_needle[i] == s_haystack[j]) ? 0 : 1; row2[j + 1] = MIN(row1[j + 1] + 1, MIN(row2[j] + 1, row1[j] + cost)); } int *tmp = row1; row1 = row2; row2 = tmp; } int *first, *smallest; first = smallest = row1; int *last = row1 + s_haystack.size(); while (++first != last) if (*first < *smallest) smallest = first; int rv = *smallest; global_free_array(row1); global_free_array(row2); return rv; }
void software_list_device::internal_validity_check(validity_checker &valid) { enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; softlist_map names; softlist_map descriptions; for (const software_info &swinfo : get_info()) { // first parse and output core errors if any if (m_errors.length() > 0) { osd_printf_error("%s: Errors parsing software list:\n%s", filename(), errors_string()); break; } // Now check if the xml data is valid: // Did we lost any description? if (swinfo.longname().empty()) { osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname().c_str()); break; } // Did we lost any year? if (swinfo.year().empty()) { osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname().c_str()); break; } // Did we lost any publisher? if (swinfo.publisher().empty()) { osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname().c_str()); break; } // Did we lost the software parts? if (swinfo.parts().empty()) { osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname().c_str()); break; } // Second, since the xml is fine, run additional checks: // check for duplicate names if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) { const software_info *match = names.find(swinfo.shortname())->second; osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname().c_str(), match->shortname().c_str()); } // check for duplicate descriptions std::string longname = std::string(swinfo.longname()); if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname().c_str(), swinfo.shortname().c_str()); bool is_clone = false; if (!swinfo.parentname().empty()) { is_clone = true; if (swinfo.parentname() == swinfo.shortname()) { osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname().c_str()); break; } // make sure the parent exists const software_info *swinfo2 = find(swinfo.parentname().c_str()); if (swinfo2 == nullptr) 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().empty()) 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 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().c_str(), is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); // make sure the year is only digits, '?' or '+' for (const char *s = swinfo.year().c_str(); *s != 0; s++) if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') { osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname().c_str(), swinfo.year().c_str()); break; } softlist_map part_names; for (const software_part &part : swinfo.parts()) { if (part.interface().empty()) osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); if (part.romdata().empty()) 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) osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); } } // release all the memory release(); }
int find_input_strings(running_machine &machine) { for (int i = 0; i < 32; i++) { for (int j = 0; j < 16; j++) { char tempstr[32]; sprintf(tempstr, "IN%d-%d", i, j); sc4inputs[i][j].name = tempstr; sc4inputs[i][j].used = false; } } int foundat = -1; UINT32 startblock = 0; UINT32 endblock = 0; UINT16 *rom = (UINT16*)machine.root_device().memregion( "maincpu" )->base(); UINT8 *rom8 = machine.root_device().memregion( "maincpu" )->base(); for (int i=0;i<(0x100000-0x40)/2;i++) { bool found = compare_input_code(machine, i); if (found==true) { startblock = (rom[i + 5] << 16) | rom[i + 6]; endblock = (rom[i + 10] << 16) | rom[i + 11]; sc45helperlog("------------ INPUTS -----------------\n"); sc45helperlog("input strings found at %08x (start of ponter block %08x end of pointer block %08x\n", i*2, startblock, endblock); foundat = i; if (endblock > startblock) { for (int j = startblock / 2; j < endblock / 2; j+=4) { UINT16 portpos = rom[j + 0]; int port = (portpos & 0x1f); int pos = (portpos >> 5); UINT16 unk2 = rom[j + 1]; UINT32 stringaddr = (rom[j + 2] << 16) | rom[j + 3]; sc45helperlog("(port %02x position %02x) unk %04x addr %08x ", port,pos, unk2, stringaddr); std::string tempstring; for (int k = stringaddr; k < stringaddr + 6; k++) { UINT8 chr = rom8[k^1]; if ((chr == 0xff) || (chr == 0x00)) { k = stringaddr + 6; } else { tempstring.push_back(chr); } } strtrimspace(tempstring); strmakelower(tempstring); //if (pos <= 5) { assert(pos >= 0 && pos < ARRAY_LENGTH(sc4inputs[port])); if (sc4inputs[port][pos].used == false) { sc4inputs[port][pos].used = true; sc4inputs[port][pos].name = tempstring; } else { printf("position already used?\n"); sc4inputs[port][pos].name.append(" OR "); sc4inputs[port][pos].name.append(tempstring); } } //else //{ // printf("invalid port position?\n"); //} sc45helperlog("%s", tempstring.c_str()); sc45helperlog("\n"); } } } }
TEST(corestr,strmakelower) { std::string value = "ValUE"; EXPECT_STREQ("value", strmakelower(value).c_str()); }