summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--elaborate.cxx48
-rw-r--r--elaborate.h1
-rw-r--r--parse.cxx21
-rwxr-xr-xtestsuite/parseko/twentytwo.stp5
-rwxr-xr-xtestsuite/parseok/sixteen.stp7
6 files changed, 84 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 1739a80d..41af6be0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2006-05-24 David Smith <dsmith@redhat.com>
+ * elaborate.cxx (isglob): New function.
+ (match_key::globmatch): New function.
+ (match_node::find_and_build): Uses isglob() and
+ match_key::globmatch() to provide support for wildcards such as
+ "kernel.syscall.*read*" (Bugzilla #1928).
+ * elaborate.h (match_key::globmatch): Added function declaration.
+ * parse.cxx (parser::parse_probe_point): Collects one or more
+ tokens into a single probe-point functor string.
+
+ * testsuite/parseko/twentytwo.stp: New file.
+ * testsuite/parseok/sixteen.stp: New file.
+
+2006-05-24 David Smith <dsmith@redhat.com>
+
* testsuite/parseko/cmdlinearg01.stp: New file.
* testsuite/parseko/cmdlinearg02.stp: New file.
* testsuite/parseko/eighteen.stp: New file.
diff --git a/elaborate.cxx b/elaborate.cxx
index bdeb14f5..82e767e5 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -13,6 +13,7 @@
extern "C" {
#include <sys/utsname.h>
+#include <fnmatch.h>
}
#include <algorithm>
@@ -165,6 +166,23 @@ match_key::operator<(match_key const & other) const
&& parameter_type < other.parameter_type));
}
+static bool
+isglob(string const & str)
+{
+ return(str.find('*') != str.npos);
+}
+
+bool
+match_key::globmatch(match_key const & other) const
+{
+ const char *other_str = other.name.c_str();
+ const char *name_str = name.c_str();
+
+ return ((fnmatch(name_str, other_str, FNM_NOESCAPE) == 0)
+ && have_parameter == other.have_parameter
+ && parameter_type == other.parameter_type);
+}
+
// ------------------------------------------------------------------------
// Members of match_node
// ------------------------------------------------------------------------
@@ -242,27 +260,33 @@ match_node::find_and_build (systemtap_session& s,
b->build (s, p, loc, param_map, results);
}
- else if (loc->components[pos]->functor == "*") // wildcard?
+ else if (isglob(loc->components[pos]->functor)) // wildcard?
{
+ match_key match (* loc->components[pos]);
+
// Call find_and_build for each possible match. Ignore errors -
// unless we don't find any match.
unsigned int num_results = results.size();
for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
{
+ const match_key& subkey = i->first;
match_node* subnode = i->second;
- // recurse
- try
- {
- subnode->find_and_build (s, p, loc, pos+1, results);
- }
- catch (const semantic_error& e)
+
+ if (match.globmatch(subkey))
{
- // Ignore semantic_errors while expanding wildcards. If
- // we get done and nothing was expanded, the code
- // following the loop will complain.
+ // recurse
+ try
+ {
+ subnode->find_and_build (s, p, loc, pos+1, results);
+ }
+ catch (const semantic_error& e)
+ {
+ // Ignore semantic_errors while expanding wildcards.
+ // If we get done and nothing was expanded, the code
+ // following the loop will complain.
+ }
}
- }
-
+ }
if (num_results == results.size())
{
// We didn't find any wildcard matches (since the size of
diff --git a/elaborate.h b/elaborate.h
index ed8570f3..426b8ee2 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -174,6 +174,7 @@ match_key
match_key & with_string();
std::string str() const;
bool operator<(match_key const & other) const;
+ bool globmatch(match_key const & other) const;
};
diff --git a/parse.cxx b/parse.cxx
index afa5a3ad..0e0d1682 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1129,7 +1129,28 @@ parser::parse_probe_point ()
pl->components.push_back (c);
// NB though we still may add c->arg soon
+ const token* last_t = t;
t = peek ();
+
+ // We need to keep going until we find something other than a
+ // '*' or identifier, since a probe point wildcard can be
+ // something like "*a", "*a*", "a*b", "a*b*", etc.
+ while (t &&
+ // case 1: '*{identifier}'
+ ((last_t->type == tok_operator && last_t->content == "*"
+ && (t->type == tok_identifier || t->type == tok_keyword))
+ // case 2: '{identifier}*'
+ || ((last_t->type == tok_identifier
+ || last_t->type == tok_keyword)
+ && t->type == tok_operator && t->content == "*")))
+ {
+ c->functor += t->content;
+ next (); // consume the identifier or '*'
+
+ last_t = t;
+ t = peek ();
+ }
+
if (t && t->type == tok_operator
&& (t->content == "{" || t->content == "," || t->content == "="
|| t->content == "+=" ))
diff --git a/testsuite/parseko/twentytwo.stp b/testsuite/parseko/twentytwo.stp
new file mode 100755
index 00000000..a5434355
--- /dev/null
+++ b/testsuite/parseko/twentytwo.stp
@@ -0,0 +1,5 @@
+#! stap -p1
+
+# bad wildcard
+
+probe a** { }
diff --git a/testsuite/parseok/sixteen.stp b/testsuite/parseok/sixteen.stp
new file mode 100755
index 00000000..31e01238
--- /dev/null
+++ b/testsuite/parseok/sixteen.stp
@@ -0,0 +1,7 @@
+#! stap -p1
+
+# complicated probe point wildcard
+probe abcX { }
+
+probe *abc* { }
+