public:
static checkdescriptor descriptor () {
- static checkdescriptor cd ("check_debug_abbrev @low");
+ static checkdescriptor cd
+ (checkdescriptor::create ("check_debug_abbrev")
+ .groups ("@low"));
return cd;
}
public:
static checkdescriptor descriptor () {
- static checkdescriptor cd ("check_debug_aranges @low");
+ static checkdescriptor cd
+ (checkdescriptor::create ("check_debug_aranges")
+ .groups ("@low"));
return cd;
}
public:
static checkdescriptor descriptor () {
- static checkdescriptor cd ("check_debug_line @low");
+ static checkdescriptor cd
+ (checkdescriptor::create ("check_debug_line")
+ .groups ("@low"));
return cd;
}
public:
static checkdescriptor descriptor () {
- static checkdescriptor cd ("check_debug_ranges @low");
+ static checkdescriptor cd
+ (checkdescriptor::create ("check_debug_ranges")
+ .groups ("@low"));
return cd;
}
public:
static checkdescriptor descriptor () {
- static checkdescriptor cd ("check_debug_loc @low");
+ static checkdescriptor cd
+ (checkdescriptor::create ("check_debug_loc")
+ .groups ("@low"));
return cd;
}
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;
}
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
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;
}
#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 ())
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 ();
+}
#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
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;
}
#include "dwarflint.hh"
#include "messages.h"
#include "checks.hh"
+#include "options.h"
#include <fcntl.h>
#include <cstring>
{
if (it != stack.begin ())
o << ',';
- o << (*it)->name;
+ o << (*it)->name ();
}
o << "}";
return o;
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);
}
}
/* 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);
break;
case ARGP_list_checks:
- dwarflint::check_registrar::inst ()->list_checks ();
- std::exit (0);
+ just_list_checks = true;
+ break;
case 'i':
tolerate_nodebug = true;
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;
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);