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

Support nested quoting #595

Closed
remkop opened this issue Jan 7, 2019 · 8 comments
Closed

Support nested quoting #595

remkop opened this issue Jan 7, 2019 · 8 comments
Labels
theme: parser An issue or change related to the parser type: enhancement ✨
Milestone

Comments

@remkop
Copy link
Owner

remkop commented Jan 7, 2019

As an enhancement to #594, we can support nested quotes.

For example, when splitting on the "," split regex, with a Map option whose keys have embedded '=' characters, we want to be able to parse input like this:

<cmd> --option "'keyprefix=keypostfix'=value","'key2=key2'=value2"

Giving a map with key-value pairs like this:

keyprefix=keypostfix : value
key2=key2 : value2
@pubudu91
Copy link

pubudu91 commented Jan 9, 2019

I tried to pass multiple -e options like the following:

$ <cmd> -e \"a=b\"=foo -e \"a b\"=bar <file-name>

Is this the same scenario as the one you've described above?

@pubudu91
Copy link

pubudu91 commented Jan 9, 2019

Ah sorry. My bad. Should escape the space as well.

@remkop
Copy link
Owner Author

remkop commented Jan 9, 2019

@pubudu91 Was there any problem with your example, or did it behave as expected?

To explain what I had in mind with nested quotes, assume we have a positional parameter defined like this:

@Parameters(split = ",")
Map<String, String> map;

the parameter values will first be split by the specified regular expression ("," in this case), and after that each substring is parsed as a KEY=VALUE map entry. For example:

"'aaa=bbb'=ccc","'xxx yyy'='zz zz zz'"

Given the above input, if CommandLine::setTrimQuotes() is set to true, first the parameter is split on the regex, and quotes are trimmed from each value, so we get these values:

'aaa=bbb'=ccc
'xxx yyy'='zz zz zz'

After that, each value is parsed as a KEY=VALUE pair and put into the map. We want the parser to recognize 'aaa=bbb' as a single token so we can have = characters embedded in the key, like you requested in #594.

For this to work, the current quote-parsing logic needs to be extended to recognize single quotes as well as double quotes, and recognize nested quoted sections. That is what this ticket is about.

@remkop
Copy link
Owner Author

remkop commented Jan 9, 2019

@pubudu91 in your example, why do you need to escape the double quotes? Don't you want to do this instead?

$ <cmd> -e "a=b"=foo -e "a b"=bar <file-name>

@pubudu91
Copy link

pubudu91 commented Jan 9, 2019

If not escaped, the quotes seem to get trimmed. Checked the args array in main() and the quotes weren't there unless it was escaped. Similar story with the space I guess. Not an issue with picocli.

@remkop
Copy link
Owner Author

remkop commented Jan 9, 2019

You can control quote trimming with CommandLine.setTrimQuotes. By default, picocli leaves the quotes in place. Could it be the shell (bash) that is trimming the quotes?

@pubudu91
Copy link

Yes, probably. As I said, it's not an issue with picocli.

@remkop remkop added this to the 4.0 milestone Jul 1, 2019
@remkop
Copy link
Owner Author

remkop commented Jul 1, 2019

Adding this ticket to the 4.0 roadmap:

As part of the work for #738, picocli 4.0 will fully support nested backslash-escaped double quotes. Single quotes will not have any special meaning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: parser An issue or change related to the parser type: enhancement ✨
Projects
None yet
Development

No branches or pull requests

2 participants