Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.97k stars 558 forks source link

Getopt::Long doesn't distinguish between '-e' and '-E' #4602

Closed p5pRT closed 22 years ago

p5pRT commented 22 years ago

Migrated from rt.perl.org#7928 (status was 'resolved')

Searchable as RT7928$

p5pRT commented 22 years ago

From @abigail

Wanting to create a utility that takes both long and short options\, I decided to use Getopt​::Long to do my option parsing.

Unfortunally\, it looks as if it cannot distinguish between one letter options that differ in case. I looked in the source\, and when there's a one-letter option in upper case\, it's going to make the lower case variant an "alias" for this option. This contradicts the documentation that says​:

  ignore_case (default​: enabled)   If enabled\, case is ignored when matching long   option names. Single character options will be   treated case-sensitive.

  Note​: disabling "ignore_case" also disables   "ignore_case_always".

Only by specifically calling C\<Getopt​::Long​::Configure 'no_ignore_case'>\, Getopt​::Long is able to distinguish between '-e' and '-E'.

I do not know whether the documentation is wrong\, or the source.

(This is Getopt​::Long version 2.26_03).

  $ cat x.pl   #!/opt/bleadperl/bin/perl -w

  use strict;

  use Getopt​::Long;

  GetOptions e => sub {print "Found lowercase `e'\n"}\,   E => sub {print "Found uppercase `E'\n"};

  __END__   $ ./x.pl -E   Found uppercase `E'   $ ./x.pl -e   Found uppercase `E'

Abigail

Perl Info ``` Flags: category=library severity=medium Site configuration information for perl v5.7.2: Configured by abigail at Fri Nov 23 17:03:17 CET 2001. Summary of my perl5 (revision 5.0 version 7 subversion 2 patch 13197) configuration: Platform: osname=linux, osvers=2.4.5, archname=i686-linux-64int-ld uname='linux hermione 2.4.5 #6 fri jun 22 01:38:20 pdt 2001 i686 unknown ' config_args='-Doptimize=-g -Dusedevel -Duse64bitall -Dusemorebits -Uversiononly -des -Dprefix=/opt/bleadperl' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=define usemymalloc=n, bincompat5005=define Compiler: cc='cc', ccflags ='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include -I/opt/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-g', cppflags='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include -I/opt/local/include' ccversion='', gccversion='2.95.3 20010315 (release)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long long', ivsize=8, nvtype='long double', nvsize=12, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib -L/opt/local/lib' libpth=/usr/local/lib /opt/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldl -lm -lc -lcrypt -lutil perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil libc=/lib/libc-2.2.3.so, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib -L/opt/local/lib' Locally applied patches: DEVEL13165 @INC for perl v5.7.2: /opt/bleadperl/lib/5.7.2/i686-linux-64int-ld /opt/bleadperl/lib/5.7.2 /opt/bleadperl/lib/site_perl/5.7.2/i686-linux-64int-ld /opt/bleadperl/lib/site_perl/5.7.2 /opt/bleadperl/lib/site_perl . Environment for perl v5.7.2: HOME=/home/abigail LANG (unset) LANGUAGE (unset) LC_ALL=POSIX LD_LIBRARY_PATH=/home/abigail/Lib:/usr/local/lib:/usr/lib:/lib:/usr/X11R6/lib:/opt/gnome/lib LOGDIR (unset) PATH=/home/abigail/Bin:/opt/perl/bin:/usr/local/bin:/usr/local/X11/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/games:/opt/povray/bin:/opt/gnome/bin:/opt/opera/bin:/usr/share/texmf/bin:/opt/Acrobat4/bin:/opt/java/blackdown/j2sdk1.3.1/bin:/usr/local/games/bin:/opt/gnuplot/bin PERLDIR=/opt/perl PERL_BADLANG (unset) SHELL=/usr/bin/bash ```
p5pRT commented 22 years ago

From @sciurius

