www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Fixing valid options for std.getopt

reply Jens Mueller <jens.k.mueller gmx.de> writes:
Hi,

I've added some changes to getopt to change when an options is
accepted/rejected. I'm going to describe its old behavior in contrast
with its old behavior.

Consider parsing an option of Type T:

T timeout;
getopt(args, "t|timeout", &timeout);

Short options (single dash):
-t v accept (was rejected)
-t=v accept
-tv only accept for numeric v (was accepted for all types except associative
arrays)

Strange short options:
-timeout v reject
-timeout=v reject (was accepted)
-timeoutv reject

Long options (double dash):
--timeout v accept
--timeout=v accept
--timeoutv reject

Strange long options:
--t v reject (was accepted)
--t=v reject (was accepted)
--tv reject


I would like to know whether you find the new behavior better or if you
prefer the old. Or even a mix of both. Or none of the above.

The current behavior is quite simple if you remember some simple rules:
1. Short options consist of a single dash and a single character.
2. Long options consist of two dashes and more than one character.
3. Passing short and long options is supported by
   <short/long option><space+><value> and <short/long option>=<value>
4. The form <short option><value> is only supported for numeric values.
5. Anything else is not supported and an exception is thrown.

To look at the changes see here:
https://github.com/jkm/phobos/commit/b208eeb142ff5a3f189c2595b9800425646b4794
(fixes old behavior)
https://github.com/jkm/phobos/commit/a25cd2459418d462c85ab14c2d970dd413b4fb05
(introduces new behavior)

Please comment.

Jens
Aug 09 2011
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 10.08.2011 1:32, Jens Mueller wrote:
 Hi,

 I've added some changes to getopt to change when an options is
 accepted/rejected. I'm going to describe its old behavior in contrast
 with its old behavior.

 Consider parsing an option of Type T:

 T timeout;
 getopt(args, "t|timeout",&timeout);

 Short options (single dash):
 -t v accept (was rejected)
+1 on this, I recall spending about an hour trying to get why -t v is not working. Though I dunno why change -tv, I think it's widely used form and not only for numerics.
 -t=v accept
 -tv only accept for numeric v (was accepted for all types except associative
arrays)
 Strange short options:
 -timeout v reject
 -timeout=v reject (was accepted)
 -timeoutv reject
 Long options (double dash):
 --timeout v accept
 --timeout=v accept
 --timeoutv reject
 Strange long options:
 --t v reject (was accepted)
 --t=v reject (was accepted)
 --tv reject

 I would like to know whether you find the new behavior better or if you
 prefer the old. Or even a mix of both. Or none of the above.
Like all of the above except -tv.
 The current behavior is quite simple if you remember some simple rules:
 1. Short options consist of a single dash and a single character.
 2. Long options consist of two dashes and more than one character.
 3. Passing short and long options is supported by
     <short/long option><space+><value>  and<short/long option>=<value>
 4. The form<short option><value>  is only supported for numeric values.
Can't figure out the reason for 4, could you clarify a bit?
 5. Anything else is not supported and an exception is thrown.

 To look at the changes see here:
 https://github.com/jkm/phobos/commit/b208eeb142ff5a3f189c2595b9800425646b4794
(fixes old behavior)
 https://github.com/jkm/phobos/commit/a25cd2459418d462c85ab14c2d970dd413b4fb05
(introduces new behavior)

 Please comment.

 Jens
-- Dmitry Olshansky
Aug 09 2011
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 On 10.08.2011 1:32, Jens Mueller wrote:
 Hi,
 
 I've added some changes to getopt to change when an options is
 accepted/rejected. I'm going to describe its old behavior in contrast
 with its old behavior.
 
 Consider parsing an option of Type T:
 
 T timeout;
 getopt(args, "t|timeout",&timeout);
 
 Short options (single dash):
 -t v accept (was rejected)
+1 on this, I recall spending about an hour trying to get why -t v is not working. Though I dunno why change -tv, I think it's widely used form and not only for numerics.
 -t=v accept
 -tv only accept for numeric v (was accepted for all types except
 associative arrays) Strange short options:
 -timeout v reject
 -timeout=v reject (was accepted)
 -timeoutv reject
 Long options (double dash):
 --timeout v accept
 --timeout=v accept
 --timeoutv reject
 Strange long options:
 --t v reject (was accepted)
 --t=v reject (was accepted)
 --tv reject
 
 I would like to know whether you find the new behavior better or if you
 prefer the old. Or even a mix of both. Or none of the above.
