]> sourceware.org Git - systemtap.git/commitdiff
Display source context for error and warning messages (6701)
authorRajan Arora <rarora@redhat.com>
Thu, 9 Oct 2008 23:58:30 +0000 (19:58 -0400)
committerRajan Arora <rarora@redhat.com>
Thu, 9 Oct 2008 23:58:30 +0000 (19:58 -0400)
ChangeLog
elaborate.cxx
parse.cxx
parse.h
session.h
staptree.h
tapsets.cxx
testsuite/ChangeLog
testsuite/parseko/source_context.stp [new file with mode: 0755]
testsuite/systemtap.base/warnings.exp

index 8b1645e44266977a695cd7ad98c0dcf0547dd3c9..3806b475a127a225250501e1455e669197d8d88b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2008-10-09  Rajan Arora   <rarora@redhat.com>
+
+       * elaborate.cxx (systemtap_session::print_error_source): New.
+       (systemtap_session::print_error): Call it.
+       (systemtap_session::print_warning): Likewise.
+       * parse.cxx (parser::print_error): Likewise.
+       * session.h (struct systemtap_session::print_error_source):
+       Declare it.
+       * parse.cxx (lexer::get_input_contents): New.
+       (parser::parse): Call it.
+       (lexer::set_current_file): New.
+       (parser::parse): Call it.
+       * parse.h (class lexer::get_input_contents): Declare it.
+       (class lexer::set_current_file): Declare it.
+       (class lexer): New member current_file.
+       (class lexer): Update input_contents from vector<char>
+       to std::string.
+       (struct source_loc): New member stap_file.
+       * staptree.h (struct stapfile): New member file_contents.
+
+2008-10-09  Stan Cox  <scox@redhat.com>
+
+       * tapsets.cxx (query_cu): Fix typo.
+
 2008-10-06  Wenji Huang  <wenji.huang@oracle.com>
 
        PR 4886
index afdc796ea3e80a27e2f1c03e6fb9c6ef9656e2cd..9f0a2a746e08a4d8ceebd9c504e95fde9d3dcc3c 100644 (file)
@@ -1426,6 +1426,7 @@ void
 systemtap_session::print_error (const semantic_error& e)
 {
   string message_str[2];
+  string align_semantic_error ("        ");
 
   // NB: we don't print error messages during listing mode.
   if (listing_mode) return;
@@ -1462,22 +1463,64 @@ systemtap_session::print_error (const semantic_error& e)
     {
       seen_errors.insert (message_str[1]);
       cerr << message_str[0];
+
+      if (e.tok1)
+        print_error_source (cerr, align_semantic_error, e.tok1);
+
+      if (e.tok2)
+        print_error_source (cerr, align_semantic_error, e.tok2);
     }
 
   if (e.chain)
     print_error (* e.chain);
 }
 
+void
+systemtap_session::print_error_source (std::ostream& message,
+                                       std::string& align, const token* tok)
+{
+  unsigned i = 0;
+  unsigned line = tok->location.line;
+  unsigned col = tok->location.column;
+  string file_contents;
+  if (tok->location.stap_file)
+    file_contents = tok->location.stap_file->file_contents;
+  else
+    //No source to print, silently exit
+    return;
+  size_t start_pos = 0, end_pos = 0;
+  //Navigate to the appropriate line
+  while (i != line && end_pos != std::string::npos)
+    {
+      start_pos = end_pos;
+      end_pos = file_contents.find ('\n', start_pos) + 1;
+      i++;
+    }
+  message << align << "source: " << file_contents.substr (start_pos, end_pos-start_pos-1) << endl;
+  message << align << "        ";
+  //Navigate to the appropriate column
+  for (i=start_pos; i<start_pos+col-1; i++)
+    {
+      if(isspace(file_contents[i]))
+       message << file_contents[i];
+      else
+       message << ' ';
+    }
+  message << "^" << endl;
+}
+
 void
 systemtap_session::print_warning (const string& message_str, const token* tok)
 {
   // Duplicate elimination
+  string align_warning (" ");
   if (seen_warnings.find (message_str) == seen_warnings.end())
     {
       seen_warnings.insert (message_str);
       clog << "WARNING: " << message_str;
       if (tok) { clog << ": "; print_token (clog, tok); }
       clog << endl;
+      print_error_source (clog, align_warning, tok);
     }
 }
 
