Boost logo

Boost Users :

Subject: Re: [Boost-users] Boost.ProgramOptions issues porting from 1.56 to 1.64
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2017-07-25 16:24:53


>
> I'm trying to understand what's going on;
> obviously there's some kind of semantic change with optional argument to
> switches.
>
> Could anyone shed some light on this please? I'm not sure how to proceed
> now. TIA, -DD
>

OK, maybe with a small stand-alone program, I'll have more chances of
getting help.

Basically the main difference is that implicit_value() no longer works in
1.64 as it used to in 1.56.
the new arg doesn't get the explicit value on the next token anymore, but
the implicit value, and
this despite the changes from June 10 [1] and Jan 13 [2].

I've even tried having a non-empty implicit value, but that makes no
difference.

My app uses implicit values extensively, and switching to default values
instead is not an option (no pun intended),
since then the options would be defined which affects the behavior of the
app extensively.

Is this a regression? Given [2] I'd say yes, but given that
test_implicit_value() [3] does test something similar
to what I'm doing, I'm a bit baffled by my little example not working
properly. What am I missing? Thanks, --DD

[1]
https://github.com/boostorg/program_options/commit/ed72cc2f92d0e48d0573614bb8d180325bff9866
[2]
https://github.com/boostorg/program_options/commit/7729850bb7eb25b42552b25eff41f141dfa3729f
[3]
https://github.com/boostorg/program_options/commit/ed72cc2f92d0e48d0573614bb8d180325bff9866

[ddevienne_at_arachne po]$ boost-1.56-gcc-4.8 --new groupA
has --new option: yes
--new option val: groupA
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = ["groupA",],
    original_tokens = ["--new","groupA",]
  },
}

[ddevienne_at_arachne po]$ boost-1.64-gcc-6.2 --new groupA
has --new option: yes
--new option val:
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = [],
    original_tokens = ["--new",]
  },

  {
    string_key = "",
    position_key = 0,
    value = ["groupA",],
    original_tokens = ["groupA",]
  },
}

Here's the full program and how I built it on both cases and running it in
different circumstances.

[ddevienne_at_arachne po]$ cat implicit_value_regression.cpp
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>

using namespace std;
using namespace boost::program_options;

std::ostream& operator<<(std::ostream& os, const std::vector<std::string>&
strings) {
    std::cout << '[';
    for (const auto& str : strings) {
        std::cout << '"' << str << '"' << ',';
    }
    return os << ']';
}

int main(int argc, char* argv[]) {
    options_description opts_desc("Options");
    opts_desc.add_options()
        ("new", value<std::string>()->implicit_value(""), "New group")
    ;

    parsed_options parsed =
        command_line_parser(argc, argv)
        .options(opts_desc)
        .run();
    variables_map args;
    store(parsed, args);

    auto new_arg = args["new"];
    if (new_arg.empty()) {
        cout << "has --new option: no" << endl;
    } else {
        cout << "has --new option: yes" << endl;
        cout << "--new option val: " << new_arg.as<std::string>() << endl;
    }

    cout << "parsed.options = {";
    for (const auto& opt : parsed.options) {
        cout << "\n {" << endl;
        cout << " string_key = \"" << opt.string_key << "\"," << endl;
        cout << " position_key = " << opt.position_key << "," << endl;
        cout << " value = " << opt.value << "," << endl;
        cout << " original_tokens = " << opt.original_tokens << endl;
        cout << " }," << endl;
    }
    cout << "}" << endl;

    return 0;
}
[ddevienne_at_arachne po]$ ls $BOOSTDIR/lib/*pro*
/users/gdadmin/trunk/project/toolworks/boost/1.56.0z/Linux_x64_2.12_gcc48//lib/libboost_program_options.so
/users/gdadmin/trunk/project/toolworks/boost/1.56.0z/Linux_x64_2.12_gcc48//lib/libboost_program_options.so.1.56.0
[ddevienne_at_arachne po]$ g++ -std=c++11 -I$BOOSTDIR/include -L$BOOSTDIR/lib
-lboost_program_options implicit_value_regression.cpp -o boost-1.56-gcc-4.8
[ddevienne_at_arachne po]$ boost-1.56-gcc-4.8 --new groupA
has --new option: yes
--new option val: groupA
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = ["groupA",],
    original_tokens = ["--new","groupA",]
  },
}
[ddevienne_at_arachne po]$ boost-1.56-gcc-4.8 --new=groupA
has --new option: yes
--new option val: groupA
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = ["groupA",],
    original_tokens = ["--new=groupA",]
  },
}
[ddevienne_at_arachne po]$ boost-1.56-gcc-4.8 --new
has --new option: yes
--new option val:
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = [],
    original_tokens = ["--new",]
  },
}
[ddevienne_at_arachne po]$ g++ --version
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[ddevienne_at_arachne po]$

[ddevienne_at_arachne po]$ ls $BOOSTDIR/lib/*pro*
/users/gdadmin/trunk/project/toolworks/boost/1.64.0/Linux_x64_2.12_gcc62/lib/libboost_program_options.so
/users/gdadmin/trunk/project/toolworks/boost/1.64.0/Linux_x64_2.12_gcc62/lib/libboost_program_options.so.1.64.0
[ddevienne_at_arachne po]$ g++ -std=c++11 -I$BOOSTDIR/include -L$BOOSTDIR/lib
-lboost_program_options implicit_value_regression.cpp -o boost-1.64-gcc-6.2
[ddevienne_at_arachne po]$ boost-1.64-gcc-6.2 --new groupA
has --new option: yes
--new option val:
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = [],
    original_tokens = ["--new",]
  },

  {
    string_key = "",
    position_key = 0,
    value = ["groupA",],
    original_tokens = ["groupA",]
  },
}
[ddevienne_at_arachne po]$ boost-1.64-gcc-6.2 --new=groupA
has --new option: yes
--new option val: groupA
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = ["groupA",],
    original_tokens = ["--new=groupA",]
  },
}
[ddevienne_at_arachne po]$ boost-1.64-gcc-6.2 --new
has --new option: yes
--new option val:
parsed.options = {
  {
    string_key = "new",
    position_key = -1,
    value = [],
    original_tokens = ["--new",]
  },
}
[ddevienne_at_arachne po]$ g++ --version
g++ (GCC) 6.2.1 20160916 (Red Hat 6.2.1-3)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net