Like all of the above except -tv.
 The current behavior is quite simple if you remember some simple rules:
 1. Short options consist of a single dash and a single character.
 2. Long options consist of two dashes and more than one character.
 3. Passing short and long options is supported by
 
 <short/long option><space+><value> and<short/long option>=<value>
 
 4. The form<short option><value> is only supported for numeric values.
Can't figure out the reason for 4, could you clarify a bit?
Normally, -tv would mean that you passed _two_ flags - the t and v flags. -t2 works because 2 can't be a flag. I'm pretty sure that this proposed behavior is normal. - Jonathan M Davis
Aug 09 2011
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Dmitry Olshansky wrote:
 On 10.08.2011 1:32, Jens Mueller wrote:
Hi,

I've added some changes to getopt to change when an options is
accepted/rejected. I'm going to describe its old behavior in contrast
with its old behavior.

Consider parsing an option of Type T:

T timeout;
getopt(args, "t|timeout",&timeout);

Short options (single dash):
-t v accept (was rejected)
+1 on this, I recall spending about an hour trying to get why -t v is not working. Though I dunno why change -tv, I think it's widely used form and not only for numerics.
I believe it's only safe for numerics. Consider the following example. -tsomestring was passed because -t is supported short option but your program also accepts the boolean long option --tsomestring. Now forgetting a single dash will change the behavior silently. One can argue it's the programmer's job to not define options in this combination. Basically whenever you define a non-boolean short option don't specify a long option starting with the same letter. Allowing it only for numeric values avoids having this rule. Thus, it's less error-prone I think. Jens
Aug 10 2011
prev sibling next sibling parent reply Bernard Helyer <b.helyer gmail.com> writes:
For SDC I've had to resort to filtering through args before getopt and 
replacing -m32 with --m32. The output flag needs to have that treatment 
too (seriously, `sdc -o=foo.bin foo.d` is just weird). I lurve these 
changes and give them two thumbs up.

d-n_n-b
Aug 09 2011
parent reply Bernard Helyer <b.helyer gmail.com> writes:
On Tue, 09 Aug 2011 22:34:29 +0000, Bernard Helyer wrote:

 For SDC I've had to resort to filtering through args before getopt and
 replacing -m32 with --m32. The output flag needs to have that treatment
 too (seriously, `sdc -o=foo.bin foo.d` is just weird). I lurve these
 changes and give them two thumbs up.
 
 d-n_n-b
That said, I would like -ofoo.bin to work as well. Perhaps a flag to allow it?
Aug 09 2011
next sibling parent Bernard Helyer <b.helyer gmail.com> writes:
On Tue, 09 Aug 2011 22:35:44 +0000, Bernard Helyer wrote:
 
 That said, I would like -ofoo.bin to work as well. Perhaps a flag to
 allow it?
Although I could just translate that by hand. Not the end of the world.
Aug 09 2011
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 10.08.2011 2:35, Bernard Helyer wrote:
 On Tue, 09 Aug 2011 22:34:29 +0000, Bernard Helyer wrote:

 For SDC I've had to resort to filtering through args before getopt and
 replacing -m32 with --m32. The output flag needs to have that treatment
 too (seriously, `sdc -o=foo.bin foo.d` is just weird). I lurve these
 changes and give them two thumbs up.

 d-n_n-b
That said, I would like -ofoo.bin to work as well. Perhaps a flag to allow it?
Same here, though not a big deal. Taking Jonathan's comment into account, how about allowing it when bundling of arguments is disabled? -- Dmitry Olshansky
Aug 09 2011
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 On 10.08.2011 2:35, Bernard Helyer wrote:
 On Tue, 09 Aug 2011 22:34:29 +0000, Bernard Helyer wrote:
 For SDC I've had to resort to filtering through args before getopt and
 replacing -m32 with --m32. The output flag needs to have that treatment
 too (seriously, `sdc -o=foo.bin foo.d` is just weird). I lurve these
 changes and give them two thumbs up.
 
 d-n_n-b
