Re: Argon: an alternative parser for command-line arguments

2019-01-26 Thread Victor Porton via Digitalmars-d-announce

On Wednesday, 9 March 2016 at 18:56:10 UTC, Markus Laker wrote:

To support git-style syntax while using Argon, I'd do this:

1. Find the (possibly empty) initial sequence of tokens that 
start with a dash.  Pass them to an Argon-derived class which 
we'll call `Stem', which parses them.


2. If no more tokens exist (as in "my-command --help"), do what 
we can with the options we've seen, and then exit.


3. Otherwise, the next token must be a subcommand name: we've 
seen something "my-command --verbose display-widgets 
--paginate".
 Use that token to select a leaf class, also derived from 
Argon.  There's one leaf class per subcommand.


4. Pass the remaining tokens (in this example, just 
"--paginate") to the selected leaf pass for parsing.  Also pass 
a reference to Stem, so that the leaf code can use any options 
garnered by Stem.


It is a wrong way, because switches may have arguments (not 
starting with a dash).


I am now considering to write a new object-oriented command line 
parser from scratch because it is sometimes easier to write new 
code than to understand other's one.


It shouldn't be hard to write some reusable code to do this, if 
it were a common requirement.


Re: Argon: an alternative parser for command-line arguments

2018-07-05 Thread Jim Balter via Digitalmars-d-announce

On Thursday, 3 March 2016 at 09:33:38 UTC, Johannes Pfau wrote:

Am Thu, 03 Mar 2016 09:09:38 +
schrieb Markus Laker :

* It can open files specified at the command line.  It can do 
a simplified version of what cat(1) does and many Perl 
programs so, and open a file specified by the user or fall 
back to reading from stdin.  There's also a convention that 
the user can type "-" to mean stdin or stdout, depending on 
the open-mode you specify.


The rest of this list sounds quite good, but please reconsider 
automatically opening files: 
https://media.ccc.de/v/32c3-7130-the_perl_jam_2


No one wants to watch a 40 minute video just to find out what 
your point is.




I guess the scenario can't happen in D as our open file methods 
won't execute programs (!) but still


But still? What other problem is there? What does it matter 
whether the command line parser opens the file or some other part 
of the program does?


Re: Argon: an alternative parser for command-line arguments

2016-03-10 Thread karabuta via Digitalmars-d-announce

On Wednesday, 9 March 2016 at 18:56:10 UTC, Markus Laker wrote:

On Saturday, 5 March 2016 at 16:28:25 UTC, karabuta wrote:
I think he meant: [git status --help], where you have three 
attributes with the last one being the flag. So in addition 
to: [status --help] by default, you also have: [git status 
--help] to get help on status only.




Argon doesn't directly support subcommands.  That probably 
stems from a bias of mine: that subcommands make it harder for 
the author to parse the command and to generate good error 
messages, and also that they make it harder for users to use 
unfamiliar commands, because users must read a man page that 
documents eleven things they have no interest in doing just to 
get to the one thing that they need to do in order to get on 
with their day.
 At work, where I have written and I still maintain many 
hundreds of commands, I've moved away from subcommands 
completely: every operation gets a command of its own.  But I 
know that not everyone agrees with me, and that's OK.  If we 
want to debate this topic further, we should probably move the 
discussion from Announce to General.



..
It shouldn't be hard to write some reusable code to do this, if 
it were a common requirement.


I don't like subcommands myself. That's why Linux is such as mess 
with so much inconsistencies.


Re: Argon: an alternative parser for command-line arguments

2016-03-09 Thread Markus Laker via Digitalmars-d-announce

On Saturday, 5 March 2016 at 16:28:25 UTC, karabuta wrote:
I think he meant: [git status --help], where you have three 
attributes with the last one being the flag. So in addition to: 
[status --help] by default, you also have: [git status --help] 
to get help on status only.


Odd: I wrote a reply to this a few days ago, and it's nowhere to 
be seen.  I'll save a copy of this reply until I see it appearing 
on the forum.


Argon doesn't directly support subcommands.  That probably stems 
from a bias of mine: that subcommands make it harder for the 
author to parse the command and to generate good error messages, 
and also that they make it harder for users to use unfamiliar 
commands, because users must read a man page that documents 
eleven things they have no interest in doing just to get to the 
one thing that they need to do in order to get on with their day. 
 At work, where I have written and I still maintain many hundreds 
of commands, I've moved away from subcommands completely: every 
operation gets a command of its own.  But I know that not 
everyone agrees with me, and that's OK.  If we want to debate 
this topic further, we should probably move the discussion from 
Announce to General.


