]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Make checks self-documenting
authorPetr Machata <pmachata@redhat.com>
Fri, 27 Aug 2010 17:51:37 +0000 (19:51 +0200)
committerPetr Machata <pmachata@redhat.com>
Fri, 27 Aug 2010 17:51:37 +0000 (19:51 +0200)
dwarflint/check_debug_abbrev.hh
dwarflint/check_debug_aranges.hh
dwarflint/check_debug_line.cc
dwarflint/check_debug_loc_range.hh
dwarflint/check_debug_pub.cc
dwarflint/check_duplicate_DW_tag_variable.cc
dwarflint/checkdescriptor.cc
dwarflint/checkdescriptor.hh
dwarflint/checks.cc
dwarflint/dwarflint.cc
dwarflint/main.cc

index 4ad0d8752450e7e45498c084aa0af33cf69e6b8a..cad078831c5f97d699db5e7d6bb698644b418ee6 100644 (file)
@@ -33,7 +33,9 @@ class check_debug_abbrev
 
 public:
   static checkdescriptor descriptor () {
-    static checkdescriptor cd ("check_debug_abbrev @low");
+    static checkdescriptor cd
+      (checkdescriptor::create ("check_debug_abbrev")
+       .groups ("@low"));
     return cd;
   }
 
index d787b35c12f2767e003924977721a9e879daf78e..c02e4ce736d671f573010aa48637fd240a166afd 100644 (file)
@@ -37,7 +37,9 @@ class check_debug_aranges
 
 public:
   static checkdescriptor descriptor () {
-    static checkdescriptor cd ("check_debug_aranges @low");
+    static checkdescriptor cd
+      (checkdescriptor::create ("check_debug_aranges")
+       .groups ("@low"));
     return cd;
   }
 
index 406e18eb5fa88a80bffb2d56c43e95492df11754..696056ea8c6ec074a4d5b2eea2cab0becfc30089 100644 (file)
@@ -57,7 +57,9 @@ namespace
 
   public:
     static checkdescriptor descriptor () {
-      static checkdescriptor cd ("check_debug_line @low");
+      static checkdescriptor cd
+       (checkdescriptor::create ("check_debug_line")
+        .groups ("@low"));
       return cd;
     }
 
index 1c6abd79d6e1c88592691dd040d61f3055c4dd03..e352d0b9974fe657b3e117a187a1b1ed38515ad0 100644 (file)
@@ -37,7 +37,9 @@ class check_debug_ranges
 
 public:
   static checkdescriptor descriptor () {
-    static checkdescriptor cd ("check_debug_ranges @low");
+    static checkdescriptor cd
+      (checkdescriptor::create ("check_debug_ranges")
+       .groups ("@low"));
     return cd;
   }
 
@@ -52,7 +54,9 @@ class check_debug_loc
 
 public:
   static checkdescriptor descriptor () {
-    static checkdescriptor cd ("check_debug_loc @low");
+    static checkdescriptor cd
+      (checkdescriptor::create ("check_debug_loc")
+       .groups ("@low"));
     return cd;
   }
 
index fdb893d6034d7737dd9b44b48635c529c2fa49b9..44936642df9995f00c1643b5a32bbbbc3093f7a2 100644 (file)
@@ -43,7 +43,7 @@ namespace
     static checkdescriptor const &descriptor () {
       static std::string name
        = (std::string)"check_"
-       + section_t::descriptor ().name.substr (1);
+       + (section_t::descriptor ().name () + 1);
       static checkdescriptor cd (name.c_str ());
       return cd;
     }