index 1c1772f62518444de67a90772bc9a1a3a798ac5a..1982eb44be6d1135edc6a403c07f14b17acb9759 100644 (file)
--- a/parse.cxx
+++ b/parse.cxx
@@ -124,17 +124,22 @@ operator << (ostream& o, const token& t)
 void
 parser::print_error  (const parse_error &pe)
 {
+  string align_parse_error ("     ");
   cerr << "parse error: " << pe.what () << endl;
 
   if (pe.tok)
     {
       cerr << "\tat: " << *pe.tok << endl;
+      session.print_error_source (cerr, align_parse_error, pe.tok);
     }
   else
     {
       const token* t = last_t;
       if (t)
-        cerr << "\tsaw: " << *t << endl;
+       {
+         cerr << "\tsaw: " << *t << endl;
+         session.print_error_source (cerr, align_parse_error, t);
+       }
       else
         cerr << "\tsaw: " << input_name << " EOF" << endl;
     }
@@ -579,15 +584,27 @@ parser::peek_kw (std::string const & kw)
 
 
 lexer::lexer (istream& i, const string& in, systemtap_session& s):
-  input (i), input_name (in),
+  input (i), input_name (in), input_contents (""),
   input_pointer (0), cursor_suspend_count(0),
-  cursor_line (1), cursor_column (1), session(s)
+  cursor_line (1), cursor_column (1), session(s),
+  current_file (0)
 {
   char c;
   while(input.get(c))
     input_contents.push_back(c);
 }
 
+std::string
+lexer::get_input_contents ()
+{
+  return input_contents;
+}
+
+void
+lexer::set_current_file (stapfile* f)
+{
+  current_file = f;
+}
 
 int
 lexer::input_peek (unsigned n)
@@ -642,6 +659,8 @@ lexer::scan (bool wildcard)
 {
   token* n = new token;
   n->location.file = input_name;
+  if (current_file)
+    n->location.stap_file = current_file;
 
   unsigned semiskipped_p = 0;
 
@@ -945,6 +964,8 @@ stapfile*
 parser::parse ()
 {
   stapfile* f = new stapfile;
+  input.set_current_file (f);
+  f->file_contents = input.get_input_contents ();
   f->name = input_name;
 
   bool empty = true;
@@ -1013,15 +1034,18 @@ parser::parse ()
     {
       cerr << "Input file '" << input_name << "' is empty or missing." << endl;
       delete f;
+      input.set_current_file (0);
       return 0;
     }
   else if (num_errors > 0)
     {
       cerr << num_errors << " parse error(s)." << endl;
       delete f;
+      input.set_current_file (0);
       return 0;
     }
 
+  input.set_current_file (0);
   return f;
 }
 
diff --git a/parse.h b/parse.h
index cf31f4f89b8878fa6c05acc70cd8fc4e0457e648..2e2b656f01110b45193480e897a8c63d4eeabd4d 100644 (file)
--- a/parse.h
+++ b/parse.h
 #include <stdexcept>
 #include <stdint.h>
 
+struct stapfile;
+
 struct source_loc
 {
   std::string file;
   unsigned line;
   unsigned column;
+  stapfile* stap_file;
 };
 
 std::ostream& operator << (std::ostream& o, const source_loc& loc);
@@ -71,6 +74,8 @@ class lexer
 public:
   token* scan (bool wildcard=false);
   lexer (std::istream&, const std::string&, systemtap_session&);
+  std::string get_input_contents ();
+  void set_current_file (stapfile* f);
 
 private:
   int input_get ();
@@ -79,16 +84,15 @@ private:
   int input_peek (unsigned n=0);
   std::istream& input;
   std::string input_name;
-  std::vector<char> input_contents;
+  std::string input_contents;
   int input_pointer; // index into input_contents
   unsigned cursor_suspend_count;
   unsigned cursor_line;
   unsigned cursor_column;
   systemtap_session& session;
+  stapfile* current_file;
 };
 
-
-struct stapfile;
 struct probe;
 struct probe_alias;
 struct vardecl;
index b8bd971a7848daef169afa30da5f76c04a53bb0e..4746422f585996dc314bfdad0092f8a65e05766c 100644 (file)
--- a/session.h
+++ b/session.h
@@ -179,6 +179,7 @@ struct systemtap_session
   const token* last_token;
   void print_token (std::ostream& o, const token* tok);
   void print_error (const semantic_error& e);
+  void print_error_source (std::ostream&, std::string&, const token* tok);
   void print_warning (const std::string& w, const token* tok = 0);
 
   // reNB: new POD members likely need to be explicitly cleared in the ctor.
index 770a731e0be523853209fa95007c6d9ebbdf7979..c35728cbfc2dc11b1cc068bb5c063f7aab21bd4b 100644 (file)
@@ -574,8 +574,10 @@ struct stapfile
   std::vector<functiondecl*> functions;
   std::vector<vardecl*> globals;
   std::vector<embeddedcode*> embeds;
+  std::string file_contents;
   bool privileged;
-  stapfile (): privileged (false) {}
+  stapfile (): file_contents (""),
+    privileged (false) {}
   void print (std::ostream& o) const;
 };
 
index a5a62c7aed528938791f7ed028c9f7637213dfd7..3a70936f56257f7e031976133387df542fe8df72 100644 (file)
@@ -3799,7 +3799,7 @@ query_cu (Dwarf_Die * cudie, void * arg)
                 {
                   stringstream msg;
                   msg << "address 0x" << hex << queryaddr
-                      << "does not match the begining of a statement";
+                      << " does not match the beginning of a statement";
                   throw semantic_error(msg.str());
                 }
             }
index 5ddee32c3497418ae406240b80c1e7b71b770b78..ceef8c40de3332e04806972e4138393789f9f613 100644 (file)
@@ -1,3 +1,8 @@
+2008-10-09  Rajan Arora   <rarora@redhat.com>
+
+       * systemtap.base/warnings.exp: Allow for source: lines.
+       * parseko/source_context.stp: New file.
+
 2008-10-04  Mark Wielaard  <mjw@redhat.com>
 
        * systemtap.base/debugpath.exp: Guess a bit more intelligently
diff --git a/testsuite/parseko/source_context.stp b/testsuite/parseko/source_context.stp
new file mode 100755 (executable)
index 0000000..403b203
--- /dev/null
@@ -0,0 +1,5 @@
+probe timer.ms(123)
+{
+printf("Probe successful\n")
+                                  eeexit ()
+}
index a90860d973cd914c6fd661da999a2b1a2626272f..4bbef40d054d3d74b0c528aa748c4e96146c5ba2 100644 (file)
@@ -6,6 +6,8 @@ expect {
     -timeout 30
     -re {^WARNING:[^\r\n]*\r\n} { incr ok; exp_continue }
     -re {^[^\r\n]*.ko\r\n} { incr ok; exp_continue }
+    -re {^[^\r]*source:[^\r\n]*\r\n} {exp_continue}
+    -re {^[^\r\n]*\^[^\r\n]*\r\n} {exp_continue}
     timeout { fail "$test (timeout)" }
     eof { }
 }
This page took 0.048093 seconds and 5 git commands to generate.