diff options
author | Josh Stone <jistone@redhat.com> | 2010-03-25 14:31:45 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2010-03-25 14:38:53 -0700 |
commit | 122b4fcd9ca8947ab96c8efdfe4430df8ea6b341 (patch) | |
tree | af054be49868bb0f3e5358dcf1d80062b06e10fd | |
parent | 4a9530fe2547894f2d2452488e62fb3f389fd4cb (diff) | |
download | systemtap-steved-122b4fcd9ca8947ab96c8efdfe4430df8ea6b341.tar.gz systemtap-steved-122b4fcd9ca8947ab96c8efdfe4430df8ea6b341.tar.xz systemtap-steved-122b4fcd9ca8947ab96c8efdfe4430df8ea6b341.zip |
PR11399: Allow '**' to match tapsets across '.'
Normally wildcards are constrained to matching a single probe point
component between the '.' separator. This patch enables '**' to match
across the separator.
Probe point parameters are still absolute separators though, as there's
not really a meaningful semantic we could use to cross them with '**'.
* elaborate.cxx (isdoubleglob): Check for '**'.
(match_node::find_and_build): Recurse '**' to cross separators.
* testsuite/semok/doubleglob.stp: New test of broad wildcards.
* testsuite/semko/doubleglob.stp: New negative test.
-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") |