To support git-style syntax while using Argon, I'd do this:

1. Find the (possibly empty) initial sequence of tokens that 
start with a dash.  Pass them to an Argon-derived class which 
we'll call `Stem', which parses them.


2. If no more tokens exist (as in "my-command --help"), do what 
we can with the options we've seen, and then exit.


3. Otherwise, the next token must be a subcommand name: we've 
seen something "my-command --verbose display-widgets --paginate". 
 Use that token to select a leaf class, also derived from Argon.  
There's one leaf class per subcommand.


4. Pass the remaining tokens (in this example, just "--paginate") 
to the selected leaf pass for parsing.  Also pass a reference to 
Stem, so that the leaf code can use any options garnered by Stem.


It shouldn't be hard to write some reusable code to do this, if 
it were a common requirement.


Re: Argon: an alternative parser for command-line arguments

2016-03-05 Thread karabuta via Digitalmars-d-announce

On Friday, 4 March 2016 at 17:34:08 UTC, Markus Laker wrote:

On Friday, 4 March 2016 at 12:21:25 UTC, Jacob Carlborg wrote:
No, I mean a longer description, more like documentation. Look 
at the help for git when using --help, it has different 
behavior than -h. The first one is more like a man page.


Ah, I see.  Sorry for the misunderstanding.

An app could do that trivially: have a --short-help option with 
shortcut -h and a --help option with no shortcut, and then 
respond to the two switches differently.  Mark the --short-help 
option as undocumented, and then it won't appear in an 
auto-generated syntax summary.


Markus


I think he meant: [git status --help], where you have three 
attributes with the last one being the flag. So in addition to: 
[status --help] by default, you also have: [git status --help] to 
get help on status only.


By the way, that styles used by git seems confusing. Why not make 
it show the default help when you do: [git --help], whilst you 
can do: [git --help=status] OR [git --help status] for help on 
status only?


git --help
git -h

git --help=status
git --help status
git -h=status


Re: Argon: an alternative parser for command-line arguments

2016-03-04 Thread Markus Laker via Digitalmars-d-announce

On Friday, 4 March 2016 at 12:21:25 UTC, Jacob Carlborg wrote:
No, I mean a longer description, more like documentation. Look 
at the help for git when using --help, it has different 
behavior than -h. The first one is more like a man page.


Ah, I see.  Sorry for the misunderstanding.

An app could do that trivially: have a --short-help option with 
shortcut -h and a --help option with no shortcut, and then 
respond to the two switches differently.  Mark the --short-help 
option as undocumented, and then it won't appear in an 
auto-generated syntax summary.


Markus


Re: Argon: an alternative parser for command-line arguments

2016-03-04 Thread Jacob Carlborg via Digitalmars-d-announce

On 2016-03-03 21:55, Markus Laker wrote:


Yes.  You can give an option a description, like this:

// ...
uint nr_doors;
// ...
Named("doors", nr_doors, 0) ("number of doors").AddRange(1, 4);

If you do this, the user has a nice, short name to type:

--doors 2

But the description will be used in error messages ("The number of doors
must be between 1 and 4") and in auto-generated syntax summaries
("--doors ").


No, I mean a longer description, more like documentation. Look at the 
help for git when using --help, it has different behavior than -h. The 
first one is more like a man page.


--
/Jacob Carlborg


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Andrei Alexandrescu via Digitalmars-d-announce

On 03/03/2016 04:09 AM, Markus Laker wrote:

On Thursday, 3 March 2016 at 01:52:11 UTC, Chris Wright wrote:

You might want to take a minute to shill it here. What's great about it?


OK.  :-)

[snip]

Very nice! I think we should adopt some of these ideas for std.getopt as 
well. -- Andrei




Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Markus Laker via Digitalmars-d-announce

On Thursday, 3 March 2016 at 15:08:37 UTC, Jacob Carlborg wrote:
Does it support some longer documentation for the flags, i.e. 
"git status -h" vs "git status --help"?


Yes.  You can give an option a description, like this:

// ...
uint nr_doors;
// ...
Named("doors", nr_doors, 0) ("number of doors").AddRange(1, 4);

If you do this, the user has a nice, short name to type:

--doors 2

