Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitoken options #444

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Multitoken options #444

wants to merge 2 commits into from

Conversation

maickrau
Copy link

@maickrau maickrau commented Dec 2, 2024

Implements multitoken options from Boost.Program_options. A multitoken option will take values until the next option is given. This makes it possible to switch to cxxopts without breaking backwards compatibility for multitoken options, and also enables a slightly easier syntax for the user for options with multiple values.

Example code without multitoken which just takes multiple parameters and prints them:

#include <iostream>
#include <vector>
#include <string>
#include "cxxopts/include/cxxopts.hpp"

int main(int argc, char** argv)
{
	cxxopts::Options options { "test" };
	options.add_options()
		("a", "Option a")
		("b", "Option b", cxxopts::value<std::vector<std::string>>())
		("c", "Option c", cxxopts::value<std::vector<std::string>>())
		;
	auto params = options.parse(argc, argv);
	bool a = params.count("a");
	std::cerr << "a: " << (a ? "yes" : "no") << std::endl;
	std::cerr << "b:";
	if (params.count("b") != 0)
	{
		for (std::string value : params["b"].as<std::vector<std::string>>())
		{
			std::cerr << " " << value;
		}
	}
	std::cerr << std::endl;
	std::cerr << "c:";
	if (params.count("c") != 0)
	{
		for (std::string value : params["c"].as<std::vector<std::string>>())
		{
			std::cerr << " " << value;
		}
	}
	std::cerr << std::endl;
	std::cerr << "unmatched:";
	for (std::string value : params.unmatched())
	{
		std::cerr << " " << value;
	}
	std::cerr << std::endl;
}
$ ./main -b 1 2 -c 3 4 -a 5
a: yes
b: 1
c: 3
unmatched: 2 4 5

Applying multitoken to option -c while keeping -b as is:

		("b", "Option b", cxxopts::value<std::vector<std::string>>())
		("c", "Option c", cxxopts::value<std::vector<std::string>>()->multitoken())

will now cause option -c to take values until the next option is given:

$ ./main -b 1 2 -c 3 4 -a 5
a: yes
b: 1
c: 3 4
unmatched: 2 5

This change is Reviewable

@jarro2783
Copy link
Owner

I'll have to get back to you on this one, I haven't forgotten it, but I can't comment further right now.

@jarro2783
Copy link
Owner

I wonder if it is worth putting some help text in to let users know that something is a multitoken option. Other than that this looks good.

@patrikhuber
Copy link

Missing multitoken support is also the last bit preventing me from completely ditching boost program_options and switching to cxxopts fully. Would be really nice to have this.

I'm assuming this would also work with cxxopts::value<std::vector<float>>()->multitoken()?

patrikhuber added a commit to patrikhuber/eos that referenced this pull request Dec 15, 2024
The command-line argument syntax of generate-obj slightly changed: Coefficient values now need to be separated by a comma instead of spaces, e.g. `generate.obj.exe --model ... --shape-coefficients 1.0,-1.5`.
If cxxopts merge jarro2783/cxxopts#444, we could potentially use their multitoken option - but I think the syntax is fine now as it is.
@maickrau
Copy link
Author

@jarro2783 I was just going by the Boost implementation which doesn't change the help text for the parameter, but if you would like to add a help text that's fine by me since it shouldn't affect backwards compatibility.

@patrikhuber Yes, float works as well. Multitoken options use the same parse_option method as other options so I think it should work for all types.

@jarro2783
Copy link
Owner

I'm not too fussed, I thought it might be good so that it is immediately obvious to the users of your program.
I'll start with this PR and we can always add to it later.

@jarro2783
Copy link
Owner

Can you write a unit test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants