From d70afd09bc3b902ed1662fbaaccc866c765d6040 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Thu, 23 Sep 2010 19:55:25 +0200 Subject: [PATCH] dwarflint: Show check-local options in --help - They are still not properly recognized - And name mangling isn't implemented --- dwarflint/Makefile.am | 2 +- dwarflint/checkdescriptor.cc | 1 + dwarflint/checkdescriptor.hh | 9 +++++--- dwarflint/dwarflint.cc | 18 ++++++++++------ dwarflint/dwarflint.hh | 3 +++ dwarflint/main.cc | 9 +++++--- dwarflint/option.cc | 41 +++++++++++++++++++++++++++++++++++- dwarflint/option.hh | 22 +++++++++++++++++-- 8 files changed, 89 insertions(+), 16 deletions(-) diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am index 70cae2679..e69324b60 100644 --- a/dwarflint/Makefile.am +++ b/dwarflint/Makefile.am @@ -53,7 +53,7 @@ dwarflint_SOURCES = \ main.cc \ messages.cc messages.hh \ misc.cc misc.hh \ - option.cc option.hh \ + option.cc option.hh option.ii \ pri.cc pri.hh \ readctx.c readctx.h \ reloc.cc reloc.hh \ diff --git a/dwarflint/checkdescriptor.cc b/dwarflint/checkdescriptor.cc index 3ab7a14f4..a5cecc6dd 100644 --- a/dwarflint/checkdescriptor.cc +++ b/dwarflint/checkdescriptor.cc @@ -78,6 +78,7 @@ checkdescriptor::checkdescriptor (create const &c) , _m_groups (c._m_groups) , _m_prereq (c._m_prereq) , _m_hidden (c._m_hidden) + , _m_opts (c._m_opts) {} bool diff --git a/dwarflint/checkdescriptor.hh b/dwarflint/checkdescriptor.hh index 8845e162b..c36eb0674 100644 --- a/dwarflint/checkdescriptor.hh +++ b/dwarflint/checkdescriptor.hh @@ -31,7 +31,7 @@ #include #include -#include "option.ii" +#include "option.hh" struct checkgroups : public std::set @@ -55,7 +55,7 @@ struct checkdescriptor char const *const _m_name; char const *_m_description; bool _m_hidden; - std::vector _m_opts; + options _m_opts; public: create (char const *name = NULL); @@ -79,7 +79,7 @@ struct checkdescriptor create option (option_i &opt) { - _m_opts.push_back (&opt); + _m_opts.add (&opt); return *this; } }; @@ -95,12 +95,15 @@ struct checkdescriptor bool hidden () const { return _m_hidden; } + options const &opts () const { return _m_opts; } + private: char const *const _m_name; char const *const _m_description; checkgroups const _m_groups; prereqs const _m_prereq; bool _m_hidden; + options const _m_opts; }; template diff --git a/dwarflint/dwarflint.cc b/dwarflint/dwarflint.cc index 63fd8b714..2a56a3704 100644 --- a/dwarflint/dwarflint.cc +++ b/dwarflint/dwarflint.cc @@ -119,17 +119,23 @@ namespace } } -void -dwarflint::check_registrar::list_checks () const +dwarflint::check_registrar::checkdescriptors_t +dwarflint::check_registrar::get_descriptors () const { - bool be_verbose = opt_list_checks.value () == "full"; - typedef std::set descset; - descset descriptors; + std::set descriptors; for (std::vector ::const_iterator it = _m_items.begin (); it != _m_items.end (); ++it) include (descriptors, (*it)->descriptor ()); + return checkdescriptors_t (descriptors.begin (), descriptors.end ()); +} + +void +dwarflint::check_registrar::list_checks () const +{ + bool be_verbose = opt_list_checks.value () == "full"; + checkdescriptors_t descriptors = get_descriptors (); - for (descset::const_iterator it = descriptors.begin (); + for (checkdescriptors_t::const_iterator it = descriptors.begin (); it != descriptors.end (); ++it) { checkdescriptor const &cd = **it; diff --git a/dwarflint/dwarflint.hh b/dwarflint/dwarflint.hh index 921967bd4..51e65f539 100644 --- a/dwarflint/dwarflint.hh +++ b/dwarflint/dwarflint.hh @@ -79,6 +79,9 @@ public: void list_checks () const; + typedef std::vector checkdescriptors_t; + checkdescriptors_t get_descriptors () const; + private: friend class dwarflint; void enroll (dwarflint &lint); diff --git a/dwarflint/main.cc b/dwarflint/main.cc index 268b66f8d..0c13bd0a4 100644 --- a/dwarflint/main.cc +++ b/dwarflint/main.cc @@ -152,9 +152,12 @@ main (int argc, char *argv[]) textdomain (PACKAGE_TARNAME); /* Parse and process arguments. */ - struct argp argp = global_opts.build_argp (); + argp_full args (global_opts, + dwarflint::check_registrar::inst ()->get_descriptors ()); + + int remaining; - argp_parse (&argp, argc, argv, 0, &remaining, NULL); + argp_parse (&args.get (), argc, argv, 0, &remaining, NULL); if (opt_list_checks.seen ()) { @@ -164,7 +167,7 @@ main (int argc, char *argv[]) else if (remaining == argc) { fputs (gettext ("Missing file name.\n"), stderr); - argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, + argp_help (&args.get (), stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, program_invocation_short_name); std::exit (1); } diff --git a/dwarflint/option.cc b/dwarflint/option.cc index 8a127efa8..6ac707e3e 100644 --- a/dwarflint/option.cc +++ b/dwarflint/option.cc @@ -28,6 +28,8 @@ #endif #include "option.hh" +#include "dwarflint.hh" +#include "checkdescriptor.hh" #include #include #include @@ -78,7 +80,7 @@ options::add (option_i *opt) const char *argp_program_bug_address = PACKAGE_BUGREPORT; argp -options::build_argp () +options::build_argp () const { _m_opts.clear (); for (const_iterator it = begin (); it != end (); ++it) @@ -95,6 +97,43 @@ Pedantic checking of DWARF stored in ELF files.", return a; } +argp_full::argp_full (options const &global, + std::vector checkdescriptors) +{ + argp main = global.build_argp (); + + typedef dwarflint::check_registrar::checkdescriptors_t checkdescriptors_t; + for (checkdescriptors_t::const_iterator it = checkdescriptors.begin (); + it != checkdescriptors.end (); ++it) + if (!(*it)->opts ().empty ()) + { + _m_children_argps.push_back ((*it)->opts ().build_argp ()); + _m_children_headers.push_back (std::string ("Options for ") + + (*it)->name () + + ":"); + } + + unsigned pos = 0; + for (checkdescriptors_t::const_iterator it = checkdescriptors.begin (); + it != checkdescriptors.end (); ++it) + if (!(*it)->opts ().empty ()) + { + argp_child child = {&_m_children_argps[pos], 0, + _m_children_headers[pos].c_str (), 0}; + _m_children.push_back (child); + pos++; + } + assert (_m_children_argps.size () == _m_children.size ()); + + if (!_m_children.empty ()) + { + _m_children.push_back ((argp_child){NULL, 0, NULL, 0}); + main.children = &_m_children.front (); + } + + _m_argp = main; +} + int option_i::_m_last_opt = 300; diff --git a/dwarflint/option.hh b/dwarflint/option.hh index 4c79b58ba..5f3af6f10 100644 --- a/dwarflint/option.hh +++ b/dwarflint/option.hh @@ -34,20 +34,38 @@ #include #include "option.ii" +#include "checkdescriptor.ii" class options : private std::map { friend class option_common; - std::vector _m_opts; + mutable std::vector _m_opts; option_i *find_opt (int key) const; static error_t parse_opt (int key, char *arg, argp_state *state); public: option_i const *getopt (int key) const; - argp build_argp (); + argp build_argp () const; void add (option_i *opt); + bool empty () const + { + return std::map::empty (); + } +}; + +class argp_full +{ + std::vector _m_children_argps; + std::vector _m_children_headers; + std::vector _m_children; + argp _m_argp; + +public: + argp_full (options const &global, + std::vector checkdescriptors); + argp const &get () const { return _m_argp; } }; class option_i // we cannot call it simply "option", this conflicts -- 2.47.2