GNOME Bugzilla – Bug 526831
G_OPTION_REMAINING no longer works with OptionEntry
Last modified: 2008-04-16 06:56:08 UTC
Please describe the problem: Setting a OptionEntry's long name to G_OPTION_REMAINING no longer works in glibmm 2.16.0. It used to work fine in older releases. I'm not sure if this is the appropriate way to parse out the remaining command line arguments, if there is another way it should be documented and/or put in the options example. Steps to reproduce: 1. Build and run test case below 2. /* g++ -o test-opts `pkg-config --libs --cflags gtkmm-2.4` main.cc */ #include <glibmm.h> #include <iostream> class Options : public Glib::OptionGroup { public: Options(); int dummy; std::vector<Glib::ustring> args; }; Options::Options() : Glib::OptionGroup("Test", "Command line options"), dummy(0) { Glib::OptionEntry e_dummy; e_dummy.set_long_name("dummy"); e_dummy.set_short_name('d'); add_entry(e_dummy, dummy); Glib::OptionEntry e_remaining; e_remaining.set_long_name(G_OPTION_REMAINING); add_entry(e_remaining, args); } int main(int argc, char *argv[]) { Options options; Glib::OptionContext context("[FILE...]"); context.set_main_group(options); try { context.parse(argc, argv); } catch (const Glib::OptionError& e) { std::cerr << e.what() << std::endl; return 1; } std::cout << "dummy: " << options.dummy << std::endl; std::cout << "parsed remaining args: "; for (Glib::OptionGroup::vecustrings::const_iterator iter = options.args.begin(); iter != options.args.end(); ++iter) { std::cout << *iter << ", "; } std::cout << std::endl; std::cout << "left in argv: "; for (int i = 1; i < argc; i++) { std::cout << argv[i] << ", "; } std::cout << std::endl; } Actual results: ./test-opts random -d 1 remaining args dummy: 1 parsed remaining args: left in argv: random, remaining, args, Expected results: ./test-opts random -d 1 remaining args dummy: 1 parsed remaining args: random, remaining, args, left in argv: Does this happen every time? yes Other information: It seems to be specific to glibmm, I tried a similar test case in plain c/glib and the remaining args were parsed properly.
I wonder if glib does a simple pointer comparison instead of a strcmp().
This is fixed in svn trunk so it will get into a future glibmm 2.16.x tarball: 2008-04-13 Murray Cumming <murrayc@murrayc.com> * glib/src/optionentry.ccg: set_long_name(): Do not use NULL for an empty string, because "" has a special meaning to GOptionEntry - it is the definition of G_OPTION_REMANING. * examples/options/main.cc: Add an entry with the long name G_OPTION_REMAINING, to list additional non-named arguments. More explicit API should be added for this. Bug #526831 (Christian Lundgren). I do wonder when this could have broken. I can imagine that I broke it in svn in the last few days while trying to fix a leak, but I can't see a change that might have broken the tarball releases before that. If this bug is really in a tarball, then I suggest that you access the GOptionEntry directly, with gobj(), to work around the problem until the fix is widely distributed. Thanks for the bug report.
I did a binary search and it happened between 2.15.2 and 2.15.3. It's not mentioned in the changelog but it's clearly there in the diff. It comes from change 545 to optionentry.hg which introduces this definition: #m4 _CONVERSION(`Glib::ustring',`const gchar*',`($3).empty() ? NULL : g_strdup(($3).c_str())')
Thanks, Philip.