index 799aa1b2e74e5a47cfa80c533027bafe22d2ecff..77e39597f987e514a27a05d9c31fcca77ac8dd0a 100644 (file)
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
-// Implements a check for:
-//  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39524
-//  (duplicate variable declaration)
-// And for:
-//  https://fedorahosted.org/pipermail/elfutils-devel/2010-July/001497.html
-//  (variable having both decl and defn in one scope)
-
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
@@ -65,7 +58,14 @@ namespace
 
   public:
     static checkdescriptor descriptor () {
-      static checkdescriptor cd ("check_duplicate_DW_tag_variable");
+      static checkdescriptor cd
+       (checkdescriptor::create ("check_duplicate_DW_tag_variable")
+        .description (
+"Implements a check for two full DW_TAG_variable DIEs with the same\n"
+"DW_AT_name value.  This covers duplicate declaration, duplicate\n"
+"definition and declaration with definition.\n"
+" https://fedorahosted.org/pipermail/elfutils-devel/2010-July/001497.html\n"
+" http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39524\n"));
       return cd;
     }
 
index 5e27e0a3f8415b190c00d85c6bb2b12846e8b1fa..c1418bea435b64994253b528becd735b594c957d 100644 (file)
 
 #include "checkdescriptor.hh"
 #include <sstream>
-
-namespace
-{
-  std::vector<std::string>
-  split_groups (std::string const &str)
-  {
-    std::stringstream ss (str);
-    std::string item;
-    std::vector<std::string> ret;
-
-    while (ss >> item)
-      ret.push_back (item);
-
-    return ret;
-  }
-}
-
-checkdescriptor::checkdescriptor (std::string const &desc)
-  : groups (::split_groups (desc))
-  , name (groups[0])
-{
-  groups.erase (groups.begin ());
-}
+#include <cassert>
 
 std::ostream &
 operator << (std::ostream &o, checkgroups const &groups)
 {
   o << '[';
-  for (std::vector<std::string>::const_iterator it = groups.begin ();
+  for (checkgroups::const_iterator it = groups.begin ();
        it != groups.end (); ++it)
     {
       if (it != groups.begin ())
@@ -63,3 +41,30 @@ operator << (std::ostream &o, checkgroups const &groups)
   o << ']';
   return o;
 }
+
+checkdescriptor::create::create (char const *a_name)
+  : name (a_name)
+  , desc (NULL)
+{}
+
+checkdescriptor::create &
+checkdescriptor::create::groups (char const *a_groups)
+{
+  std::stringstream ss (a_groups);
+  std::string group;
+  while (ss >> group)
+    g.insert (group);
+  return *this;
+}
+
+checkdescriptor::checkdescriptor (create const &c)
+  : _m_name (c.name)
+  , _m_description (c.desc)
+  , _m_groups (c.g)
+{}
+
+bool
+checkdescriptor::in_group (std::string const &group) const
+{
+  return _m_groups.find (group) != _m_groups.end ();
+}
index 45e659e27c97635a653990e16be9b8136c9cd35f..beffa3d0d1af95c7f65316adbe1c5ebc332789fc 100644 (file)
 #ifndef DWARFLINT_CHECKDESCRIPTOR_HH
 #define DWARFLINT_CHECKDESCRIPTOR_HH
 
-#include <vector>
+#include <set>
 #include <string>
 #include <iosfwd>
 
 struct checkgroups
-  : public std::vector<std::string>
-{
-  checkgroups (std::vector<std::string> const &v)
-    : std::vector<std::string> (v)
-  {}
-};
+  : public std::set<std::string>
+{};
 std::ostream &operator << (std::ostream &o, checkgroups const &groups);
 
 struct checkdescriptor
 {
-  checkgroups groups;
-  std::string const name;
+  struct create
+  {
+    checkgroups g;
+    char const *const name;
+    char const *desc;
+    create (char const *name);
+    create &groups (char const *name);
+
+    create &description (char const *d)
+    { desc = d; return *this; }
+  };
+
+  checkdescriptor (create const &c);
+
+  char const *name () const { return _m_name; }
+  char const *description () const { return _m_description; }
+
+  checkgroups const &groups () const { return _m_groups; }
+  bool in_group (std::string const &group) const;
 
-  checkdescriptor (std::string const &desc);
+private:
+  char const *const _m_name;
+  char const *const _m_description;
+  checkgroups const _m_groups;
 };
 
 #endif//DWARFLINT_CHECKDESCRIPTOR_HH
index 5d628ff6813cfa05dbc4ee4254bc3c01c23f3b9f..16b7abe13f22b25a7dbcba5b8c8ddba2a19349c8 100644 (file)
@@ -43,8 +43,8 @@ reporter::operator () (char const *what, bool ext)
     for (size_t i = 0; i < stack.size (); ++i)
       std::cout << ' ';
 
-  std::cout << cd.name << ' ' << what;
+  std::cout << cd.name () << ' ' << what;
   if (ext)
-    std::cout << ' ' << cd.groups << ' ' << stack;
+    std::cout << ' ' << cd.groups () << ' ' << stack;
   std::cout << std::endl;
 }
index b15c3f816fcce106a0ad7198a88b2be6c4407b38..419f56269177fde7bfc25631d75a7bcdfaa9ec64 100644 (file)
@@ -26,6 +26,7 @@
 #include "dwarflint.hh"
 #include "messages.h"
 #include "checks.hh"
+#include "options.h"
 
 #include <fcntl.h>
 #include <cstring>
@@ -42,7 +43,7 @@ operator << (std::ostream &o, checkstack const &stack)
     {
       if (it != stack.begin ())
        o << ',';
-      o << (*it)->name;
+      o << (*it)->name ();
     }
   o << "}";
   return o;
@@ -103,27 +104,33 @@ dwarflint::check_registrar::list_checks () const
        it != _m_items.end (); ++it)
     {
       checkdescriptor const &cd = (*it)->descriptor ();
-      std::cout << cd.name << ' ' << cd.groups << std::endl;
+      std::cout << cd.name () << ' ' << cd.groups () << std::endl;
+      if (be_verbose)
+       {
+         char const *desc = cd.description ();
+         if (desc != NULL)
+           std::cout << desc;
+         std::cout << std::endl;
+       }
     }