But the description will be used in error messages ("The number 
of doors must be between 1 and 4") and in auto-generated syntax 
summaries ("--doors ").


For a positional parameter, the user never types the name, and so 
you just do this:


Pos("number of doors", nr_doors, 0).AddRange(1, 4);

Then the syntax element we auto-generate will be "doors>" and error messages will be the same as for the equivalent 
named option.


Markus


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Markus Laker via Digitalmars-d-announce

On Thursday, 3 March 2016 at 09:33:38 UTC, Johannes Pfau wrote:
The rest of this list sounds quite good, but please reconsider 
automatically opening files: 
https://media.ccc.de/v/32c3-7130-the_perl_jam_2


I guess the scenario can't happen in D as our open file methods 
won't execute programs (!) but still


I think we're safe:

msl@james:~/d/argon$ perl -wE 'open my $fh, "ls |" or die; print 
for (<$fh>)[0..2]'

argon
argon.d
argon.html
msl@james:~/d/argon$ rdmd --eval='try auto f = std.stdio.File("ls 
|", "r"); catch (Exception e) e.msg.writeln'

Cannot open file `ls |' in mode `r' (No such file or directory)
msl@james:~/d/argon$

Of course, if you can demonstrate a vulnerability, I'll certainly 
fix it.


Markus


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Markus Laker via Digitalmars-d-announce

On Thursday, 3 March 2016 at 04:48:42 UTC, Jason White wrote:
I was also dissatisfied with std.getopt and wrote a command 
line argument parser (competition!):


https://github.com/jasonwhite/darg

Though it's not quite feature-complete yet, it does everything 
I need it to. It uses compile-time introspection to fill out 
the fields of a struct. It can also generate the help and usage 
strings at compile-time.


I've not explored D's UDAs yet, so it took a moment to click, but 
I think that's very clever.  There's an obvious run-time benefit 
to doing things like that.


Markus


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Nick Sabalausky via Digitalmars-d-announce

On 03/02/2016 02:50 PM, Markus Laker wrote:

https://github.com/markuslaker/Argon

Let me know if you do something interesting with it.

Markus



Reminds me of one I used years ago for C#: I like the approach, it's a 
good one. Getopt by comparison, while very good, always seemed like a 
kludge to accomplish a similar thing without the benefit of user 
attributes (which D lacked at the time).




Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Jacob Carlborg via Digitalmars-d-announce

On 2016-03-02 20:50, Markus Laker wrote:

https://github.com/markuslaker/Argon

Let me know if you do something interesting with it.


Does it support some longer documentation for the flags, i.e. "git 
status -h" vs "git status --help"?


--
/Jacob Carlborg


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Johannes Pfau via Digitalmars-d-announce
Am Thu, 03 Mar 2016 09:09:38 +
schrieb Markus Laker :

> * It can open files specified at the command line.  It can do a 
> simplified version of what cat(1) does and many Perl programs so, 
> and open a file specified by the user or fall back to reading 
> from stdin.  There's also a convention that the user can type "-" 
> to mean stdin or stdout, depending on the open-mode you specify.

The rest of this list sounds quite good, but please reconsider
automatically opening files:
https://media.ccc.de/v/32c3-7130-the_perl_jam_2

I guess the scenario can't happen in D as our open file methods won't
execute programs (!) but still


Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Markus Laker via Digitalmars-d-announce

On Thursday, 3 March 2016 at 04:48:42 UTC, Jason White wrote:
Looks nice! Can it support sub-commands (e.g., git status)? I 
suppose that can be done by passing through unused arguments 
and parsing those again.


Yes, that's what I'd do.

Also, you'll get more users if it's a dub package and on 
code.dlang.org.


Thanks for the tip.  I'm going to have to research those; I'm an 
experienced programmer, but I'm new to D.


I was also dissatisfied with std.getopt and wrote a command 
line argument parser (competition!):


https://github.com/jasonwhite/darg


Looks interesting.  Thanks.  I'll take a proper look this 
evening, when I can give it the time it deserves.


Markus



Re: Argon: an alternative parser for command-line arguments

2016-03-03 Thread Markus Laker via Digitalmars-d-announce

On Thursday, 3 March 2016 at 01:52:11 UTC, Chris Wright wrote:
You might want to take a minute to shill it here. What's great 
about it?


OK.  :-)

* It parses positional parameters, error-checks them and places 
them into type-safe variables: it doesn't just pick out named 
--switches and then leave you to pick everything else out of argv.


* It can open files specified at the command line.  It can do a 
simplified version of what cat(1) does and many Perl programs so, 
and open a file specified by the user or fall back to reading 
from stdin.  There's also a convention that the user can type "-" 
to mean stdin or stdout, depending on the open-mode you specify.


* You can apply range-checks to numeric input and length-checks 
to string input.


* For numeric arguments, you can change the default radix from 
decimal to hex, octal or binary, and users can choose their own 
radices at run time.


