This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/1] Adding enumeration support to statement pp


linenos converted to vector<int> from int[2]
expanded statement.exp to cover ENUMERATED testing identical to RANGE

Signed-off-by: Brian Chrisman <brchrisman@gmail.com>
---
 dwflpp.cxx                             | 14 ++++-----
 dwflpp.h                               | 10 +++---
 tapsets.cxx                            | 56 ++++++++++++++++++++++++----------
 testsuite/systemtap.base/statement.exp | 31 +++++++++++++++++--
 4 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/dwflpp.cxx b/dwflpp.cxx
index bea4153..7bc88e6 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1777,7 +1777,7 @@ get_funcs_in_srcfile(base_func_info_map_t& funcs,
 
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
-                                         int linenos[2],
+                                         const vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -1821,9 +1821,9 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
                                     current_funcs, matching_lines);
   else if (lineno_type == WILDCARD)
     collect_all_lines(srcfile, current_funcs, matching_lines);
-  else // RANGE
-    for (int lineno = linenos[0]; lineno <= linenos[1]; lineno++)
-      collect_lines_for_single_lineno(srcfile, lineno, false, /* is_relative */
+  else if (lineno_type == ENUMERATED)
+    for (vector<int>::const_iterator it = linenos.begin(); it != linenos.end(); it++)
+      collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
                                       current_funcs, matching_lines);
 
   // call back with matching lines
@@ -1858,7 +1858,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  const vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
@@ -1916,8 +1916,8 @@ dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                         matches_lineno = dline == linenos[0];
                       else if (lineno_type == RELATIVE)
                         matches_lineno = dline == linenos[0] + function.decl_line;
-                      else if (lineno_type == RANGE)
-                        matches_lineno = (linenos[0] <= dline && dline <= linenos[1]);
+                      else if (lineno_type == ENUMERATED)
+                        matches_lineno = (binary_search(linenos.begin(), linenos.end(), dline));
                       else // WILDCARD
                         matches_lineno = true;
 
diff --git a/dwflpp.h b/dwflpp.h
index 2d4a656..03100db 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -38,7 +38,7 @@ struct symbol_table;
 struct base_query;
 struct external_function_query;
 
-enum lineno_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD };
+enum lineno_t { ABSOLUTE, RELATIVE, WILDCARD, ENUMERATED };
 enum info_status { info_unknown, info_present, info_absent };
 
 // module -> cu die[]
