+ One_option option;
+ Parse_function parse;
+};
+
+} // End namespace options.
+
+
+// These are helper macros use by DEFINE_uint64/etc below.
+// This macro is used inside the General_options_ class, so defines
+// var() and set_var() as General_options methods. Arguments as are
+// for the constructor for One_option. param_type__ is the same as
+// type__ for built-in types, and "const type__ &" otherwise.
+#define DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ default_value_as_string__, helpstring__, helparg__, \
+ optional_arg__, type__, param_type__, parse_fn__) \
+ public: \
+ param_type__ \
+ varname__() const \
+ { return this->varname__##_.value; } \
+ \
+ bool \
+ user_set_##varname__() const \
+ { return this->varname__##_.user_set_via_option; } \
+ \
+ private: \
+ struct Struct_##varname__ : public options::Struct_var \
+ { \
+ Struct_##varname__() \
+ : option(#varname__, dashes__, shortname__, default_value_as_string__, \
+ helpstring__, helparg__, optional_arg__, this), \
+ user_set_via_option(false), value(default_value__) \
+ { } \
+ \
+ void \
+ parse_to_value(const char* option_name, const char* arg, \
+ Command_line*, General_options*) \
+ { \
+ parse_fn__(option_name, arg, &this->value); \
+ this->user_set_via_option = true; \
+ } \
+ \
+ options::One_option option; \
+ bool user_set_via_option; \
+ type__ value; \
+ }; \
+ Struct_##varname__ varname__##_; \
+ void \
+ set_##varname__(param_type__ value) \
+ { this->varname__##_.value = value; }
+
+// These macros allow for easy addition of a new commandline option.
+
+// If no_helpstring__ is not NULL, then in addition to creating
+// VARNAME, we also create an option called no-VARNAME.
+#define DEFINE_bool(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, no_helpstring__) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ default_value__ ? "true" : "false", helpstring__, NULL, \
+ false, bool, bool, options::parse_bool) \
+ struct Struct_no_##varname__ : public options::Struct_var \
+ { \
+ Struct_no_##varname__() : option("no-" #varname__, dashes__, '\0', \
+ default_value__ ? "false" : "true", \
+ no_helpstring__, NULL, false, this) \
+ { } \
+ \
+ void \
+ parse_to_value(const char*, const char*, \
+ Command_line*, General_options* options) \
+ { options->set_##varname__(false); } \
+ \
+ options::One_option option; \
+ }; \
+ Struct_no_##varname__ no_##varname__##_initializer_
+
+#define DEFINE_uint(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ #default_value__, helpstring__, helparg__, false, \
+ int, int, options::parse_uint)
+
+#define DEFINE_uint64(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ #default_value__, helpstring__, helparg__, false, \
+ uint64_t, uint64_t, options::parse_uint64)
+
+#define DEFINE_double(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ #default_value__, helpstring__, helparg__, false, \
+ double, double, options::parse_double)
+
+#define DEFINE_string(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ default_value__, helpstring__, helparg__, false, \
+ const char*, const char*, options::parse_string)
+
+// This is like DEFINE_string, but we convert each occurrence to a
+// Search_directory and store it in a vector. Thus we also have the
+// add_to_VARNAME() method, to append to the vector.
+#define DEFINE_dirlist(varname__, dashes__, shortname__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, , \
+ "", helpstring__, helparg__, false, options::Dir_list, \
+ const options::Dir_list&, options::parse_dirlist) \
+ void \
+ add_to_##varname__(const char* new_value) \
+ { options::parse_dirlist(NULL, new_value, &this->varname__##_.value); } \
+ void \
+ add_search_directory_to_##varname__(const Search_directory& dir) \
+ { this->varname__##_.value.push_back(dir); }
+
+// When you have a list of possible values (expressed as string)
+// After helparg__ should come an initializer list, like
+// {"foo", "bar", "baz"}
+#define DEFINE_enum(varname__, dashes__, shortname__, default_value__, \
+ helpstring__, helparg__, ...) \
+ DEFINE_var(varname__, dashes__, shortname__, default_value__, \
+ default_value__, helpstring__, helparg__, false, \
+ const char*, const char*, parse_choices_##varname__) \
+ private: \
+ static void parse_choices_##varname__(const char* option_name, \
+ const char* arg, \
+ const char** retval) { \
+ const char* choices[] = __VA_ARGS__; \
+ options::parse_choices(option_name, arg, retval, \
+ choices, sizeof(choices) / sizeof(*choices)); \
+ }