From a477f3f17daab73993ce765900e95cddc3463586 Mon Sep 17 00:00:00 2001 From: dsmith Date: Wed, 24 May 2006 18:37:50 +0000 Subject: 2006-05-24 David Smith * 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. --- ChangeLog | 14 ++++++++++++ elaborate.cxx | 48 ++++++++++++++++++++++++++++++----------- elaborate.h | 1 + parse.cxx | 21 ++++++++++++++++++ testsuite/parseko/twentytwo.stp | 5 +++++ testsuite/parseok/sixteen.stp | 7 ++++++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100755 testsuite/parseko/twentytwo.stp create mode 100755 testsuite/parseok/sixteen.stp diff --git a/ChangeLog b/ChangeLog index 1739a80d..41af6be0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-05-24 David Smith + + * 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 * testsuite/parseko/cmdlinearg01.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 +#include } #include @@ -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* { } + -- cgit