@@ -318,7 +318,7 @@ struct dwflpp
 
   template<typename T>
   void iterate_over_srcfile_lines (char const * srcfile,
-                                   int linenos[2],
+                                   const std::vector<int> linenos,
                                    enum lineno_t lineno_type,
                                    base_func_info_map_t& funcs,
                                    void (*callback) (Dwarf_Addr,
@@ -339,7 +339,7 @@ struct dwflpp
   void iterate_over_labels (Dwarf_Die *begin_die,
                             const std::string& sym,
                             const base_func_info& function,
-                            int linenos[2],
+                            const std::vector<int> linenos,
                             enum lineno_t lineno_type,
                             T *data,
                             void (* callback)(const base_func_info&,
@@ -701,7 +701,7 @@ dwflpp::iterate_over_plt<void>(void *object, void (*callback)(void*,
                                                               size_t));
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
-                                         int linenos[2],
+                                         const std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -711,7 +711,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const std::string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  const std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
diff --git a/tapsets.cxx b/tapsets.cxx
index 04810dc..9befdff 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -812,7 +812,7 @@ struct dwarf_query : public base_query
   string function;
   string file;
   lineno_t lineno_type;
-  int linenos[2];
+  vector<int> linenos;
   bool query_done;	// Found exact match
 
   // Holds the prologue end of the current function
@@ -1086,9 +1086,7 @@ void
 dwarf_query::parse_function_spec(const string & spec)
 {
   lineno_type = ABSOLUTE;
-  linenos[0] = linenos[1] = 0;
-
-  size_t src_pos, line_pos, dash_pos, scope_pos;
+  size_t src_pos, line_pos, scope_pos;
 
   // look for named scopes
   scope_pos = spec.rfind("::");
@@ -1135,18 +1133,29 @@ dwarf_query::parse_function_spec(const string & spec)
           if (lineno_type != WILDCARD)
             try
               {
-                // try to parse either N or N-M
-                dash_pos = spec.find('-', line_pos + 1);
-                if (dash_pos == string::npos)
-                  linenos[0] = linenos[1] = lex_cast<int>(spec.substr(line_pos + 1));
+                // try to parse N, N-M, or N,M,O,P, or combination thereof...
+                if (spec.find_first_of(",-", line_pos + 1) != string::npos)
+                  {
+                    lineno_type = ENUMERATED;
+                    vector<string> sub_specs;
+                    tokenize(spec.substr(line_pos + 1), sub_specs, ",");
+                    vector<string>::const_iterator line_spec;
+                    for (line_spec = sub_specs.begin(); line_spec != sub_specs.end(); ++line_spec)
+                      {
+                        vector<string> ranges;
+                        tokenize(*line_spec, ranges, "-");
+                        if (ranges.size() > 1)
+                            for (int i = lex_cast<int>(ranges.front()); i <= lex_cast<int>(ranges.back()); i++)
+                                linenos.push_back(i);
+                        else
+                            linenos.push_back(lex_cast<int>(ranges.at(0)));
+                      }
+                    sort(linenos.begin(), linenos.end());
+                  }
                 else
                   {
-                    lineno_type = RANGE;
-                    linenos[0] = lex_cast<int>(spec.substr(line_pos + 1,
-                                                        dash_pos - line_pos - 1));
-                    linenos[1] = lex_cast<int>(spec.substr(dash_pos + 1));
-                    if (linenos[0] > linenos[1])
-                      throw runtime_error("bad range");
+                    linenos.push_back(lex_cast<int>(spec.substr(line_pos + 1)));
+                    linenos.push_back(lex_cast<int>(spec.substr(line_pos + 1)));
                   }
               }
             catch (runtime_error & exn)
@@ -1188,8 +1197,23 @@ dwarf_query::parse_function_spec(const string & spec)
               clog << "+" << linenos[0];
               break;
 
-            case RANGE:
-              clog << linenos[0] << " - " << linenos[1];
+            case ENUMERATED:
+              {
+                vector<int>::const_iterator linenos_it,range_it;
+                for (linenos_it = linenos.begin(); linenos_it != linenos.end(); ++linenos_it)
+                  {
+                    vector<int>::const_iterator range_it(linenos_it);
+                    while ((range_it+1) != linenos.end() && *range_it + 1 == *(range_it+1))
+                        ++range_it;
+                    if (linenos_it == range_it)
+                        clog << *linenos_it;
+                    else
+                        clog << *linenos_it << "-" << *range_it;
+                    if (range_it + 1 != linenos.end())
+                      clog << ",";
+                    linenos_it = range_it;
+                  }
+                }
               break;
 
             case WILDCARD:
diff --git a/testsuite/systemtap.base/statement.exp b/testsuite/systemtap.base/statement.exp
index a8a1f87..546450a 100644
--- a/testsuite/systemtap.base/statement.exp
+++ b/testsuite/systemtap.base/statement.exp
@@ -90,7 +90,7 @@ expect_probes * * 9
 
 # Now we do some consistent probe checking
 
-# ABSOLUTE and RANGE should give the same results for wild and single func
+# ABSOLUTE, RANGE, and ENUMERATED should give the same results for wild and single func
 set subtest "ABSOLUTE - single func"
 expect_probes foo 5 1
 set subtest "ABSOLUTE - wild func"
@@ -99,8 +99,16 @@ set subtest "RANGE - single func"
 expect_probes foo 5-7 3
 set subtest "RANGE - wild func"
 expect_probes * 5-7 3
-
-# But ABSOLUTE and RANGE shouldn't give any results if the linenos fall outside
+set subtest "ENUMERATED - single func"
+expect_probes foo 5,6,7 3
+set subtest "ENUMERATED and RANGE - single func"
+expect_probes foo 5,6-7 3
+set subtest "ENUMERATED - wild func"
+expect_probes * 5,6,7 3
+set subtest "ENUMERATED and RANGE - wild func"
+expect_probes * 5-6,7 3
+
+# But ABSOLUTE, RANGE, and ENUMERATED shouldn't give any results if the linenos fall outside
 # the given func(s)
 set subtest "ABSOLUTE - outside single func"
 expect_probes bar 5 0
@@ -110,6 +118,10 @@ set subtest "RANGE - outside single func"
 expect_probes bar 5-7 0
 set subtest "RANGE - outside wild func"
 expect_probes {[bm]*} 5-7 0
+set subtest "ENUMERATED - outside single func"
+expect_probes bar 5-6,7 0
+set subtest "ENUMERATED - outside wild func"
+expect_probes {[bm]*} 5,6-7 0
 
 # RELATIVE and WILDCARD must be applied *per* function
 set subtest "RELATIVE - single func"
@@ -138,6 +150,12 @@ expect_probes foo 0-5 2
 set subtest "RANGE - out-of-bounds upper"
 expect_probes foo 5-999 3
 
+# ENUMERATED on a function is bound by function linenos
+set subtest "ENUMERATED - out-of-bounds lower"
+expect_probes foo 0,1,2,3,4,5 2
+set subtest "ENUMERATED - out-of-bounds upper"
+expect_probes foo 5,6,7,998,999 3
+
 # RANGE overlapping two functions yields intersection of range and filtered
 # functions
 set subtest "RANGE - single func overlapping"
@@ -145,4 +163,11 @@ expect_probes foo 5-13 3
 set subtest "RANGE - wildcard func overlapping"
 expect_probes * 5-13 6
 
+# ENUMERATED overlapping two functions yields intersection of range and filtered
+# functions
+set subtest "ENUMERATED - single func overlapping"
+expect_probes foo 5,6,7,8,9,10,11,12,13 3
+set subtest "ENUMERATED - wildcard func overlapping"
+expect_probes * 5,6,7,8,9,10,11,12,13 6
+
 if {[file exists "$test"]}   { file delete "$test" }
-- 
1.8.5.2 (Apple Git-48)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]