* You can error-check string input using a sequence of regular 
expressions with user-friendly error messages, and then the 
picked-apart input is ready for your program to use, so that you 
don't have to analyse it again.


* Users can abbreviate switch names and enum values.

* As well as default values, there are separate end-of-line 
defaults, so that `list-it`, `list-it --wrap' and `list-it --wrap 
132' are all valid: you might arrange things so that the first 
doesn't wrap, the second wraps to 80 columns by default, and the 
third wraps to the user-specified width.


* You can set up argument groups: between N and M of these 
arguments (e.g. you can have --to and --by, but not both); all or 
none of these arguments (can't have --length without --width or 
vice versa); and first-or-none arguments (can specify a file name 
without a block size, but not vice versa).  An argument can 
belong to more than one group, and groups can be applied to any 
mixture of positional arguments and --named-options.


* Error messages are friendly, and take into account (for 
example) whether the user specified a parameter by its long name 
or its short name, and (if there are alternatives, such as 
--colour and color) which of several long names was used.


* Users can take advantage of flexible syntax: for example, -t5, 
-t 5 and -t=5 are all permitted and, for Boolean switches, --foo 
reverses the default (typically turning a switch on), but there's 
also --foo=0, --foo=no and ==foo=false (or any abbreviations), 
and similarly for true values.


* Argon gently encourages you to improve program structure by 
moving command-line parsing and all your parameters into a 
separate class, rather than passing a dozen pieces of information 
between functions all over the code.



How do I use it?


Here's the example from Github, showing off just the basic 
functionality:


#!/usr/bin/rdmd --shebang -unittest -g -debug -w

import argon;

import std.stdio;

// Imagine a program that creates widgets of some kind.

enum Colours {black, blue, green, cyan, red, magenta, yellow, 
white}


// Write a class that inherits from argon.Handler:

class MyHandler: argon.Handler {

// Inside your class, define a set of data members.
// Argon will copy user input into these variables.

uint size;
Colours colour;
bool winged;
uint nr_windows;
string name;
argon.Indicator got_name;

// In your constructor, make a series of calls to Named(),
// Pos() and (not shown here) Incremental().  These calls 
tell Argon
// what kind of input to expect and where to deposit the 
input after

// decoding and checking it.

this() {
// The first argument is positional (meaning that the 
user specifies
// it just after the command name, with an 
--option-name), because we
// called Pos().  It's mandatory, because the Pos() 
invocation doesn't
// specify a default value or an indicator.  (Indicators 
are explained
// below.)  The AddRange() call rejects user input that 
isn't between

// 1 and 20, inclusive.
Pos("size of the widget", size).AddRange(1, 20);

// The second argument is also positional, but it's 
optional, because
// we specified a default colour: by default, our program 
will create
// a green widget.  The user specifies colours by their 
names ('black',

// 'blue', etc.), or any unambiguous abbreviation.
Pos("colour of the widget", colour, Colours.green);

// The third argument is a Boolean option that is named, 
as all
// Boolean arguments are.  That means a user who wants to 
override
// the default has to specify it by typing "--winged", or 
some
// unambiguous abbreviation of it.  We've also provided a 
-w shortcut.

//
// All Boolean arguments are optional.
Named("winged", winged) ('w');

// The fourth argument, the number of windows, is a named 
argument,
// with a long name of --windows and a short name of -i, 
and it's

Re: Argon: an alternative parser for command-line arguments

2016-03-02 Thread Jason White via Digitalmars-d-announce

On Wednesday, 2 March 2016 at 19:50:30 UTC, Markus Laker wrote:

https://github.com/markuslaker/Argon

Let me know if you do something interesting with it.

Markus


Looks nice! Can it support sub-commands (e.g., git status)? I 
suppose that can be done by passing through unused arguments and 
parsing those again.


Also, you'll get more users if it's a dub package and on 
code.dlang.org.


I was also dissatisfied with std.getopt and wrote a command line 
argument parser (competition!):


https://github.com/jasonwhite/darg

Though it's not quite feature-complete yet, it does everything I 
need it to. It uses compile-time introspection to fill out the 
fields of a struct. It can also generate the help and usage 
strings at compile-time.


Re: Argon: an alternative parser for command-line arguments

2016-03-02 Thread Chris Wright via Digitalmars-d-announce
On Wed, 02 Mar 2016 19:50:30 +, Markus Laker wrote:

> https://github.com/markuslaker/Argon
> 
> Let me know if you do something interesting with it.
> 
> Markus

You might want to take a minute to shill it here. What's great about it? 
How do I use it? Why should I use it instead of std.getopt?

This is redundant, but it means I can get an idea of your project without 
having to click the link.