void software_list_device::find_approx_matches(const std::string &name, int matches, const software_info **list, const char *interface) { // if no name, return if (name.empty()) return; // initialize everyone's states std::vector<double> penalty(matches); for (int matchnum = 0; matchnum < matches; matchnum++) { penalty[matchnum] = 2.0; list[matchnum] = nullptr; } // iterate over our info (will cause a parse if needed) std::u32string const search(ustr_from_utf8(normalize_unicode(name, unicode_normalization_form::D, true))); for (const software_info &swinfo : get_info()) { for (const software_part &swpart : swinfo.parts()) { if ((interface == nullptr || swpart.matches_interface(interface)) && is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE) { // pick the best match between driver name and description double const longpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.longname(), unicode_normalization_form::D, true))); double const shortpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.shortname(), unicode_normalization_form::D, true))); double const curpenalty = (std::min)(longpenalty, shortpenalty); // make sure it isn't already in the table bool skip = false; for (int matchnum = 0; !skip && (matchnum < matches) && list[matchnum]; matchnum++) { if ((penalty[matchnum] == curpenalty) && (swinfo.longname() == list[matchnum]->longname()) && (swinfo.shortname() == list[matchnum]->shortname())) skip = true; } if (!skip) { // insert into the sorted table of matches for (int matchnum = matches - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < matches - 1) { penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } } } } }
int main(void) { char *result; char *input = strdup("Poincar\xc3\xa9 and \xc3\xa6"); normalize_unicode(input, &result); if (strcmp(result, "Poincare and ae")) { fprintf(stderr, "Error: Expected Poincare, got %s\n", result); free(input); free(result); return 1; } free(input); free(result); input = strdup("rándôm"); normalize_unicode(input, &result); if (strcmp(result, "random")) { fprintf(stderr, "Error: Expected \"random\", got %s\n", result); free(input); free(result); return 1; } free(input); free(result); return 0; }