That said, I would like -ofoo.bin to work as well. Perhaps a flag to allow it?
Same here, though not a big deal. Taking Jonathan's comment into account, how about allowing it when bundling of arguments is disabled?
I'm not sure that it's a bad idea to give some options on how getopt works (e.g. a way to disallow the bundling of arguments), but in general it should probably work like the C getopt as far as what it accepts goes, and I believe that these changes bring it more in line with the C getopt. Typically, the only way to use multi-character flags is --, and when you use -, every all of the characters immediately following it are individual flags. It's _very_ odd for dmd to have flags which are multi-character but only take a single -, and I'd argue that that's not behavior which should be emulated. So, in general, I think that these changes are very much the right approach. However, it may be reasonable to have a way to alter some of getopt's behavior for those who want it. - Jonathan M Davis
Aug 09 2011
parent reply David Nadlinger <see klickverbot.at> writes:
On 8/10/11 2:57 AM, Jonathan M Davis wrote:
 It's _very_ odd for dmd to have flags which are multi-character but only take
 a single -, and I'd argue that that's not behavior which should be emulated.
I don't know what your definition of odd is, but some counterexamples that immediately come to my mind: GCC, just about every Java VM, LLVM/Clang, … David
Aug 09 2011
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 On 8/10/11 2:57 AM, Jonathan M Davis wrote:
 It's _very_ odd for dmd to have flags which are multi-character but only
 take a single -, and I'd argue that that's not behavior which should be
 emulated.
I don't know what your definition of odd is, but some counterexamples that immediately come to my mind: GCC, just about every Java VM, LLVM/Clang, …
I mean that most programs don't work that way - at least not the ones that I've used. Some _do_ work that way, but in my experience, it's abnormal. I do find it interesting though that all of the examples that you give are compilers or related to compilers. Assuming that they're the prime examples of programs that work that way, I wonder if there's something particular about compilers which makes it so that they don't follow the more general trend (the overabundance of flags that they have perhaps?). But maybe my experience in the matter is just lopsided. - Jonathan M Davis
Aug 09 2011
prev sibling next sibling parent reply Andrew Wiley <wiley.andrew.j gmail.com> writes:
On Tue, Aug 9, 2011 at 6:01 PM, David Nadlinger <see klickverbot.at> wrote:

 On 8/10/11 2:57 AM, Jonathan M Davis wrote:

 It's _very_ odd for dmd to have flags which are multi-character but only
 take
 a single -, and I'd argue that that's not behavior which should be
 emulated.
I don't know what your definition of odd is, but some counterexamples tha=
t
 immediately come to my mind: GCC, just about every Java VM, LLVM/Clang, =
=85
 David
I can't think of an example with GCC. It does things like -fdisable-some-option, but I can't think of a multicharacter _flag_. Also, I've always felt that the way Java VMs take arguments feels like it grew organically into something terrible (-Xmx512m! -Xkill-the-rabbit!). I can't speak to LLVM/Clang. Could you post a few specific examples? It's hard to generalize with this sort of thing. (And don't even get me started on Windows. Should I be using /? or -? or = =3D? or -help or --FML-this-OS-doesn't-support-CLI)
Aug 09 2011
parent reply David Nadlinger <see klickverbot.at> writes:
On 8/10/11 3:57 AM, Andrew Wiley wrote:
 On Tue, Aug 9, 2011 at 6:01 PM, David Nadlinger <see klickverbot.at
 <mailto:see klickverbot.at>> wrote:
     I don't know what your definition of odd is, but some
     counterexamples that immediately come to my mind: GCC, just about
     every Java VM, LLVM/Clang, …

     David
 I can't think of an example with GCC. It does things like
 -fdisable-some-option, but I can't think of a multicharacter _flag_.
Just have a look at its manpage? -combine, -pipe, -pedantic, -trigraphs, etc. David
Aug 10 2011
parent reply Brad Roberts <braddr slice-2.puremagic.com> writes:
On Thu, 11 Aug 2011, David Nadlinger wrote:

 On 8/10/11 3:57 AM, Andrew Wiley wrote:
 On Tue, Aug 9, 2011 at 6:01 PM, David Nadlinger <see klickverbot.at
 <mailto:see klickverbot.at>> wrote:
     I don't know what your definition of odd is, but some
     counterexamples that immediately come to my mind: GCC, just about
     every Java VM, LLVM/Clang, ?
 
     David
 I can't think of an example with GCC. It does things like
 -fdisable-some-option, but I can't think of a multicharacter _flag_.
Just have a look at its manpage? -combine, -pipe, -pedantic, -trigraphs, etc. David
While it's not hard to find some software the deviates from the behavior of getopt based parameters, I think you'll notice that the majority of it is ancient software. Like any ancient system, there's a cost/benefit to changes that often falls on the "don't change it" side. I greatly prefer the predictability and standardization that getopt style parameter handling has brought to the world and strongly urge NOT going very far with expanding its capabilities. DMD is a particularly good example of bad parameter handling, imho. My 2 cents, Brad
Aug 10 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On Windoze I think it's pretty standard to use -longname. I really
like forward-slash style arguments too (boo-hoo for you posixers,
idk.).
Aug 10 2011
parent Don <nospam nospam.com> writes:
Andrej Mitrovic wrote:
 On Windoze I think it's pretty standard to use -longname. I really
 like forward-slash style arguments too (boo-hoo for you posixers,
 idk.).
Does anything on Windows use --longname, apart from direct ports of posix tools?
Aug 10 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
David Nadlinger wrote:
 On 8/10/11 2:57 AM, Jonathan M Davis wrote:
It's _very_ odd for dmd to have flags which are multi-character but only take
a single -, and I'd argue that that's not behavior which should be emulated.
I don't know what your definition of odd is, but some counterexamples that immediately come to my mind: GCC, just about every Java VM, LLVM/Clang, $B!D(B
I've also come across this. I first thought it's a GNU vs. something other issue. But gcc proves me wrong. The basic difference is whether a long option has to have two dashes. If it doesn't, then bundling of short options cannot be supported as Mike Wey pointed out some time ago. I often use this bundling when using tar, e.g. tar -xf <file>. Maybe the above tools need no bundling. Jens
Aug 10 2011
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Andrew Wiley wrote:
 On Tue, Aug 9, 2011 at 6:01 PM, David Nadlinger <see klickverbot.at> wrote:
 
 On 8/10/11 2:57 AM, Jonathan M Davis wrote:

 It's _very_ odd for dmd to have flags which are multi-character but only
 take
 a single -, and I'd argue that that's not behavior which should be
 emulated.
I don't know what your definition of odd is, but some counterexamples that immediately come to my mind: GCC, just about every Java VM, LLVM/Clang, $B!D(B David
I can't think of an example with GCC. It does things like -fdisable-some-option, but I can't think of a multicharacter _flag_.
There are -pg and -pedantic. Jens
Aug 10 2011
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 On 10.08.2011 2:35, Bernard Helyer wrote:
 On Tue, 09 Aug 2011 22:34:29 +0000, Bernard Helyer wrote:
 For SDC I've had to resort to filtering through args before getopt and
 replacing -m32 with --m32. The output flag needs to have that treatment
 too (seriously, `sdc -o=foo.bin foo.d` is just weird). I lurve these
 changes and give them two thumbs up.
 
 d-n_n-b
That said, I would like -ofoo.bin to work as well. Perhaps a flag to allow it?
Same here, though not a big deal. Taking Jonathan's comment into account, how about allowing it when bundling of arguments is disabled?
I'm not sure that it's a bad idea to give some options on how getopt works (e.g. a way to disallow the bundling of arguments), but in general it should probably work like the C getopt as far as what it accepts goes, and I believe that these changes bring it more in line with the C getopt.
I will check man 3 getopt.
 Typically, the only way to use multi-character flags is --, and when you use 
 -, every all of the characters immediately following it are individual flags. 
 It's _very_ odd for dmd to have flags which are multi-character but only take 
 a single -, and I'd argue that that's not behavior which should be emulated.
 
 So, in general, I think that these changes are very much the right approach. 
 However, it may be reasonable to have a way to alter some of getopt's behavior 
 for those who want it.
Supporting a short option like -ofoo.bin may be error prone. Let's say I also have the long boolean option --obar. Now somebody passes -obar but intended --obar. Is this problematic? Jens
Aug 10 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-08-09 23:32, Jens Mueller wrote:
 Hi,

 I've added some changes to getopt to change when an options is
 accepted/rejected. I'm going to describe its old behavior in contrast
 with its old behavior.

 Consider parsing an option of Type T:

 T timeout;
 getopt(args, "t|timeout",&timeout);

 Short options (single dash):
 -t v accept (was rejected)
 -t=v accept
 -tv only accept for numeric v (was accepted for all types except associative
arrays)

 Strange short options:
 -timeout v reject
 -timeout=v reject (was accepted)
 -timeoutv reject

 Long options (double dash):
 --timeout v accept
 --timeout=v accept
 --timeoutv reject

 Strange long options:
 --t v reject (was accepted)
 --t=v reject (was accepted)
 --tv reject


 I would like to know whether you find the new behavior better or if you
 prefer the old. Or even a mix of both. Or none of the above.

 The current behavior is quite simple if you remember some simple rules:
 1. Short options consist of a single dash and a single character.
 2. Long options consist of two dashes and more than one character.
 3. Passing short and long options is supported by
     <short/long option><space+><value>  and<short/long option>=<value>
 4. The form<short option><value>  is only supported for numeric values.
 5. Anything else is not supported and an exception is thrown.

 To look at the changes see here:
 https://github.com/jkm/phobos/commit/b208eeb142ff5a3f189c2595b9800425646b4794
