diff options
-rw-r--r-- | elaborate.cxx | 74 | ||||
-rwxr-xr-x | testsuite/semko/doubleglob.stp | 3 | ||||
-rwxr-xr-x | testsuite/semok/doubleglob.stp | 6 |
3 files changed, 83 insertions, 0 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 717192f2..ee63c8f3 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -289,6 +289,12 @@ isglob(string const & str) return(str.find('*') != str.npos); } +static bool +isdoubleglob(string const & str) +{ + return(str.find("**") != str.npos); +} + bool match_key::globmatch(match_key const & other) const { @@ -391,6 +397,74 @@ match_node::find_and_build (systemtap_session& s, b->build (s, p, loc, param_map, results); } } + else if (isdoubleglob(loc->components[pos]->functor)) // ** wildcard? + { + unsigned int num_results = results.size(); + + // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar" + + const probe_point::component *comp = loc->components[pos]; + const string &functor = comp->functor; + size_t glob_start = functor.find("**"); + size_t glob_end = functor.find_first_not_of('*', glob_start); + const string prefix = functor.substr(0, glob_start); + const string suffix = ((glob_end != string::npos) ? + functor.substr(glob_end) : ""); + + // Synthesize "foo*bar" + probe_point *simple_pp = new probe_point(*loc); + probe_point::component *simple_comp = new probe_point::component(*comp); + simple_comp->functor = prefix + "*" + suffix; + simple_pp->components[pos] = simple_comp; + try + { + find_and_build (s, p, simple_pp, pos, results); + } + catch (const semantic_error& e) + { + // Ignore semantic_errors, but cleanup + delete simple_pp; + delete simple_comp; + } + + // Synthesize "foo*.**bar" + // NB: any component arg should attach to the latter part only + probe_point *expanded_pp = new probe_point(*loc); + probe_point::component *expanded_comp_pre = new probe_point::component(*comp); + expanded_comp_pre->functor = prefix + "*"; + expanded_comp_pre->arg = NULL; + probe_point::component *expanded_comp_post = new probe_point::component(*comp); + expanded_comp_post->functor = "**" + suffix; + expanded_pp->components[pos] = expanded_comp_pre; + expanded_pp->components.insert(expanded_pp->components.begin() + pos + 1, + expanded_comp_post); + try + { + find_and_build (s, p, expanded_pp, pos, results); + } + catch (const semantic_error& e) + { + // Ignore semantic_errors, but cleanup + delete expanded_pp; + delete expanded_comp_pre; + delete expanded_comp_post; + } + + if (! loc->optional && num_results == results.size()) + { + // 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(string("probe point mismatch at position ") + + lex_cast (pos) + + " (alternatives:" + alternatives + ")" + + " didn't find any wildcard matches", + comp->tok); + } + } else if (isglob(loc->components[pos]->functor)) // wildcard? { match_key match (* loc->components[pos]); diff --git a/testsuite/semko/doubleglob.stp b/testsuite/semko/doubleglob.stp new file mode 100755 index 00000000..55a50760 --- /dev/null +++ b/testsuite/semko/doubleglob.stp @@ -0,0 +1,3 @@ +#! stap -p2 + +probe foo**bar {} diff --git a/testsuite/semok/doubleglob.stp b/testsuite/semok/doubleglob.stp new file mode 100755 index 00000000..06065165 --- /dev/null +++ b/testsuite/semok/doubleglob.stp @@ -0,0 +1,6 @@ +#! stap -p2 + +probe *sys**pen {} // [nd_]syscall.[mq_]open +probe t**ile {} // timer.profile +probe t**es(1) {} // timer.jiffies(1) +probe ke**on("vfs_read") {} // kernel.function("vfs_open") |