std::vector<std::string> SymbolTable::ClosestVariableOrFunctionMatch(const char *str) const { // This is a little wasteful, but we'll look through all of the // variable and function symbols and compute the edit distance from the // given string to them. If the edit distance is under maxDelta, then // it goes in the entry of the matches[] array corresponding to its // edit distance. const int maxDelta = 2; std::vector<std::string> matches[maxDelta+1]; for (int i = 0; i < (int)variables.size(); ++i) { std::vector<Symbol *> &sv = *(variables[i]); for (int j = 0; j < (int)sv.size(); ++j) { int dist = StringEditDistance(str, sv[j]->name, maxDelta+1); if (dist <= maxDelta) matches[dist].push_back(sv[j]->name); } } std::map<std::string, std::vector<Symbol *> >::const_iterator iter; for (iter = functions.begin(); iter != functions.end(); ++iter) { int dist = StringEditDistance(str, iter->first, maxDelta+1); if (dist <= maxDelta) matches[dist].push_back(iter->first); } // Now, return the first entry of matches[] that is non-empty, if any. for (int i = 0; i <= maxDelta; ++i) { if (matches[i].size()) return matches[i]; } // Otherwise, no joy. return std::vector<std::string>(); }
std::vector<std::string> SymbolTable::closestTypeMatch(const char *str, bool structsVsEnums) const { // This follows the same approach as ClosestVariableOrFunctionMatch() // above; compute all edit distances, keep the ones shorter than // maxDelta, return the first non-empty vector of one or more sets of // alternatives with minimal edit distance. const int maxDelta = 2; std::vector<std::string> matches[maxDelta+1]; TypeMapType::const_iterator iter; for (iter = types.begin(); iter != types.end(); ++iter) { // Skip over either StructTypes or EnumTypes, depending on the // value of the structsVsEnums parameter bool isEnum = (CastType<EnumType>(iter->second) != NULL); if (isEnum && structsVsEnums) continue; else if (!isEnum && !structsVsEnums) continue; int dist = StringEditDistance(str, iter->first, maxDelta+1); if (dist <= maxDelta) matches[dist].push_back(iter->first); } for (int i = 0; i <= maxDelta; ++i) { if (matches[i].size()) return matches[i]; } return std::vector<std::string>(); }
std::vector<std::string> MatchStrings(const std::string &str, const std::vector<std::string> &options) { if (str.size() == 0 || (str.size() == 1 && !isalpha(str[0]))) // don't even try... return std::vector<std::string>(); const int maxDelta = 2; std::vector<std::string> matches[maxDelta+1]; // For all of the options that are up to maxDelta edit distance, store // them in the element of matches[] that corresponds to their edit // distance. for (int i = 0; i < (int)options.size(); ++i) { int dist = StringEditDistance(str, options[i], maxDelta+1); if (dist <= maxDelta) matches[dist].push_back(options[i]); } // And return the first one of them, if any, that has at least one // match. for (int i = 0; i <= maxDelta; ++i) { if (matches[i].size()) return matches[i]; } return std::vector<std::string>(); }