(fixes old behavior)
 https://github.com/jkm/phobos/commit/a25cd2459418d462c85ab14c2d970dd413b4fb05
(introduces new behavior)

 Please comment.

 Jens
I like it, but I see no reason to accept <short option><value>. I've never understood why anyone would want to accept that. For example, looking at DMD's help message is often hard to tell where an option end and the value beings, i.e. -offilename. -- /Jacob Carlborg
Aug 09 2011
parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Jacob Carlborg wrote:
 On 2011-08-09 23:32, Jens Mueller wrote:
Hi,

I've added some changes to getopt to change when an options is
accepted/rejected. I'm going to describe its old behavior in contrast
with its old behavior.

Consider parsing an option of Type T:

T timeout;
getopt(args, "t|timeout",&timeout);

Short options (single dash):
-t v accept (was rejected)
-t=v accept
-tv only accept for numeric v (was accepted for all types except associative
arrays)

Strange short options:
-timeout v reject
-timeout=v reject (was accepted)
-timeoutv reject

Long options (double dash):
--timeout v accept
--timeout=v accept
--timeoutv reject

Strange long options:
--t v reject (was accepted)
--t=v reject (was accepted)
--tv reject


I would like to know whether you find the new behavior better or if you
prefer the old. Or even a mix of both. Or none of the above.

The current behavior is quite simple if you remember some simple rules:
1. Short options consist of a single dash and a single character.
2. Long options consist of two dashes and more than one character.
3. Passing short and long options is supported by
    <short/long option><space+><value>  and<short/long option>=<value>
4. The form<short option><value>  is only supported for numeric values.
5. Anything else is not supported and an exception is thrown.

To look at the changes see here:
https://github.com/jkm/phobos/commit/b208eeb142ff5a3f189c2595b9800425646b4794
(fixes old behavior)
https://github.com/jkm/phobos/commit/a25cd2459418d462c85ab14c2d970dd413b4fb05
(introduces new behavior)

Please comment.

Jens
I like it, but I see no reason to accept <short option><value>. I've never understood why anyone would want to accept that. For example, looking at DMD's help message is often hard to tell where an option end and the value beings, i.e. -offilename.
I think short options with no space are supported because a number of people (don't know how many) type no spaces. For example $ ping -c1 <some host> vs $ ping -c 1 <some host> Both work. ping's documentation explains the -c option using a space. I.e. the documentation is easy to read. Supporting it does not break anything for you. And this way it does no harm to anybody. The only reason for dropping it may be inconsistency, i.e. why does it only work for numeric values. Jens
Aug 10 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-08-10 09:26, Jens Mueller wrote:
 I think short options with no space are supported because a number of
 people (don't know how many) type no spaces.
 For example
 $ ping -c1<some host>
 vs
 $ ping -c 1<some host>

 Both work. ping's documentation explains the -c option using a space.
 I.e. the documentation is easy to read.
 Supporting it does not break anything for you. And this way it does no
 harm to anybody. The only reason for dropping it may be inconsistency,
 i.e. why does it only work for numeric values.

 Jens
Just saying I don't like that. I won't break anything for me but it will let people continue to implement tools which uses this syntax. -- /Jacob Carlborg
Aug 10 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, August 10, 2011 09:51:32 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On 10.08.2011 2:35, Bernard Helyer wrote:
 On Tue, 09 Aug 2011 22:34:29 +0000, Bernard Helyer wrote:
 For SDC I've had to resort to filtering through args before
 getopt and replacing -m32 with --m32. The output flag needs
 to have that treatment too (seriously, `sdc -o=foo.bin foo.d`
 is just weird). I lurve these changes and give them two
 thumbs up.
 
 d-n_n-b
That said, I would like -ofoo.bin to work as well. Perhaps a flag to allow it?
Same here, though not a big deal. Taking Jonathan's comment into account, how about allowing it when bundling of arguments is disabled?
I'm not sure that it's a bad idea to give some options on how getopt works (e.g. a way to disallow the bundling of arguments), but in general it should probably work like the C getopt as far as what it accepts goes, and I believe that these changes bring it more in line with the C getopt.
I will check man 3 getopt.
 Typically, the only way to use multi-character flags is --, and when you
 use -, every all of the characters immediately following it are
 individual flags. It's _very_ odd for dmd to have flags which are
 multi-character but only take a single -, and I'd argue that that's not
 behavior which should be emulated.
 
 So, in general, I think that these changes are very much the right
 approach. However, it may be reasonable to have a way to alter some of
 getopt's behavior for those who want it.
Supporting a short option like -ofoo.bin may be error prone. Let's say I also have the long boolean option --obar. Now somebody passes -obar but intended --obar. Is this problematic?
Personally, I'll all for requiring that multi-character flags use -- and not -, and I _do_ think that it's problematic to allow multi-character flags to use -. However, I'm not entirely against having a way to tell getopt to accept multi- character flags with a single - if people want that and it can work reasonably without causing problems as long as people are careful about the flags that their program accepts. It definitely shouldn't be the default behavior though. However, given that getopt is a single function call with a variadic argument, the only way that I can think of that you'd be able to tell it whether to accept multi-character flags with a single - would be a template argument, and I'd be very concerned that accepting multi-character flags with a single - would make getopt overly complicated. I'd have to examine the implementation though to see how much worse it would make it. It would probably have to change so that there is no difference between - and -- (both are treated like --), except that --ofbar.bin isn't accepted with your changes (you need either --of bar.bin or --of=bar.bin). So, treating - like -- isn't really going to do what the people who want multi-character flags with - would want anyway (and I do think that disallowing --ofbar.bin is the correct decision, so I'm not advising changing that). So, I don't know. I'm generally against programs having multi-character flags which work with -, and I'm definitely afraid that allowing such things with a separate setting for getopt is going to overcomplicate getopt. Regardless, I would be _completely_ against the default allowing it. So, I'd prefer that getopt just have the one set of behaviors and disallow multi-character flags with -, but I don't want to just reject it out of hand if others want it and it's reasonably feasible without overcomplicating things. The real question is how the C getopt works, since that's what our getopt is at least supposed to be modeled after (and given that it has the same name, it's not unreasonable to expect essentially the same behavior). However, a quick glance at getopt's man page makes it seem far more complicated than our getopt, which I would consider to be undesirable. So, we may not want to quite follow the C getopt. However, we should definitely look at how it handles the flags and what it allows and try for something similar. - Jonathan M Davis
Aug 10 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 Personally, I'll all for requiring that multi-character flags use -- and not
-, 
 and I _do_ think that it's problematic to allow multi-character flags to use
-. 
 However, I'm not entirely against having a way to tell getopt to accept multi-
 character flags with a single - if people want that and it can work reasonably 
 without causing problems as long as people are careful about the flags that 
 their program accepts. It definitely shouldn't be the default behavior though.
If I add support for it, it won't be default. I'm thinking about adding a configuration option multiCharDoubleDashOnly (default), multiCharSingleDoubleDash (allow additionally a single dash), and multiCharSingleDashOnly (only allows single dash for long options). multiCharSingleDoubleDash or multiCharSingleDashOnly imply that bundling is turned off.
 However, given that getopt is a single function call with a variadic argument, 
 the only way that I can think of that you'd be able to tell it whether to 
 accept multi-character flags with a single - would be a template argument, and 
 I'd be very concerned that accepting multi-character flags with a single - 
 would make getopt overly complicated. I'd have to examine the implementation 
 though to see how much worse it would make it.
Using getopt's config enum should make it possible as I outlined above. I hope this change keeps the code simple.
 It would probably have to change so that there is no difference
 between - and -- (both are treated like --), except that --ofbar.bin
 isn't accepted with your changes (you need either --of bar.bin or
 --of=bar.bin). So, treating - like -- isn't really going to do what
 the people who want multi-character flags with - would want anyway
 (and I do think that disallowing --ofbar.bin is the correct decision,
 so I'm not advising changing that).
Yeah. Long options (with whatever many dashes) and no space or equal sign as separator is confusing. I'm only going to add this if there is a strong case for it.
 So, I don't know. I'm generally against programs having multi-character flags 
 which work with -, and I'm definitely afraid that allowing such things with a 
 separate setting for getopt is going to overcomplicate getopt. Regardless, I 
 would be _completely_ against the default allowing it. So, I'd prefer that 
 getopt just have the one set of behaviors and disallow multi-character flags 
 with -, but I don't want to just reject it out of hand if others want it and 
 it's reasonably feasible without overcomplicating things.
So far we only have seen some examples of tools that are using single dash multi-character options. Nobody so far has argued that this is a good way of doing it which is kind of interesting.
 The real question is how the C getopt works, since that's what our getopt is 
 at least supposed to be modeled after (and given that it has the same name, 
 it's not unreasonable to expect essentially the same behavior). However, a 
 quick glance at getopt's man page makes it seem far more complicated than our 
 getopt, which I would consider to be undesirable. So, we may not want to quite 
 follow the C getopt. However, we should definitely look at how it handles the 
 flags and what it allows and try for something similar.
D's getopt is actually modeled after Perl's Getopt::Long (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is actually different in the details but I believe D's getopt is easy to use in comparison. Next I will add support for -tv where v can be of arbitrary type to support -ofile.bin. This behavior is configurable via noSpaceForShortOption. If set it implies no bundling. The other behavior is noSpaceForShortOptionNumeric. I'm not sure yet whether defaulting to noSpaceForShortOptionNumeric is good as it breaks code. Many thanks to all for sharing your opinions. Jens
Aug 10 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, August 10, 2011 15:28 Jens Mueller wrote:
 D's getopt is actually modeled after Perl's Getopt::Long
 (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is actually
 different in the details but I believe D's getopt is easy to use in
 comparison.
Well, D's getopt should be fairly standard it terms of default behavior, and it should be reasonably easy to use. As it stands, it's pretty easy to use. I think that my main gripe is http://d.puremagic.com/issues/show_bug.cgi?id=5228 , but better sorting out its behavior like you're doing is a definite improvement IMHO.
From the little I looked at Linux' getopt, it was pretty bad in terms of 
usability in comparison. So, I defintely don't think that we should follow it in _that_ regard. But I do think that the default settings should follow what is generally standard as far as how flags function and how they accept arguments. - Jonathan M Davis
Aug 10 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 On Wednesday, August 10, 2011 15:28 Jens Mueller wrote:
 D's getopt is actually modeled after Perl's Getopt::Long
 (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is actually
 different in the details but I believe D's getopt is easy to use in
 comparison.
Well, D's getopt should be fairly standard it terms of default behavior, and it should be reasonably easy to use. As it stands, it's pretty easy to use. I think that my main gripe is http://d.puremagic.com/issues/show_bug.cgi?id=5228 , but better sorting out its behavior like you're doing is a definite improvement IMHO.
Didn't know of this report. There are also other regarding getopt that I should check. I will have a look when I'm finished with the current changes. Since the report is concerned with exception reporting it'll be nice to have some specific examples where the thrown exception is not good enough. Maybe you can add the specific usage examples that you found. Jens
Aug 11 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, August 11, 2011 10:02:38 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Wednesday, August 10, 2011 15:28 Jens Mueller wrote:
 D's getopt is actually modeled after Perl's Getopt::Long
 (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is
 actually
 different in the details but I believe D's getopt is easy to use in
 comparison.
Well, D's getopt should be fairly standard it terms of default behavior, and it should be reasonably easy to use. As it stands, it's pretty easy to use. I think that my main gripe is http://d.puremagic.com/issues/show_bug.cgi?id=5228 , but better sorting out its behavior like you're doing is a definite improvement IMHO.
Didn't know of this report. There are also other regarding getopt that I should check. I will have a look when I'm finished with the current changes. Since the report is concerned with exception reporting it'll be nice to have some specific examples where the thrown exception is not good enough. Maybe you can add the specific usage examples that you found.
I'd have to mess around with getopt for a bit to get a good feel for exactly what I'd like out of a specific exception, but the prime example would be that a GetOptException would be able to tell you exactly which flag failed and what the value was that was used with it. A ConvException is incredibly generic about the problem. If I had --flag=stuff --option=stuff and one of those was supposed to take an int instead of a string, then the ConvException is only going to tell you what the string was that faild to convert - not what flag it was for - and regardless, it doesn't tell you in a way that's easy for the program to determine what happened. Ideally, _no_ exceptions would be seen by the user, and for the program to be able to give the user adequate feedback on which flag failed and why it failed, the program needs an exception which actually tells it what failed and why. Right now, all it gets is that a conversion in one of the flags failed, which just doesn't cut it if you want to figure out what went wrong so that you can give the user decent feedback. - Jonathan M Davis
Aug 11 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 On Thursday, August 11, 2011 10:02:38 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Wednesday, August 10, 2011 15:28 Jens Mueller wrote:
 D's getopt is actually modeled after Perl's Getopt::Long
 (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is
 actually
 different in the details but I believe D's getopt is easy to use in
 comparison.
Well, D's getopt should be fairly standard it terms of default behavior, and it should be reasonably easy to use. As it stands, it's pretty easy to use. I think that my main gripe is http://d.puremagic.com/issues/show_bug.cgi?id=5228 , but better sorting out its behavior like you're doing is a definite improvement IMHO.
Didn't know of this report. There are also other regarding getopt that I should check. I will have a look when I'm finished with the current changes. Since the report is concerned with exception reporting it'll be nice to have some specific examples where the thrown exception is not good enough. Maybe you can add the specific usage examples that you found.
I'd have to mess around with getopt for a bit to get a good feel for exactly what I'd like out of a specific exception, but the prime example would be that a GetOptException would be able to tell you exactly which flag failed and what the value was that was used with it. A ConvException is incredibly generic about the problem. If I had --flag=stuff --option=stuff and one of those was supposed to take an int instead of a string, then the ConvException is only going to tell you what the string was that faild to convert - not what flag it was for - and regardless, it doesn't tell you in a way that's easy for the program to determine what happened.
I see.
 Ideally, _no_ exceptions would be seen by the user, and for the program to be 
 able to give the user adequate feedback on which flag failed and why it
failed, 
 the program needs an exception which actually tells it what failed and why. 
 Right now, all it gets is that a conversion in one of the flags failed, which 
 just doesn't cut it if you want to figure out what went wrong so that you can 
 give the user decent feedback.
Turning the exception into a useful message could be actually done by std.log. In release mode std.log's format string may be changed. But there are other options as well. I will look into providing more useful exceptions which are needed either case. Jens
Aug 11 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, August 11, 2011 14:16 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Thursday, August 11, 2011 10:02:38 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Wednesday, August 10, 2011 15:28 Jens Mueller wrote:
 D's getopt is actually modeled after Perl's Getopt::Long
 (http://perldoc.perl.org/Getopt/Long.html). Linux's getopt is
 actually
 different in the details but I believe D's getopt is easy to use in
 comparison.
Well, D's getopt should be fairly standard it terms of default behavior, and it should be reasonably easy to use. As it stands, it's pretty easy to use. I think that my main gripe is http://d.puremagic.com/issues/show_bug.cgi?id=5228 , but better sorting out its behavior like you're doing is a definite improvement IMHO.
Didn't know of this report. There are also other regarding getopt that I should check. I will have a look when I'm finished with the current changes. Since the report is concerned with exception reporting it'll be nice to have some specific examples where the thrown exception is not good enough. Maybe you can add the specific usage examples that you found.
I'd have to mess around with getopt for a bit to get a good feel for exactly what I'd like out of a specific exception, but the prime example would be that a GetOptException would be able to tell you exactly which flag failed and what the value was that was used with it. A ConvException is incredibly generic about the problem. If I had --flag=stuff --option=stuff and one of those was supposed to take an int instead of a string, then the ConvException is only going to tell you what the string was that faild to convert - not what flag it was for - and regardless, it doesn't tell you in a way that's easy for the program to determine what happened.
I see.
 Ideally, _no_ exceptions would be seen by the user, and for the program
 to be able to give the user adequate feedback on which flag failed and
 why it failed, the program needs an exception which actually tells it
 what failed and why. Right now, all it gets is that a conversion in one
 of the flags failed, which just doesn't cut it if you want to figure out
 what went wrong so that you can give the user decent feedback.
Turning the exception into a useful message could be actually done by std.log. In release mode std.log's format string may be changed. But there are other options as well. I will look into providing more useful exceptions which are needed either case.
std.log may be able to help, but getopt really doesn't have anything to do with logging. The primary issue is that it's currently very difficult to programmatically handle failures from getopt. It's difficult to do much better than print the exception message or that there was a general failure. To be able to programmatically handle the failure, you need specific stuff like which flag failed, what value it was given, and why it failed. When all you really have is the type of the exception and its message, it's not really enough to handle it programmatically. - Jonathan M Davis
Aug 11 2011