#include "sections.hh"
#include "option.hh"
+static void_option ignore_missing
+ ("Don't complain if files have no DWARF at all",
+ "ignore", 'i');
+
class check_nodebug
: public check<check_nodebug>
{
static checkdescriptor cd
(checkdescriptor::create ("check_nodebug")
.groups ("@low")
+ .option (ignore_missing)
.description (
"Checks that there are at least essential debuginfo sections present\n"
"in the ELF file.\n"));
};
static reg<check_nodebug> reg_nodebug;
-static void_option ignore_missing
- ("Don't complain if files have no DWARF at all",
- "ignore-missing", 'i');
check_nodebug::check_nodebug (checkstack &stack, dwarflint &lint)
{
#include <set>
#include <string>
#include <iosfwd>
+#include <vector>
+
+#include "option.ii"
struct checkgroups
: public std::set<std::string>
char const *const _m_name;
char const *_m_description;
bool _m_hidden;
+ std::vector<option_i *> _m_opts;
public:
create (char const *name = NULL);
_m_hidden = true;
return *this;
}
+
+ create option (option_i &opt)
+ {
+ _m_opts.push_back (&opt);
+ return *this;
+ }
};
checkdescriptor (create const &c);
#include "checks.hh"
#include "option.hh"
-static void_option show_progress
+static global_opt<void_option> show_progress
("Print out checks as they are performed, their context and result.",
"show-progress");
namespace
{
+
+#define DIE_OPTSTRING \
+ "{single-addr|artificial|inlined|inlined_subroutine\
+|no-coverage|mutable|immutable}[,...]"
+
+ string_option opt_ignore
+ ("Skip certain DIEs.", DIE_OPTSTRING, "ignore");
+
+ string_option opt_dump
+ ("Dump certain DIEs.", DIE_OPTSTRING, "dump");
+
+ string_option opt_tabulation_rule
+ ("Rule for sorting results into buckets. start is either integer 0..100, \
+or special value 0.0 indicating cases with no coverage whatsoever \
+(i.e. not those that happen to round to 0%).",
+ "start[:step][,...]",
+ "tabulate");
+
class locstats
: public highlevel_check<locstats>
{
static checkdescriptor cd
(checkdescriptor::create ("locstats")
.groups ("@nodefault")
+ .option (opt_ignore)
+ .option (opt_dump)
+ .option (opt_tabulation_rule)
.description (
"Computes a location info coverage statistics. Goes through the whole\n"
"DIE graph, looking at each variable and formal parameter, and\n"
TYPE(mutable) \
TYPE(immutable)
- string_option opt_ignore
- ("Skip certain DIEs.",
- "{single-addr|artificial|inlined|inlined_subroutine\
-|no-coverage|mutable|immutable}[,...]",
- "locstats:ignore");
-
- string_option opt_dump
- ("Dump certain DIEs.",
- "{single-addr|artificial|inlined|inlined_subroutine\
-|no-coverage|mutable|immutable}[,...]",
- "locstats:dump");
-
- string_option opt_tabulation_rule
- ("Rule for sorting results into buckets. start is either integer 0..100, \
-or special value 0.0 indicating cases with no coverage whatsoever \
-(i.e. not those that happen to round to 0%).",
- "start[:step][,...]",
- "locstats:tabulate");
-
struct tabrule
{
int start;
for (int i = 0; i <= 100; ++i)
tally[i] = 0;
- tabrules_t tabrules (opt_tabulation_rule.seen ()
- ? opt_tabulation_rule.value () : "10:10");
- die_type_matcher ignore (opt_ignore.seen () ? opt_ignore.value () : "");
- die_type_matcher dump (opt_dump.seen () ? opt_dump.value () : "");
+ tabrules_t tabrules (/*opt_tabulation_rule.seen ()
+ ? opt_tabulation_rule.value () :*/ "10:10");
+ die_type_matcher ignore (/*opt_ignore.seen () ? opt_ignore.value () :*/ "");
+ die_type_matcher dump (/*opt_dump.seen () ? opt_dump.value () :*/ "");
std::bitset<dt__count> interested = ignore | dump;
bool interested_mutability
= interested.test (dt_mutable) || interested.test (dt_immutable);
struct message_criteria error_criteria;
struct check_option_t
- : public option_common
+ : public global_opt<option_common>
{
struct initial_checkrules
: public checkrules
} rules;
check_option_t ()
- : option_common ("Only run selected checks.",
- "[+-][@]name,...", "check", 0)
+ : global_opt<option_common> ("Only run selected checks.",
+ "[+-][@]name,...", "check", 0)
{}
error_t parse_opt (char *arg, __attribute__ ((unused)) argp_state *state)
}
} check_option;
-void_option be_quiet ("Do not print anything if successful",
- "quiet", 'q');
+global_opt<void_option>
+ be_quiet ("Do not print anything if successful",
+ "quiet", 'q');
-string_option opt_list_checks ("List all the available checks.",
- "full", "list-checks", 0,
- OPTION_ARG_OPTIONAL);
+global_opt<string_option>
+ opt_list_checks ("List all the available checks.",
+ "full", "list-checks", 0,
+ OPTION_ARG_OPTIONAL);
// xxx The following three should go away when we introduce the
// message filtering. Or should be preserved, but in a way that makes
// more sense, right now they are simply a misnomer.
-void_option ignore_bloat ("Ignore messages related to bloat.", "ignore-bloat");
-void_option be_strict ("Be somewhat stricter.", "strict");
-void_option be_tolerant ("Be somewhat more tolerant.", "tolerant");
+global_opt<void_option>
+ ignore_bloat ("Ignore messages related to bloat.", "ignore-bloat");
+global_opt<void_option>
+ be_strict ("Be somewhat stricter.", "strict");
+global_opt<void_option>
+ be_tolerant ("Be somewhat more tolerant.", "tolerant");
// xxx as soon as where is in c++, this can move there
-void_option opt_show_refs = void_option (
-"When validating .debug_loc and .debug_ranges, display information about \
+global_opt<void_option>
+ opt_show_refs("\
+When validating .debug_loc and .debug_ranges, display information about \
the DIE referring to the entry in consideration", "ref");
extern "C" bool show_refs () { return (bool)opt_show_refs; }
textdomain (PACKAGE_TARNAME);
/* Parse and process arguments. */
- struct argp argp = options::registered ().build_argp ();
+ struct argp argp = global_opts.build_argp ();
int remaining;
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
#include <cstring>
#include <iostream>
-option_common *
-options::opt (int key) const
+option_i *
+options::find_opt (int key) const
{
const_iterator it = find (key);
if (it == end ())
return it->second;
}
-option_common const *
+option_i const *
options::getopt (int key) const
{
- return opt (key);
+ return find_opt (key);
}
error_t
options::parse_opt (int key, char *arg,
__attribute__ ((unused)) argp_state *state)
{
- option_common *o = registered ().opt (key);
+ option_i *o = global_opts.find_opt (key); // XXX temporary
if (o == NULL)
return ARGP_ERR_UNKNOWN;
return o->parse_opt (arg, state);
struct last_option
: public argp_option
{
- last_option () {
+ last_option ()
+ {
std::memset (this, 0, sizeof (*this));
}
};
+void
+options::add (option_i *opt)
+{
+ int key = opt->key ();
+ assert (getopt (key) == NULL);
+ (*this)[key] = opt;
+}
+
/* Bug report address. */
const char *argp_program_bug_address = PACKAGE_BUGREPORT;
}
-int option_common::_m_last_opt = 300;
-
-options &
-options::registered ()
-{
- static options opts;
- return opts;
-}
+int option_i::_m_last_opt = 300;
int
-option_common::get_short_option (char opt_short)
+option_i::get_short_option (char opt_short)
{
if (opt_short)
return opt_short;
arg_description, flags,
description, 0))
, _m_seen (false)
-{
- assert (options::registered ().getopt (_m_opt.key) == NULL);
- options::registered ()[_m_opt.key] = this;
-}
+{}
+
+options global_opts;
#include <map>
#include <vector>
#include <cassert>
-
#include <iostream>
-class option_common;
+#include "option.ii"
class options
- : private std::map<int, option_common *>
+ : private std::map<int, option_i *>
{
friend class option_common;
std::vector<argp_option> _m_opts;
- option_common *opt (int key) const;
+ option_i *find_opt (int key) const;
static error_t parse_opt (int key, char *arg, argp_state *state);
public:
- static options ®istered ();
- option_common const *getopt (int key) const;
+ option_i const *getopt (int key) const;
argp build_argp ();
+ void add (option_i *opt);
};
-class option_common
+class option_i // we cannot call it simply "option", this conflicts
+ // with another global declaration
{
- argp_option _m_opt;
-
+ // last allocated option unique identifier
static int _m_last_opt;
+
+protected:
+ // Answer either opt_short argument if it's non-0. Otherwise create
+ // new unique identifier.
static int get_short_option (char opt_short);
+public:
+ virtual bool seen () const = 0;
+ virtual argp_option const &build_option () const = 0;
+ virtual error_t parse_opt (char *arg, argp_state *state) = 0;
+ virtual int key () const = 0;
+ virtual ~option_i () {}
+};
+
+class option_common
+ : public option_i
+{
+ argp_option _m_opt;
+
protected:
bool _m_seen;
char const *opt_long, char opt_short,
int flags = 0);
-public: // consumer interface
- bool seen () const { return _m_seen; }
+public:
+ bool
+ seen () const
+ {
+ return _m_seen;
+ }
-public: // option handler interface
- argp_option const &build_option () const { return _m_opt; }
- virtual error_t parse_opt (char *arg, argp_state *state) = 0;
+ argp_option const &
+ build_option () const
+ {
+ return _m_opt;
+ }
+
+ int
+ key () const
+ {
+ return _m_opt.key;
+ }
};
template<class arg_type>
typedef xoption<void> void_option;
typedef xoption<std::string> string_option;
+extern options global_opts;
+
+template<class OPT>
+struct global_opt
+ : public OPT
+{
+ template<typename... Args>
+ global_opt (Args const&... args)
+ : OPT (args...)
+ {
+ global_opts.add (this);
+ }
+};
+
#endif//DWARFLINT_OPTION_HH
--- /dev/null
+class option_i;