getopt: How does arraySep work?

Jon Degenhardt jond at noreply.com
Thu Jul 16 19:01:08 UTC 2020


On Thursday, 16 July 2020 at 17:40:25 UTC, Steven Schveighoffer 
wrote:
> On 7/16/20 1:13 PM, Andre Pany wrote:
>> On Thursday, 16 July 2020 at 05:03:36 UTC, Jon Degenhardt 
>> wrote:
>>> On Wednesday, 15 July 2020 at 07:12:35 UTC, Andre Pany wrote:
>>>> [...]
>>>
>>> An enhancement is likely to hit some corner-cases involving 
>>> list termination requiring choices that are not fully 
>>> generic. Any time a legal list value looks like a legal 
>>> option. Perhaps the most important case is single digit 
>>> numeric options like '-1', '-2'. These are legal short form 
>>> options, and there are programs that use them. They are also 
>>> somewhat common numeric values to include in command lines 
>>> inputs.
>>>
>>> [...]
>> 
>> My naive implementation would be that any dash would stop the 
>> list of multiple values. If you want to have a value 
>> containing a space or a dash, you enclose it with double 
>> quotes in the terminal.
>
> Enclose with double quotes in the terminal does nothing:
>
> myapp --modelicalibs "file-a.mo" "file-b.mo"
>
> will give you EXACTLY the same string[] args as:
>
> myapp --modelicalibs file-a.mo file-b.mo
>
> I think Jon's point is that it's difficult to distinguish where 
> an array list ends if you get the parameters as separate items.
>
> Like:
>
> myapp --numbers 1 2 3 -5 -6
>
> Is that numbers=> [1, 2, 3, -5, -6]
>
> or is it numbers=> [1, 2, 3], 5 => true, 6 => true
>
> This is probably why the code doesn't support that.
>
> -Steve

Yes, this what I was getting. Thanks for the clarification.

Also, it's not always immediately obvious what part of the 
argument splitting is being done by the shell, and what is being 
done by the program/getopt. Taking inspiration from the recent 
one-liners, here's way to see how the program gets the args from 
the shell for different command lines:

$ echo 'import std.stdio; void main(string[] args) { args[1 .. 
$].writeln; }' | dmd -run - --numbers 1,2,3,-5,-6
["--numbers", "1,2,3,-5,-6"]

$ echo 'import std.stdio; void main(string[] args) { args[1 .. 
$].writeln; }' | dmd -run - --numbers 1 2 3 -5 -6
["--numbers", "1", "2", "3", "-5", "-6"]

$ echo 'import std.stdio; void main(string[] args) { args[1 .. 
$].writeln; }' | dmd -run - --numbers "1" "2" "3" "-5" "-6"
["--numbers", "1", "2", "3", "-5", "-6"]

$ echo 'import std.stdio; void main(string[] args) { args[1 .. 
$].writeln; }' | dmd -run - --numbers '1 2 3 -5 -6'
["--numbers", "1 2 3 -5 -6"]

The first case is what getopt supports now - All the values in a 
single string with a separator that getopt splits on. The 2nd and 
3rd are identical from the program's perspective (Steve's point), 
but they've already been split, so getopt would need a different 
approach. And requires dealing with ambiguity. The fourth form 
eliminates the ambiguity, but puts the burden on the user to use 
quotes.


More information about the Digitalmars-d-learn mailing list