+  if (!be_verbose)
+    std::cout << "Use --list-checks --verbose "
+      "to get detailed description of each check." << std::endl;
 }
 
 namespace
 {
   bool
   rule_matches (std::string const &name,
-               checkdescriptor const &d)
+               checkdescriptor const &cd)
   {
     if (name == "@all")
       return true;
     if (name == "@none")
       return false;
-    if (name == d.name)
+    if (name == cd.name ())
       return true;
-    for (std::vector<std::string>::const_iterator it = d.groups.begin ();
-        it != d.groups.end (); ++it)
-      if (name == *it)
-       return true;
-    return false;
+    return cd.in_group (name);
   }
 }
 
index 0613addd0177b97e9d34ce9e5e5632e6d800a359..05070d23ac046f627f949ec11ef46e2d3fa7c394 100644 (file)
@@ -94,6 +94,9 @@ struct message_criteria warning_criteria;
 /* Accepted (warning) messages, that are turned into errors.  */
 struct message_criteria error_criteria;
 
+/* Whether to list available checks and exit.  */
+static bool just_list_checks = false;
+
 
 static error_t parse_opt (int key, char *arg, struct argp_state *state);
 
@@ -195,8 +198,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
       break;
 
     case ARGP_list_checks:
-      dwarflint::check_registrar::inst ()->list_checks ();
-      std::exit (0);
+      just_list_checks = true;
+      break;
 
     case 'i':
       tolerate_nodebug = true;
@@ -213,10 +216,14 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
       break;
 
     case ARGP_KEY_NO_ARGS:
-      fputs (gettext ("Missing file name.\n"), stderr);
-      argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
-                program_invocation_short_name);
-      exit (1);
+      if (!just_list_checks)
+       {
+         fputs (gettext ("Missing file name.\n"), stderr);
+         argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
+                    program_invocation_short_name);
+         exit (1);
+       }
+      break;
 
     default:
       return ARGP_ERR_UNKNOWN;
@@ -237,6 +244,12 @@ main (int argc, char *argv[])
   int remaining;
   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
 
+  if (just_list_checks)
+    {
+      dwarflint::check_registrar::inst ()->list_checks ();
+      std::exit (0);
+    }
+
   /* Initialize warning & error criteria.  */
   warning_criteria |= message_term (mc_none, mc_none);