From 5bcb7b4ea057614cd041db696f43935f6f6a93f1 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 31 Oct 2013 15:38:29 -0400 Subject: [PATCH] levensh suggest unresolved probe points This patch adds Levenshtein suggestion to match_node::find_and_build(). Suggestions are made in three cases: - Unresolved double-glob (e.g. syscall.poen**) - Unresolved glob (e.g. syscall.poen*) - Unresolved no-glob (e.g. kernel.functoin("bla")) Note that suggestions for globby functors are based on the prefix part only (part of functor prior to the **) to increase meaningfulness. Example outputs: syscall.poen --> similar: open, chown, fork, iopl, mount kernel.functoin --> similar: function, data, trace, mark, statement syscall.poen** --> similar: open, chown, fork, iopl, mount syscall.poen* --> similar: open, chown, fork, iopl, mount syscall.*poen --> similar: open, chown, ppoll, capget, capset syscall.**poen --> similar: open, capget, capset, chown, fchown Non-globby functors in general give good results. Globby stuff can be troublesome: sys**poen --> similar: nfs, vfs, _nfs, _vfs, end --- elaborate.cxx | 53 +++++++++++++++++++++++++++++++-------------------- elaborate.h | 1 + 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/elaborate.cxx b/elaborate.cxx index 00ce8c9a2..01d03c8f6 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -541,12 +541,10 @@ match_node::find_and_build (systemtap_session& s, { // We didn't find any wildcard matches (since the size of // the result vector didn't change). Throw an error. - string alternatives; - for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++) - alternatives += string(" ") + i->first.str(); - - throw SEMANTIC_ERROR(_F("probe point mismatch (alternatives: %s)", - alternatives.c_str()), comp->tok); + string sugs = suggest_functors(functor); + throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s", + sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()), + comp->tok); } } else if (isglob(loc->components[pos]->functor)) // wildcard? @@ -618,13 +616,10 @@ match_node::find_and_build (systemtap_session& s, { // We didn't find any wildcard matches (since the size of // the result vector didn't change). Throw an error. - string alternatives; - for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++) - alternatives += string(" ") + i->first.str(); - - throw SEMANTIC_ERROR(_F("probe point mismatch %s didn't find any wildcard matches", - (alternatives == "" ? "" : _(" (alternatives: ") + - alternatives + ")").c_str()), loc->components[pos]->tok); + string sugs = suggest_functors(loc->components[pos]->functor); + throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s", + sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()), + loc->components[pos]->tok); } } else @@ -657,18 +652,34 @@ match_node::find_and_build (systemtap_session& s, { // We didn't find any alias suffixes (since the size of the // result vector didn't change). Throw an error. - string alternatives; - for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++) - alternatives += string(" ") + i->first.str(); - - throw SEMANTIC_ERROR(_F("probe point mismatch %s", - (alternatives == "" ? "" : (_(" (alternatives:") + alternatives + - ")").c_str())), - loc->components[pos]->tok); + string sugs = suggest_functors(loc->components[pos]->functor); + throw SEMANTIC_ERROR (_F("probe point mismatch%s", + sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()), + loc->components[pos]->tok); } } } +string +match_node::suggest_functors(string functor) +{ + // only use prefix if globby (and prefix is non-empty) + size_t glob = functor.find('*'); + if (glob != string::npos && glob != 0) + functor.erase(glob); + if (functor.empty()) + return ""; + + set functors; + for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++) + { + string ftor = i->first.str(); + if (ftor.find('(') != string::npos) // trim any parameter + ftor.erase(ftor.find('(')); + functors.insert(ftor); + } + return levenshtein_suggest(functor, functors, 5); // print top 5 +} void match_node::try_suffix_expansion (systemtap_session& s, diff --git a/elaborate.h b/elaborate.h index e93723d60..08e3d1f86 100644 --- a/elaborate.h +++ b/elaborate.h @@ -330,6 +330,7 @@ match_node void find_and_build (systemtap_session& s, probe* p, probe_point *loc, unsigned pos, std::vector& results); + std::string suggest_functors(std::string functor); void try_suffix_expansion (systemtap_session& s, probe *p, probe_point *loc, unsigned pos, std::vector& results); -- 2.43.5