]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Show check-local options in --help
authorPetr Machata <pmachata@redhat.com>
Thu, 23 Sep 2010 17:55:25 +0000 (19:55 +0200)
committerPetr Machata <pmachata@redhat.com>
Thu, 23 Sep 2010 17:55:25 +0000 (19:55 +0200)
- They are still not properly recognized
- And name mangling isn't implemented

dwarflint/Makefile.am
dwarflint/checkdescriptor.cc
dwarflint/checkdescriptor.hh
dwarflint/dwarflint.cc
dwarflint/dwarflint.hh
dwarflint/main.cc
dwarflint/option.cc
dwarflint/option.hh

index 70cae267990b0be413c45ad057d29799e57a14c0..e69324b6011bfad21e939c73b5f14b24adcf2164 100644 (file)
@@ -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 \
index 3ab7a14f46bea65cecd5428875ad01f3e419b55f..a5cecc6dd8ca8a561c11400f501ee93150af35db 100644 (file)
@@ -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
index 8845e162b5a4c5da6bd97a92fa321e66abf2fe2a..c36eb06749907ec6748619b7c6aa9b30121b9213 100644 (file)
@@ -31,7 +31,7 @@
 #include <iosfwd>
 #include <vector>
 
-#include "option.ii"
+#include "option.hh"
 
 struct checkgroups
   : public std::set<std::string>
@@ -55,7 +55,7 @@ struct checkdescriptor
     char const *const _m_name;
     char const *_m_description;
     bool _m_hidden;
-    std::vector<option_i *> _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 <class T>
index 63fd8b714d7c6baca0e7dfb6f6abfb0df9d5a572..2a56a370457e757b14b0839c6f6b7c97b90e6108 100644 (file)
@@ -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<checkdescriptor const *> descset;
-  descset descriptors;
+  std::set<checkdescriptor const *> descriptors;
   for (std::vector <item *>::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;
index 921967bd43e4dab3eaadd6e5caae032762b3fc12..51e65f539862fcc37e77d0ced7085d82faa0cca1 100644 (file)
@@ -79,6 +79,9 @@ public:
 
     void list_checks () const;
 
+    typedef std::vector<checkdescriptor const *> checkdescriptors_t;
+    checkdescriptors_t get_descriptors () const;
+
   private:
     friend class dwarflint;
     void enroll (dwarflint &lint);
index 268b66f8d60ab9fd5fa5456840bb76e2184f6a7a..0c13bd0a42f81359d855f9227d6c17d9cf65bd74 100644 (file)
@@ -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);
     }
index 8a127efa8a3800e595ffc7b218ca3224f7cafcf6..6ac707e3ec8e9963deb043c5599cfc90a480334a 100644 (file)
@@ -28,6 +28,8 @@
 #endif
 
 #include "option.hh"
+#include "dwarflint.hh"
+#include "checkdescriptor.hh"
 #include <cassert>
 #include <cstring>
 #include <iostream>
@@ -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<checkdescriptor const *> 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;
 
index 4c79b58ba57bdd2a8e095872558ec084c86f2026..5f3af6f1072bd1c3e74e5c5691ba2f734511b34d 100644 (file)
 #include <iostream>
 
 #include "option.ii"
+#include "checkdescriptor.ii"
 
 class options
   : private std::map<int, option_i *>
 {
   friend class option_common;
-  std::vector<argp_option> _m_opts;
+  mutable std::vector<argp_option> _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<int, option_i *>::empty ();
+  }
+};
+
+class argp_full
+{
+  std::vector<argp> _m_children_argps;
+  std::vector<std::string> _m_children_headers;
+  std::vector<argp_child> _m_children;
+  argp _m_argp;
+
+public:
+  argp_full (options const &global,
+            std::vector<checkdescriptor const *> checkdescriptors);
+  argp const &get () const { return _m_argp; }
 };
 
 class option_i // we cannot call it simply "option", this conflicts