From: Petr Machata Date: Fri, 27 Aug 2010 17:51:37 +0000 (+0200) Subject: dwarflint: Make checks self-documenting X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ccbe9f0ad0b2f99866f5fa342d1716e2cc03c20e;p=thirdparty%2Felfutils.git dwarflint: Make checks self-documenting --- diff --git a/dwarflint/check_debug_abbrev.hh b/dwarflint/check_debug_abbrev.hh index 4ad0d8752..cad078831 100644 --- a/dwarflint/check_debug_abbrev.hh +++ b/dwarflint/check_debug_abbrev.hh @@ -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; } diff --git a/dwarflint/check_debug_aranges.hh b/dwarflint/check_debug_aranges.hh index d787b35c1..c02e4ce73 100644 --- a/dwarflint/check_debug_aranges.hh +++ b/dwarflint/check_debug_aranges.hh @@ -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; } diff --git a/dwarflint/check_debug_line.cc b/dwarflint/check_debug_line.cc index 406e18eb5..696056ea8 100644 --- a/dwarflint/check_debug_line.cc +++ b/dwarflint/check_debug_line.cc @@ -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; } diff --git a/dwarflint/check_debug_loc_range.hh b/dwarflint/check_debug_loc_range.hh index 1c6abd79d..e352d0b99 100644 --- a/dwarflint/check_debug_loc_range.hh +++ b/dwarflint/check_debug_loc_range.hh @@ -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; } diff --git a/dwarflint/check_debug_pub.cc b/dwarflint/check_debug_pub.cc index fdb893d60..44936642d 100644 --- a/dwarflint/check_debug_pub.cc +++ b/dwarflint/check_debug_pub.cc @@ -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; } diff --git a/dwarflint/check_duplicate_DW_tag_variable.cc b/dwarflint/check_duplicate_DW_tag_variable.cc index 799aa1b2e..77e39597f 100644 --- a/dwarflint/check_duplicate_DW_tag_variable.cc +++ b/dwarflint/check_duplicate_DW_tag_variable.cc @@ -23,13 +23,6 @@ Network licensing program, please visit 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 #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; } diff --git a/dwarflint/checkdescriptor.cc b/dwarflint/checkdescriptor.cc index 5e27e0a3f..c1418bea4 100644 --- a/dwarflint/checkdescriptor.cc +++ b/dwarflint/checkdescriptor.cc @@ -25,35 +25,13 @@ #include "checkdescriptor.hh" #include - -namespace -{ - std::vector - split_groups (std::string const &str) - { - std::stringstream ss (str); - std::string item; - std::vector 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 std::ostream & operator << (std::ostream &o, checkgroups const &groups) { o << '['; - for (std::vector::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 (); +} diff --git a/dwarflint/checkdescriptor.hh b/dwarflint/checkdescriptor.hh index 45e659e27..beffa3d0d 100644 --- a/dwarflint/checkdescriptor.hh +++ b/dwarflint/checkdescriptor.hh @@ -26,25 +26,41 @@ #ifndef DWARFLINT_CHECKDESCRIPTOR_HH #define DWARFLINT_CHECKDESCRIPTOR_HH -#include +#include #include #include struct checkgroups - : public std::vector -{ - checkgroups (std::vector const &v) - : std::vector (v) - {} -}; + : public std::set +{}; 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 diff --git a/dwarflint/checks.cc b/dwarflint/checks.cc index 5d628ff68..16b7abe13 100644 --- a/dwarflint/checks.cc +++ b/dwarflint/checks.cc @@ -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; } diff --git a/dwarflint/dwarflint.cc b/dwarflint/dwarflint.cc index b15c3f816..419f56269 100644 --- a/dwarflint/dwarflint.cc +++ b/dwarflint/dwarflint.cc @@ -26,6 +26,7 @@ #include "dwarflint.hh" #include "messages.h" #include "checks.hh" +#include "options.h" #include #include @@ -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::const_iterator it = d.groups.begin (); - it != d.groups.end (); ++it) - if (name == *it) - return true; - return false; + return cd.in_group (name); } } diff --git a/dwarflint/main.cc b/dwarflint/main.cc index 0613addd0..05070d23a 100644 --- a/dwarflint/main.cc +++ b/dwarflint/main.cc @@ -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);