I think it's a documentation issue. The concept of 'single character option' implies the use of the 'bundling' configuration option. Without bundling\, a single character option is just a long option of one character\, and taken case independent.

  % cat t1.pl   #!/opt/bleadperl/bin/perl -w   use strict;   use Getopt​::Long qw(​:config debug);   GetOptions e => sub {print "Found lowercase `e'\n"}\,   E => sub {print "Found uppercase `E'\n"};

  % perl -w t1.pl   GetOpt​::Long 2.2603 ($Revision​: 2.47 $) called from package "main".   ARGV​: ()   autoabbrev=1\,bundling=0\,getopt_compat=1\,gnu_compat=0\,order=1\,   ignorecase=1\,passthrough=0\,genprefix="(--|-|\+)".   => link "e" to CODE(0x8163960)   => link "E" to CODE(0x80fa8b4)   => $opctl{e} = ARRAY(0x80eace8) [""\,M\,$\,\\,\\,"E"]

There's only one option in this case.

  % cat t2.pl   #!/opt/bleadperl/bin/perl -w   use strict;   use Getopt​::Long qw(​:config debug bundling);   GetOptions e => sub {print "Found lowercase `e'\n"}\,   E => sub {print "Found uppercase `E'\n"};

  % perl -w t2.pl   GetOpt​::Long 2.2603 ($Revision​: 2.47 $) called from package "main".   ARGV​: ()   autoabbrev=1\,bundling=1\,getopt_compat=1\,gnu_compat=0\,order=1\,   ignorecase=1\,passthrough=0\,genprefix="(--|-|\+)".   => link "e" to CODE(0x8172a34)   => link "E" to CODE(0x8172b30)   => $opctl{e} = ARRAY(0x8182df0) [""\,M\,$\,\\,\\,"e"]   $opctl{E} = ARRAY(0x80eace8) [""\,M\,$\,\\,\\,"E"]

Now\, there are two.

Would this be more clear​:

  ignore_case (default​: enabled)   If enabled\, case is ignored when matching long   option names. If\, however\, bundling is enabled as   well\, single character options will be treated   case-sensitive.

-- Johan

p5pRT commented 22 years ago

From @sciurius

I think it's a documentation issue. The concept of 'single character option' implies the use of the 'bundling' configuration option. Without bundling\, a single character option is just a long option of one character\, and taken case independent.

  % cat t1.pl   #!/opt/bleadperl/bin/perl -w   use strict;   use Getopt​::Long qw(​:config debug);   GetOptions e => sub {print "Found lowercase `e'\n"}\,   E => sub {print "Found uppercase `E'\n"};

  % perl -w t1.pl   GetOpt​::Long 2.2603 ($Revision​: 2.47 $) called from package "main".   ARGV​: ()   autoabbrev=1\,bundling=0\,getopt_compat=1\,gnu_compat=0\,order=1\,   ignorecase=1\,passthrough=0\,genprefix="(--|-|\+)".   => link "e" to CODE(0x8163960)   => link "E" to CODE(0x80fa8b4)   => $opctl{e} = ARRAY(0x80eace8) [""\,M\,$\,\\,\\,"E"]

There's only one option in this case.

  % cat t2.pl   #!/opt/bleadperl/bin/perl -w   use strict;   use Getopt​::Long qw(​:config debug bundling);   GetOptions e => sub {print "Found lowercase `e'\n"}\,   E => sub {print "Found uppercase `E'\n"};

  % perl -w t2.pl   GetOpt​::Long 2.2603 ($Revision​: 2.47 $) called from package "main".   ARGV​: ()   autoabbrev=1\,bundling=1\,getopt_compat=1\,gnu_compat=0\,order=1\,   ignorecase=1\,passthrough=0\,genprefix="(--|-|\+)".   => link "e" to CODE(0x8172a34)   => link "E" to CODE(0x8172b30)   => $opctl{e} = ARRAY(0x8182df0) [""\,M\,$\,\\,\\,"e"]   $opctl{E} = ARRAY(0x80eace8) [""\,M\,$\,\\,\\,"E"]

Now\, there are two.

Would this be more clear​:

  ignore_case (default​: enabled)   If enabled\, case is ignored when matching long   option names. If\, however\, bundling is enabled as   well\, single character options will be treated   case-sensitive.

-- Johan

p5pRT commented 22 years ago

From @abigail

Yes\, I would think so.

Abigail

p5pRT commented 22 years ago

@abigail - Status changed from 'open' to 'resolved'

p5pRT commented 22 years ago

@sciurius - Status changed from 'open' to 'resolved'