summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-03-25 14:31:45 -0700
committerJosh Stone <jistone@redhat.com>2010-03-25 14:38:53 -0700
commit122b4fcd9ca8947ab96c8efdfe4430df8ea6b341 (patch)
treeaf054be49868bb0f3e5358dcf1d80062b06e10fd
parent4a9530fe2547894f2d2452488e62fb3f389fd4cb (diff)
downloadsystemtap-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.cxx74
-rwxr-xr-xtestsuite/semko/doubleglob.stp3
-rwxr-xr-xtestsuite/semok/doubleglob.stp6
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")