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 /elaborate.cxx | |
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.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 74 |
1 files changed, 74 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]); |