diff options
author | Murray Cumming <murrayc@murrayc.com> | 2016-02-26 22:46:55 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2016-02-26 22:46:55 +0100 |
commit | e1eb5c1d651a8906074feda2d2a0ad103e838949 (patch) | |
tree | e387d5498d9c2dd53170126b3497b28c25c5d47a /glib/src/optiongroup.ccg | |
parent | dc111022570a417f396b81cdaef1a5db58022017 (diff) | |
download | glibmm-e1eb5c1d651a8906074feda2d2a0ad103e838949.tar.gz |
Run clang-format on the .ccg files.
This seems to work.
Diffstat (limited to 'glib/src/optiongroup.ccg')
-rw-r--r-- | glib/src/optiongroup.ccg | 792 |
1 files changed, 411 insertions, 381 deletions
diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg index 56236e4d..20f3ae15 100644 --- a/glib/src/optiongroup.ccg +++ b/glib/src/optiongroup.ccg @@ -26,30 +26,29 @@ namespace Glib { -namespace //anonymous +namespace // anonymous { -//A pointer to an OptionArgCallback instance is stored in CppOptionEntry::cpparg_ -//when a callback function shall parse the command option's value. +// A pointer to an OptionArgCallback instance is stored in CppOptionEntry::cpparg_ +// when a callback function shall parse the command option's value. class OptionArgCallback { public: explicit OptionArgCallback(const OptionGroup::SlotOptionArgString& slot) : slot_string_(new OptionGroup::SlotOptionArgString(slot)), slot_filename_(nullptr) - { } + { + } explicit OptionArgCallback(const OptionGroup::SlotOptionArgFilename& slot) : slot_string_(nullptr), slot_filename_(new OptionGroup::SlotOptionArgFilename(slot)) - { } + { + } - bool is_filename_option() const - { return slot_filename_ != nullptr; } + bool is_filename_option() const { return slot_filename_ != nullptr; } - const OptionGroup::SlotOptionArgString* get_slot_string() const - { return slot_string_; } + const OptionGroup::SlotOptionArgString* get_slot_string() const { return slot_string_; } - const OptionGroup::SlotOptionArgFilename* get_slot_filename() const - { return slot_filename_; } + const OptionGroup::SlotOptionArgFilename* get_slot_filename() const { return slot_filename_; } ~OptionArgCallback() { @@ -58,28 +57,29 @@ public: } private: - //One of these slot pointers is 0 and the other one points to a slot. + // One of these slot pointers is 0 and the other one points to a slot. OptionGroup::SlotOptionArgString* slot_string_; OptionGroup::SlotOptionArgFilename* slot_filename_; - //Not copyable + // Not copyable OptionArgCallback(const OptionArgCallback&); OptionArgCallback& operator=(const OptionArgCallback&); }; -extern "C" -{ +extern "C" { -static gboolean g_callback_pre_parse(GOptionContext* context, - GOptionGroup* /* group */, gpointer data, GError** error) +static gboolean +g_callback_pre_parse( + GOptionContext* context, GOptionGroup* /* group */, gpointer data, GError** error) { OptionContext cppContext(context, false /* take_ownership */); auto option_group = static_cast<OptionGroup*>(data); - if(!option_group) + if (!option_group) { OptionError(OptionError::FAILED, "Glib::OptionGroup: g_callback_pre_parse(): " - "No OptionGroup pointer available").propagate(error); + "No OptionGroup pointer available") + .propagate(error); return false; } @@ -87,19 +87,20 @@ static gboolean g_callback_pre_parse(GOptionContext* context, { return option_group->on_pre_parse(cppContext, *option_group); } - catch(Glib::Error& err) + catch (Glib::Error& err) { err.propagate(error); } - catch(...) + catch (...) { Glib::exception_handlers_invoke(); } return false; } -static void g_callback_error(GOptionContext* context, - GOptionGroup* /* group */, gpointer data, GError** /* TODO error */) +static void +g_callback_error( + GOptionContext* context, GOptionGroup* /* group */, gpointer data, GError** /* TODO error */) { // TODO GError** error is input data containing information on an error that // has occurred before this function is called. When API can be broken, @@ -109,22 +110,21 @@ static void g_callback_error(GOptionContext* context, OptionContext cppContext(context, false /* take_ownership */); auto option_group = static_cast<OptionGroup*>(data); - if(option_group) + if (option_group) return option_group->on_error(cppContext, *option_group); } -const gchar* OptionGroup_Translate_glibmm_callback(const gchar* string, - gpointer data) +const gchar* +OptionGroup_Translate_glibmm_callback(const gchar* string, gpointer data) { - Glib::OptionGroup::SlotTranslate* the_slot = - static_cast<Glib::OptionGroup::SlotTranslate*>(data); + Glib::OptionGroup::SlotTranslate* the_slot = static_cast<Glib::OptionGroup::SlotTranslate*>(data); try { // The C docs says that the char* belongs to Glib. return g_strdup((*the_slot)(Glib::ustring(string)).c_str()); } - catch(...) + catch (...) { Glib::exception_handlers_invoke(); } @@ -132,32 +132,35 @@ const gchar* OptionGroup_Translate_glibmm_callback(const gchar* string, return nullptr; } -static void OptionGroup_Translate_glibmm_callback_destroy(void* data) +static void +OptionGroup_Translate_glibmm_callback_destroy(void* data) { delete static_cast<Glib::OptionGroup::SlotTranslate*>(data); } } /* extern "C" */ -} //anonymous namespace +} // anonymous namespace -//static -gboolean OptionGroup::post_parse_callback(GOptionContext* context, - GOptionGroup* /* group */, gpointer data, GError** error) +// static +gboolean +OptionGroup::post_parse_callback( + GOptionContext* context, GOptionGroup* /* group */, gpointer data, GError** error) { OptionContext cppContext(context, false /* take_ownership */); OptionGroup* option_group = static_cast<OptionGroup*>(data); - if(!option_group) + if (!option_group) { OptionError(OptionError::FAILED, "Glib::OptionGroup::post_parse_callback(): " - "No OptionGroup pointer available").propagate(error); + "No OptionGroup pointer available") + .propagate(error); return false; } - //The C args have now been given values by g_option_context_parse(). - //Convert C values to C++ values: - for(auto& the_pair : option_group->map_entries_) + // The C args have now been given values by g_option_context_parse(). + // Convert C values to C++ values: + for (auto& the_pair : option_group->map_entries_) { auto& cpp_entry = the_pair.second; cpp_entry.convert_c_to_cpp(); @@ -167,57 +170,61 @@ gboolean OptionGroup::post_parse_callback(GOptionContext* context, { return option_group->on_post_parse(cppContext, *option_group); } - catch(Glib::Error& err) + catch (Glib::Error& err) { err.propagate(error); } - catch(...) + catch (...) { Glib::exception_handlers_invoke(); } return false; } -//static -gboolean OptionGroup::option_arg_callback(const gchar* option_name, const gchar* value, - gpointer data, GError** error) +// static +gboolean +OptionGroup::option_arg_callback( + const gchar* option_name, const gchar* value, gpointer data, GError** error) { const Glib::ustring cpp_option_name(option_name); const OptionGroup* const option_group = static_cast<const OptionGroup*>(data); - if(!option_group) + if (!option_group) { OptionError(OptionError::FAILED, "Glib::OptionGroup::option_arg_callback(): " - "No OptionGroup pointer available for option " + cpp_option_name).propagate(error); + "No OptionGroup pointer available for option " + + cpp_option_name) + .propagate(error); return false; } - //option_name is either a single dash followed by a single letter (for a - //short name) or two dashes followed by a long option name. + // option_name is either a single dash followed by a single letter (for a + // short name) or two dashes followed by a long option name. OptionGroup::type_map_entries::const_iterator iterFind = option_group->map_entries_.end(); - if(option_name[1] == '-') + if (option_name[1] == '-') { - //Long option name. - const auto long_option_name = Glib::ustring(option_name+2); + // Long option name. + const auto long_option_name = Glib::ustring(option_name + 2); iterFind = option_group->map_entries_.find(long_option_name); } else { - //Short option name. + // Short option name. const auto short_option_name = option_name[1]; - for(iterFind = option_group->map_entries_.begin(); - iterFind != option_group->map_entries_.end(); ++iterFind) + for (iterFind = option_group->map_entries_.begin(); + iterFind != option_group->map_entries_.end(); ++iterFind) { const auto& cppOptionEntry = iterFind->second; - if (cppOptionEntry.entry_ && - cppOptionEntry.entry_->get_short_name() == short_option_name) + if (cppOptionEntry.entry_ && cppOptionEntry.entry_->get_short_name() == short_option_name) break; } } - if(iterFind == option_group->map_entries_.end()) + if (iterFind == option_group->map_entries_.end()) { OptionError(OptionError::UNKNOWN_OPTION, "Glib::OptionGroup::option_arg_callback(): " - "Unknown option " + cpp_option_name).propagate(error); + "Unknown option " + + cpp_option_name) + .propagate(error); return false; } @@ -225,7 +232,9 @@ gboolean OptionGroup::option_arg_callback(const gchar* option_name, const gchar* if (cppOptionEntry.carg_type_ != G_OPTION_ARG_CALLBACK) { OptionError(OptionError::FAILED, "Glib::OptionGroup::option_arg_callback() " - "called for non-callback option " + cpp_option_name).propagate(error); + "called for non-callback option " + + cpp_option_name) + .propagate(error); return false; } @@ -247,50 +256,50 @@ gboolean OptionGroup::option_arg_callback(const gchar* option_name, const gchar* return (*the_slot)(cpp_option_name, cpp_value, has_value); } } - catch(Glib::Error& err) + catch (Glib::Error& err) { err.propagate(error); } - catch(...) + catch (...) { Glib::exception_handlers_invoke(); } return false; } -OptionGroup::OptionGroup(const Glib::ustring& name, const Glib::ustring& description, const Glib::ustring& help_description) -: gobject_( g_option_group_new(name.c_str(), description.c_str(), help_description.c_str(), - this /* user_data */, nullptr /* destroy_func */) ), +OptionGroup::OptionGroup(const Glib::ustring& name, const Glib::ustring& description, + const Glib::ustring& help_description) +: gobject_(g_option_group_new(name.c_str(), description.c_str(), help_description.c_str(), + this /* user_data */, nullptr /* destroy_func */)), has_ownership_(true) { - //g_callback_pre_parse(), post_parse_callback(), g_callback_error(), and - //option_arg_callback() depend on user_data being this. The first three - //functions get a GOptionGroup*, but it would not be correct to use it for - //creating a new OptionGroup. They must call their virtual functions in the - //original OptionGroup instance. + // g_callback_pre_parse(), post_parse_callback(), g_callback_error(), and + // option_arg_callback() depend on user_data being this. The first three + // functions get a GOptionGroup*, but it would not be correct to use it for + // creating a new OptionGroup. They must call their virtual functions in the + // original OptionGroup instance. - //Connect callbacks, so that derived classes can override the virtual methods: + // Connect callbacks, so that derived classes can override the virtual methods: g_option_group_set_parse_hooks(gobj(), &g_callback_pre_parse, &post_parse_callback); g_option_group_set_error_hook(gobj(), &g_callback_error); } -OptionGroup::OptionGroup(GOptionGroup* castitem) -: gobject_(castitem), - has_ownership_(true) +OptionGroup::OptionGroup(GOptionGroup* castitem) : gobject_(castitem), has_ownership_(true) { - //Always takes ownership - never takes copy. + // Always takes ownership - never takes copy. } OptionGroup::OptionGroup(OptionGroup&& other) noexcept -: map_entries_(std::move(other.map_entries_)), - gobject_(std::move(other.gobject_)), - has_ownership_(std::move(other.has_ownership_)) + : map_entries_(std::move(other.map_entries_)), + gobject_(std::move(other.gobject_)), + has_ownership_(std::move(other.has_ownership_)) { other.gobject_ = nullptr; other.has_ownership_ = false; } -OptionGroup& OptionGroup::operator=(OptionGroup&& other) noexcept +OptionGroup& +OptionGroup::operator=(OptionGroup&& other) noexcept { release_gobject(); @@ -304,16 +313,17 @@ OptionGroup& OptionGroup::operator=(OptionGroup&& other) noexcept return *this; } -void OptionGroup::release_gobject() noexcept +void +OptionGroup::release_gobject() noexcept { - //Free any C types that were allocated during add_entry(): - for(auto& the_pair : map_entries_) + // Free any C types that were allocated during add_entry(): + for (auto& the_pair : map_entries_) { auto& cpp_entry = the_pair.second; cpp_entry.release_c_arg(); } - if(has_ownership_ && gobject_) + if (has_ownership_ && gobject_) { g_option_group_unref(gobj()); gobject_ = nullptr; @@ -325,52 +335,63 @@ OptionGroup::~OptionGroup() release_gobject(); } -void OptionGroup::add_entry(const OptionEntry& entry) +void +OptionGroup::add_entry(const OptionEntry& entry) { - //It does not copy the entry, so it needs to live as long as the group. + // It does not copy the entry, so it needs to live as long as the group. - //g_option_group_add_entries takes an array, with the last item in the array having a null long_name. - //Hopefully this will be properly documented eventually - see bug # + // g_option_group_add_entries takes an array, with the last item in the array having a null + // long_name. + // Hopefully this will be properly documented eventually - see bug # - //Create a temporary array, just so we can give the correct thing to g_option_group_add_entries: + // Create a temporary array, just so we can give the correct thing to g_option_group_add_entries: GOptionEntry array[2]; - array[0] = *(entry.gobj()); //Copy contents. + array[0] = *(entry.gobj()); // Copy contents. std::memset(&array[1], 0, sizeof(GOptionEntry)); g_option_group_add_entries(gobj(), array); } -void OptionGroup::add_entry(const OptionEntry& entry, bool& arg) +void +OptionGroup::add_entry(const OptionEntry& entry, bool& arg) { - add_entry_with_wrapper(entry, G_OPTION_ARG_NONE /* Actually a boolean on/off, depending on whether the argument name was given, without argument parameters. */, &arg); + add_entry_with_wrapper(entry, + G_OPTION_ARG_NONE /* Actually a boolean on/off, depending on whether the argument name was given, without argument parameters. */, + &arg); } -void OptionGroup::add_entry(const OptionEntry& entry, int& arg) +void +OptionGroup::add_entry(const OptionEntry& entry, int& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_INT, &arg); } -void OptionGroup::add_entry(const OptionEntry& entry, double& arg) +void +OptionGroup::add_entry(const OptionEntry& entry, double& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_DOUBLE, &arg); } -void OptionGroup::add_entry(const OptionEntry& entry, Glib::ustring& arg) +void +OptionGroup::add_entry(const OptionEntry& entry, Glib::ustring& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_STRING, &arg); } -void OptionGroup::add_entry(const OptionEntry& entry, vecustrings& arg) +void +OptionGroup::add_entry(const OptionEntry& entry, vecustrings& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_STRING_ARRAY, &arg); } -void OptionGroup::add_entry_filename(const OptionEntry& entry, std::string& arg) +void +OptionGroup::add_entry_filename(const OptionEntry& entry, std::string& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_FILENAME, &arg); } -void OptionGroup::add_entry_filename(const OptionEntry& entry, vecstrings& arg) +void +OptionGroup::add_entry_filename(const OptionEntry& entry, vecstrings& arg) { add_entry_with_wrapper(entry, G_OPTION_ARG_FILENAME_ARRAY, &arg); } @@ -387,28 +408,31 @@ void OptionGroup::add_entry_filename(const OptionEntry& entry, vecstrings& arg) // with G_OPTION_FLAG_FILENAME. We do this automatiically in set_c_arg_default(). // Other option flags are set by OptionEntry::set_flags(). -void OptionGroup::add_entry(const OptionEntry& entry, const SlotOptionArgString& slot) +void +OptionGroup::add_entry(const OptionEntry& entry, const SlotOptionArgString& slot) { - //The OptionArgCallback is deleted in release_c_arg(). + // The OptionArgCallback is deleted in release_c_arg(). add_entry_with_wrapper(entry, G_OPTION_ARG_CALLBACK, new OptionArgCallback(slot)); } -void OptionGroup::add_entry_filename(const OptionEntry& entry, const SlotOptionArgFilename& slot) +void +OptionGroup::add_entry_filename(const OptionEntry& entry, const SlotOptionArgFilename& slot) { - //The OptionArgCallback is deleted in release_c_arg(). + // The OptionArgCallback is deleted in release_c_arg(). add_entry_with_wrapper(entry, G_OPTION_ARG_CALLBACK, new OptionArgCallback(slot)); } -void OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg arg_type, void* cpp_arg) +void +OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg arg_type, void* cpp_arg) { const auto name = entry.get_long_name(); type_map_entries::iterator iterFind = map_entries_.find(name); - if (iterFind == map_entries_.end()) //If we have not added this entry already + if (iterFind == map_entries_.end()) // If we have not added this entry already { CppOptionEntry cppEntry; - //g_option_group_add_entry() does not take its own copy, so we must keep the instance alive. + // g_option_group_add_entry() does not take its own copy, so we must keep the instance alive. cppEntry.entry_ = new OptionEntry(entry); - //cppEntry.entry_ is deleted in release_c_arg(), via the destructor. + // cppEntry.entry_ is deleted in release_c_arg(), via the destructor. // Several options can refer to the same C++ variable, // typically a pair of --enable-x / --disable-x options. @@ -418,13 +442,11 @@ void OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg ar void* carg = nullptr; if (arg_type != G_OPTION_ARG_CALLBACK) { - for (type_map_entries::iterator iter = map_entries_.begin(); - iter != map_entries_.end(); ++iter) + for (type_map_entries::iterator iter = map_entries_.begin(); iter != map_entries_.end(); + ++iter) { const auto& cpp_entry = iter->second; - if (cpp_entry.cpparg_ == cpp_arg && - cpp_entry.carg_type_ == arg_type && - cpp_entry.carg_) + if (cpp_entry.cpparg_ == cpp_arg && cpp_entry.carg_type_ == arg_type && cpp_entry.carg_) { is_duplicate = true; carg = cpp_entry.carg_; @@ -442,386 +464,394 @@ void OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg ar } cppEntry.cpparg_ = cpp_arg; - //Give the information to the C API: + // Give the information to the C API: cppEntry.entry_->gobj()->arg = arg_type; cppEntry.entry_->gobj()->arg_data = carg; - //Remember the C++/C mapping so that we can use it later: + // Remember the C++/C mapping so that we can use it later: map_entries_[name] = cppEntry; add_entry(*(cppEntry.entry_)); } else if (arg_type == G_OPTION_ARG_CALLBACK) { - //Delete the OptionArgCallback instance that was allocated by add_entry() - //or add_entry_filename(). + // Delete the OptionArgCallback instance that was allocated by add_entry() + // or add_entry_filename(). auto option_arg = static_cast<OptionArgCallback*>(cpp_arg); delete option_arg; } } - -bool OptionGroup::on_pre_parse(OptionContext& /* context */, OptionGroup& /* group */) +bool +OptionGroup::on_pre_parse(OptionContext& /* context */, OptionGroup& /* group */) { return true; } -bool OptionGroup::on_post_parse(OptionContext& /* context */, OptionGroup& /* group */) +bool +OptionGroup::on_post_parse(OptionContext& /* context */, OptionGroup& /* group */) { return true; } -void OptionGroup::on_error(OptionContext& /* context */, OptionGroup& /* group */) +void +OptionGroup::on_error(OptionContext& /* context */, OptionGroup& /* group */) { } -void OptionGroup::set_translate_func(const SlotTranslate& slot) +void +OptionGroup::set_translate_func(const SlotTranslate& slot) { // Create a copy of the slot. A pointer to this will be passed through the // callback's data parameter. It will be deleted when // OptionGroup_Translate_glibmm_callback_destroy() is called. auto slot_copy = new SlotTranslate(slot); - g_option_group_set_translate_func(gobj(), - &OptionGroup_Translate_glibmm_callback, slot_copy, + g_option_group_set_translate_func(gobj(), &OptionGroup_Translate_glibmm_callback, slot_copy, &OptionGroup_Translate_glibmm_callback_destroy); } - OptionGroup::CppOptionEntry::CppOptionEntry() : carg_type_(G_OPTION_ARG_NONE), carg_(nullptr), cpparg_(nullptr), entry_(nullptr) -{} +{ +} -void OptionGroup::CppOptionEntry::allocate_c_arg() +void +OptionGroup::CppOptionEntry::allocate_c_arg() { - //Create an instance of the appropriate C type. - //This will be destroyed in the OptionGroup destructor. + // Create an instance of the appropriate C type. + // This will be destroyed in the OptionGroup destructor. // - //We must also call set_c_arg_default() to give these C types the specified - //defaults based on the C++-typed arguments. - switch(carg_type_) + // We must also call set_c_arg_default() to give these C types the specified + // defaults based on the C++-typed arguments. + switch (carg_type_) { - case G_OPTION_ARG_STRING: //The char* will be for UTF8 a string. - case G_OPTION_ARG_FILENAME: //The char* will be for a string in the current locale's encoding. - { - char** typed_arg = new char*; - //The C code will allocate a char* and put it here, for us to g_free() later. - *typed_arg = nullptr; - carg_ = typed_arg; + case G_OPTION_ARG_STRING: // The char* will be for UTF8 a string. + case G_OPTION_ARG_FILENAME: // The char* will be for a string in the current locale's encoding. + { + char** typed_arg = new char*; + // The C code will allocate a char* and put it here, for us to g_free() later. + *typed_arg = nullptr; + carg_ = typed_arg; - break; - } - case G_OPTION_ARG_INT: - { - int* typed_arg = new int; - *typed_arg = 0; - carg_ = typed_arg; + break; + } + case G_OPTION_ARG_INT: + { + int* typed_arg = new int; + *typed_arg = 0; + carg_ = typed_arg; - break; - } - case G_OPTION_ARG_DOUBLE: - { - double* typed_arg = new double; - *typed_arg = 0.0; - carg_ = typed_arg; + break; + } + case G_OPTION_ARG_DOUBLE: + { + double* typed_arg = new double; + *typed_arg = 0.0; + carg_ = typed_arg; - break; - } - case G_OPTION_ARG_STRING_ARRAY: - case G_OPTION_ARG_FILENAME_ARRAY: - { - char*** typed_arg = new char**; - //The C code will allocate a char** and put it here, for us to g_strfreev() later. - *typed_arg = nullptr; - carg_ = typed_arg; + break; + } + case G_OPTION_ARG_STRING_ARRAY: + case G_OPTION_ARG_FILENAME_ARRAY: + { + char*** typed_arg = new char**; + // The C code will allocate a char** and put it here, for us to g_strfreev() later. + *typed_arg = nullptr; + carg_ = typed_arg; - break; - } - case G_OPTION_ARG_NONE: // Actually a boolean. - { - gboolean* typed_arg = new gboolean; - *typed_arg = false; - carg_ = typed_arg; + break; + } + case G_OPTION_ARG_NONE: // Actually a boolean. + { + gboolean* typed_arg = new gboolean; + *typed_arg = false; + carg_ = typed_arg; - break; - } - case G_OPTION_ARG_CALLBACK: - { - //The C arg pointer is a function pointer, cast to void*. - union { - void* dp; - GOptionArgFunc fp; - } u; - u.fp = &OptionGroup::option_arg_callback; - carg_ = u.dp; - - // With all compiler warnings turned on and a high optimization level - // it's difficult to cast a function pointer to a void*. See bug 589197. - // A few results with g++ 4.4.5 with the flags -pedantic -O2 -Werror: - // - // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); - // error: ISO C++ forbids casting between pointer-to-function and pointer-to-object - // - // *reinterpret_cast<GOptionArgFunc*>(&carg_) = &OptionGroup::option_arg_callback; - // *(OptionArgFunc*)&carg_ = &OptionGroup::option_arg_callback; - // error: dereferencing type-punned pointer will break strict-aliasing rules - // - // If any compiler dislikes the union, the following code is worth testing: - // carg_ = reinterpret_cast<void*>( - // reinterpret_cast<unsigned long>(&OptionGroup::option_arg_callback)); + break; + } + case G_OPTION_ARG_CALLBACK: + { + // The C arg pointer is a function pointer, cast to void*. + union { + void* dp; + GOptionArgFunc fp; + } u; + u.fp = &OptionGroup::option_arg_callback; + carg_ = u.dp; + + // With all compiler warnings turned on and a high optimization level + // it's difficult to cast a function pointer to a void*. See bug 589197. + // A few results with g++ 4.4.5 with the flags -pedantic -O2 -Werror: + // + // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); + // error: ISO C++ forbids casting between pointer-to-function and pointer-to-object + // + // *reinterpret_cast<GOptionArgFunc*>(&carg_) = &OptionGroup::option_arg_callback; + // *(OptionArgFunc*)&carg_ = &OptionGroup::option_arg_callback; + // error: dereferencing type-punned pointer will break strict-aliasing rules + // + // If any compiler dislikes the union, the following code is worth testing: + // carg_ = reinterpret_cast<void*>( + // reinterpret_cast<unsigned long>(&OptionGroup::option_arg_callback)); + + break; + } + default: + { + break; + } + } +} - break; +void +OptionGroup::CppOptionEntry::set_c_arg_default(void* cpp_arg) +{ + switch (carg_type_) + { + case G_OPTION_ARG_INT: + { + *static_cast<int*>(carg_) = *static_cast<int*>(cpp_arg); + break; + } + case G_OPTION_ARG_DOUBLE: + { + *static_cast<double*>(carg_) = *static_cast<double*>(cpp_arg); + break; + } + case G_OPTION_ARG_NONE: + { + *static_cast<gboolean*>(carg_) = *static_cast<bool*>(cpp_arg); + break; + } + case G_OPTION_ARG_STRING: + case G_OPTION_ARG_FILENAME: + case G_OPTION_ARG_STRING_ARRAY: + case G_OPTION_ARG_FILENAME_ARRAY: + { + // No need to set default values for string-valued options. + // If *carg_ is still 0, when convert_c_to_cpp() is called, just don't + // touch *cpparg_. Besides, setting default values in *carg_ can result + // in memory leaks, because glib would not free the strings before + // the char*'s are overwritten with pointers to newly allocated copies + // of the command option arguments. + break; + } + case G_OPTION_ARG_CALLBACK: + { + // No value to set here. The arg pointer is a function pointer. + + // Set or clear FLAG_FILENAME in *entry_. + const OptionArgCallback* const option_arg = static_cast<const OptionArgCallback*>(cpp_arg); + if (option_arg->is_filename_option()) + { + entry_->set_flags(entry_->get_flags() | OptionEntry::FLAG_FILENAME); } - default: + else { - break; + entry_->set_flags(entry_->get_flags() & ~OptionEntry::FLAG_FILENAME); } + break; + } + default: + { + break; + } } } -void OptionGroup::CppOptionEntry::set_c_arg_default(void* cpp_arg) +void +OptionGroup::CppOptionEntry::release_c_arg() { - switch(carg_type_) + // Delete the instances that we created in allocate_c_arg(). + // Notice that we delete the type that we created, but not the value to which it points. + if (carg_) { - case G_OPTION_ARG_INT: + switch (carg_type_) { - *static_cast<int*>(carg_) = *static_cast<int*>(cpp_arg); + case G_OPTION_ARG_STRING: + case G_OPTION_ARG_FILENAME: + { + char** typed_arg = static_cast<char**>(carg_); + g_free(*typed_arg); // Free the char* string at typed_arg, if allocated by the C code. + delete typed_arg; // Delete the char** that we allocated in allocate_c_arg(). + break; } - case G_OPTION_ARG_DOUBLE: + case G_OPTION_ARG_INT: { - *static_cast<double*>(carg_) = *static_cast<double*>(cpp_arg); + int* typed_arg = static_cast<int*>(carg_); + delete typed_arg; + break; } - case G_OPTION_ARG_NONE: + case G_OPTION_ARG_DOUBLE: { - *static_cast<gboolean*>(carg_) = *static_cast<bool*>(cpp_arg); + double* typed_arg = static_cast<double*>(carg_); + delete typed_arg; + break; } - case G_OPTION_ARG_STRING: - case G_OPTION_ARG_FILENAME: case G_OPTION_ARG_STRING_ARRAY: case G_OPTION_ARG_FILENAME_ARRAY: { - // No need to set default values for string-valued options. - // If *carg_ is still 0, when convert_c_to_cpp() is called, just don't - // touch *cpparg_. Besides, setting default values in *carg_ can result - // in memory leaks, because glib would not free the strings before - // the char*'s are overwritten with pointers to newly allocated copies - // of the command option arguments. + char*** typed_arg = static_cast<char***>(carg_); + g_strfreev(*typed_arg); // Free the array of strings and the array at typed_arg, if allocated + // by the C code. + delete typed_arg; // Delete the char*** that we allocated in allocate_c_arg(). + + break; + } + case G_OPTION_ARG_NONE: // Actually a boolean. + { + gboolean* typed_arg = static_cast<gboolean*>(carg_); + delete typed_arg; + break; } case G_OPTION_ARG_CALLBACK: { - //No value to set here. The arg pointer is a function pointer. + // Delete the OptionArgCallback instance that was allocated by add_entry() + // or add_entry_filename(). + auto option_arg = static_cast<OptionArgCallback*>(cpparg_); + delete option_arg; + cpparg_ = nullptr; - //Set or clear FLAG_FILENAME in *entry_. - const OptionArgCallback* const option_arg = static_cast<const OptionArgCallback*>(cpp_arg); - if (option_arg->is_filename_option()) - { - entry_->set_flags(entry_->get_flags() | OptionEntry::FLAG_FILENAME); - } - else - { - entry_->set_flags(entry_->get_flags() & ~OptionEntry::FLAG_FILENAME); - } break; } default: { break; } - } -} - -void OptionGroup::CppOptionEntry::release_c_arg() -{ - //Delete the instances that we created in allocate_c_arg(). - //Notice that we delete the type that we created, but not the value to which it points. - if(carg_) - { - switch(carg_type_) - { - case G_OPTION_ARG_STRING: - case G_OPTION_ARG_FILENAME: - { - char** typed_arg = static_cast<char**>(carg_); - g_free(*typed_arg); //Free the char* string at typed_arg, if allocated by the C code. - delete typed_arg; //Delete the char** that we allocated in allocate_c_arg(). - - break; - } - case G_OPTION_ARG_INT: - { - int* typed_arg = static_cast<int*>(carg_); - delete typed_arg; - - break; - } - case G_OPTION_ARG_DOUBLE: - { - double* typed_arg = static_cast<double*>(carg_); - delete typed_arg; - - break; - } - case G_OPTION_ARG_STRING_ARRAY: - case G_OPTION_ARG_FILENAME_ARRAY: - { - char*** typed_arg = static_cast<char***>(carg_); - g_strfreev(*typed_arg); //Free the array of strings and the array at typed_arg, if allocated by the C code. - delete typed_arg; //Delete the char*** that we allocated in allocate_c_arg(). - - break; - } - case G_OPTION_ARG_NONE: // Actually a boolean. - { - gboolean* typed_arg = static_cast<gboolean*>(carg_); - delete typed_arg; - - break; - } - case G_OPTION_ARG_CALLBACK: - { - //Delete the OptionArgCallback instance that was allocated by add_entry() - //or add_entry_filename(). - auto option_arg = static_cast<OptionArgCallback*>(cpparg_); - delete option_arg; - cpparg_ = nullptr; - - break; - } - default: - { - break; - } } carg_ = nullptr; } - if(entry_) + if (entry_) delete entry_; } -void OptionGroup::CppOptionEntry::convert_c_to_cpp() +void +OptionGroup::CppOptionEntry::convert_c_to_cpp() { if (!carg_) return; - switch(carg_type_) + switch (carg_type_) { - case G_OPTION_ARG_STRING: - { - char** typed_arg = static_cast<char**>(carg_); - auto typed_cpp_arg = static_cast<Glib::ustring*>(cpparg_); - if(typed_arg && *typed_arg && typed_cpp_arg) - { - *typed_cpp_arg = *typed_arg; - } - break; - } - case G_OPTION_ARG_FILENAME: + case G_OPTION_ARG_STRING: + { + char** typed_arg = static_cast<char**>(carg_); + auto typed_cpp_arg = static_cast<Glib::ustring*>(cpparg_); + if (typed_arg && *typed_arg && typed_cpp_arg) { - char** typed_arg = static_cast<char**>(carg_); - auto typed_cpp_arg = static_cast<std::string*>(cpparg_); - if(typed_arg && *typed_arg && typed_cpp_arg) - { - *typed_cpp_arg = *typed_arg; - } - break; + *typed_cpp_arg = *typed_arg; } - case G_OPTION_ARG_INT: + break; + } + case G_OPTION_ARG_FILENAME: + { + char** typed_arg = static_cast<char**>(carg_); + auto typed_cpp_arg = static_cast<std::string*>(cpparg_); + if (typed_arg && *typed_arg && typed_cpp_arg) { - *((int*)cpparg_) = *(static_cast<int*>(carg_)); - break; + *typed_cpp_arg = *typed_arg; } - case G_OPTION_ARG_DOUBLE: - { - *((double*)cpparg_) = *(static_cast<double*>(carg_)); - break; - } - case G_OPTION_ARG_STRING_ARRAY: + break; + } + case G_OPTION_ARG_INT: + { + *((int*)cpparg_) = *(static_cast<int*>(carg_)); + break; + } + case G_OPTION_ARG_DOUBLE: + { + *((double*)cpparg_) = *(static_cast<double*>(carg_)); + break; + } + case G_OPTION_ARG_STRING_ARRAY: + { + char*** typed_arg = static_cast<char***>(carg_); + auto typed_cpp_arg = static_cast<vecustrings*>(cpparg_); + if (typed_arg && *typed_arg && typed_cpp_arg) { - char*** typed_arg = static_cast<char***>(carg_); - auto typed_cpp_arg = static_cast<vecustrings*>(cpparg_); - if(typed_arg && *typed_arg && typed_cpp_arg) + typed_cpp_arg->clear(); + + // The C array is null-terminated. + // Glib::StringArrayHandle array_handle(*typed_arg, Glib::OWNERSHIP_NONE); + + // The SUN Forte compiler complains about this: + // "optiongroup.cc", line 354: Error: Cannot assign Glib::ArrayHandle<Glib::ustring, + // Glib::Container_Helpers::TypeTraits<Glib::ustring>> to std::vector<Glib::ustring> without + // "std::vector<Glib::ustring>::operator=(const std::vector<Glib::ustring>&)";. + // + //(*typed_cpp_arg) = array_handle; + // + // And the Tru64 compiler does not even like us to instantiate the StringArrayHandle: + // + // cxx: Error: ../../glib/glibmm/containerhandle_shared.h, line 149: the operand + // of a pointer dynamic_cast must be a pointer to a complete class type + // return dynamic_cast<CppType>(Glib::wrap_auto(cobj, false /* take_copy */)); + + // for(Glib::StringArrayHandle::iterator iter = array_handle.begin(); iter != + // array_handle.end(); ++iter) + //{ + // typed_cpp_arg->emplace_back(*iter); + //} + + // So we do this: + + char** char_array_next = *typed_arg; + while (*char_array_next) { - typed_cpp_arg->clear(); - - //The C array is null-terminated. - //Glib::StringArrayHandle array_handle(*typed_arg, Glib::OWNERSHIP_NONE); - - //The SUN Forte compiler complains about this: - // "optiongroup.cc", line 354: Error: Cannot assign Glib::ArrayHandle<Glib::ustring, - // Glib::Container_Helpers::TypeTraits<Glib::ustring>> to std::vector<Glib::ustring> without - // "std::vector<Glib::ustring>::operator=(const std::vector<Glib::ustring>&)";. - // - //(*typed_cpp_arg) = array_handle; - // - //And the Tru64 compiler does not even like us to instantiate the StringArrayHandle: - // - // cxx: Error: ../../glib/glibmm/containerhandle_shared.h, line 149: the operand - // of a pointer dynamic_cast must be a pointer to a complete class type - // return dynamic_cast<CppType>(Glib::wrap_auto(cobj, false /* take_copy */)); - - //for(Glib::StringArrayHandle::iterator iter = array_handle.begin(); iter != array_handle.end(); ++iter) - //{ - // typed_cpp_arg->emplace_back(*iter); - //} - - //So we do this: - - char** char_array_next = *typed_arg; - while(*char_array_next) - { - typed_cpp_arg->emplace_back(*char_array_next); - ++char_array_next; - } + typed_cpp_arg->emplace_back(*char_array_next); + ++char_array_next; } - break; } - case G_OPTION_ARG_FILENAME_ARRAY: + break; + } + case G_OPTION_ARG_FILENAME_ARRAY: + { + char*** typed_arg = static_cast<char***>(carg_); + auto typed_cpp_arg = static_cast<vecstrings*>(cpparg_); + if (typed_arg && *typed_arg && typed_cpp_arg) { - char*** typed_arg = static_cast<char***>(carg_); - auto typed_cpp_arg = static_cast<vecstrings*>(cpparg_); - if(typed_arg && *typed_arg && typed_cpp_arg) - { - typed_cpp_arg->clear(); + typed_cpp_arg->clear(); - //See comments above about the SUN Forte and Tru64 compilers. + // See comments above about the SUN Forte and Tru64 compilers. - char** char_array_next = *typed_arg; - while(*char_array_next) - { - typed_cpp_arg->emplace_back(*char_array_next); - ++char_array_next; - } + char** char_array_next = *typed_arg; + while (*char_array_next) + { + typed_cpp_arg->emplace_back(*char_array_next); + ++char_array_next; } - break; - } - case G_OPTION_ARG_NONE: // Actually a boolean. - { - *(static_cast<bool*>(cpparg_)) = *(static_cast<gboolean*>(carg_)); - break; - } - case G_OPTION_ARG_CALLBACK: - { - //Nothing to convert here. That's a task for the callback function - //(the SlotOptionArgString or SlotOptionArgFilename). - break; - } - default: - { - break; } + break; + } + case G_OPTION_ARG_NONE: // Actually a boolean. + { + *(static_cast<bool*>(cpparg_)) = *(static_cast<gboolean*>(carg_)); + break; + } + case G_OPTION_ARG_CALLBACK: + { + // Nothing to convert here. That's a task for the callback function + //(the SlotOptionArgString or SlotOptionArgFilename). + break; + } + default: + { + break; + } } } -GOptionGroup* OptionGroup::gobj_give_ownership() +GOptionGroup* +OptionGroup::gobj_give_ownership() { has_ownership_ = false; return gobj(); } } // namespace Glib - |