p-ranav / argparse

Argument Parser for Modern C++
MIT License
2.63k stars 245 forks source link

Feature request: Support & strip quote characters on string inputs #134

Closed softhorizons closed 2 years ago

softhorizons commented 3 years ago

Essential, particularly for file names.

skrobinson commented 2 years ago

Can you provide some examples? Ideally, give one or two samples with an explanation of what you expect and what is really happening. Anyone wanting to take on this feature request will need more details.

softhorizons commented 2 years ago

Sample command line I want to parse myprogram --output Test File.txt

Currently: cli.add_argument("--output") cli.parse_args(argc, argv); auto outfile = cli.get("--output"); This returns outfile == "Test"; //incorrect But I need outfile == "Test File.txt"; //correct

Instead, I need the ability to have a quoted command line syntax like this: myprogram --output "Test File.txt" and alternate syntax myprogram --output 'Test File.txt'

This should return: outfile == "Test File.txt"; //correct

skrobinson commented 2 years ago

Which shell are you using? With Bash, I get the following results, which I believe is what you want.

#include <argparse/argparse.hpp>
#include <iostream>
#include <string>

int main(int argc, const char* argv[]) {
    argparse::ArgumentParser cli;
    cli.add_argument("--output");

    cli.parse_args(argc, argv);
    auto outfile = cli.get<std::string>("--output");

    std::cout << "outfile == \"Test File.txt\" is " << std::boolalpha << (outfile == "Test File.txt") << std::endl;
}
$ g++ -Iargparse-cpp.git/include --std=c++17 -o arg arg.cpp
$ ./arg --output "Test File.txt"
outfile == "Test File.txt" is true
$ ./arg --output 'Test File.txt'
outfile == "Test File.txt" is true
softhorizons commented 2 years ago

Windows. Win10 to be precise. Maybe not liked, but still rather popular.

skrobinson commented 2 years ago

...but still rather popular.

This made me chuckle. How many billions of installs of Windows are there?

I have some follow-up questions to try to find the source of the unexpected parsing.

Are you using PowerShell or cmd.exe or something else?

Do you see the bad parsing when typing into a cli shell? Or is this launched from an icon?

Is your argparse-using program started as an argument to cmd.exe? I.e. cmd.exe /C myprogram --output "Text File.txt". This pattern appears to have special rules for processing quotes.

Does the minimal example code I posted not work in your environment?

softhorizons commented 2 years ago

You're correct, using double-quotes indeed works. That was due to my cockpit error. Apologies. However, using single quotes does not work. My environment is MSVC 2019 debug, using CMake. I believe MSVC spawns a cmd.exe shell when running in the CMake enviromnent, but I wouldn't swear to it.

My launch.vs.json file has: "args": [ "--heat Heatmap.csv --steering SteeringIdentity.csv --bg SmallSquare100.png --output 'c:/tmp/output file.png' Running the program and looking at the raw argv, I see: argv[8] 0x000001ea0c9a4843 "'c:/tmp/output" argv[9] 0x000001ea0c9a4852 "file.png'"

So, Windows doesn't honor single quotes and just puts them into the argv as ordinary characters.

My first reaction is to say that it'd be nice to have argparse honor single quotes like in the rest of the universe by joining arguments with leading & trailing single quotes, but a) turns out that's just not the platform's native convention, and b) that behavior would require guessing that there's exactly one space between args.

So, unless you feel that single quotes should be supported on Windows, feel free to close this thread.

skrobinson commented 2 years ago

Thank you for the detailed explanation of your findings. I suspect you are not the first or last to be surprised by parsing differences with quotes and your message may help someone else.

So, unless you feel that single quotes should be supported on Windows, feel free to close this thread.

My feeling is that fighting against the platform's usual behavior is just asking for misery. If you are satisfied that your issue has been solved, please close this issue.