* lib/Autom4te/General.pm (getopt): Move the guts of its implementation ... * lib/Autom4te/Getopt.pm (parse_options): .. into this function in the new Autom4te::Getopt module. This will make it simpler for the implementation to be shared with other projects (right now, Automake). * lib/Automake/Makefile.am (dist_perllib_DATA): Add the new module. --- lib/Autom4te/General.pm | 49 +++---------------- lib/Autom4te/Getopt.pm | 118 ++++++++++++++++++++++++++++++++++++++++++++++ lib/Autom4te/Makefile.am | 1 + 3 files changed, 126 insertions(+), 42 deletions(-) create mode 100644 lib/Autom4te/Getopt.pm
diff --git a/lib/Autom4te/General.pm b/lib/Autom4te/General.pm index f05042f..a7a1223 100644 --- a/lib/Autom4te/General.pm +++ b/lib/Autom4te/General.pm @@ -36,6 +36,7 @@ use 5.006_002; use Exporter; use Autom4te::ChannelDefs; use Autom4te::Channels; +use Autom4te::Getopt (); use File::Basename; use File::Path (); use File::stat; @@ -232,12 +233,10 @@ sub debug (@) =item C<getopt (%option)> -Wrapper around C<Getopt::Long>. In addition to the user C<option>s, -support C<-h>/C<--help>, C<-V>/C<--version>, C<-v>/C<--verbose>, -C<-d>/C<--debug>, C<-f>/C<--force>. Conform to the GNU Coding -Standards for error messages. Try to work around a weird behavior -from C<Getopt::Long> to preserve C<-> as an C<@ARGV> instead of -rejecting it as a broken option. +Wrapper around C<Autom4te::Getopt::parse_options>. In addition to +the user C<option>s, support C<-h>/C<--help>, C<-V>/C<--version>, +C<-v>/C<--verbose>, C<-d>/C<--debug>, C<-f>/C<--force>. Conform to +the GNU Coding Standards for error messages. =cut @@ -247,8 +246,6 @@ rejecting it as a broken option. sub getopt (%) { my (%option) = @_; - use Getopt::Long; - %option = ("h|help" => sub { print $help; exit 0 }, "V|version" => sub { print $version; exit 0 }, @@ -258,40 +255,8 @@ sub getopt (%) # User options last, so that they have precedence. %option); - Getopt::Long::Configure ("bundling", "pass_through"); - GetOptions (%option) - or exit 1; - - # FIXME: Lot of code duplication with automake here. It would probably - # be best to generalize our getopt() func and rip it out in a new module - # from which automake can sync. - if (@ARGV && $ARGV[0] =~ /^-./) - { - my %argopts; - for my $k (keys %option) - { - if ($k =~ /(.*)=s$/) - { - map { $argopts{(length ($_) == 1) - ? "-$_" : "--$_" } = 1; } (split (/\|/, $1)); - } - } - if ($ARGV[0] eq '--') - { - shift @ARGV; - } - elsif (exists $argopts{$ARGV[0]}) - { - fatal ("option `$ARGV[0]' requires an argument\n" - . "Try `$0 --help' for more information."); - } - else - { - fatal ("unrecognized option `$ARGV[0]'.\n" - . "Try `$0 --help' for more information."); - } - } - + Autom4te::Getopt::parse_options (%option); + setup_channel 'note', silent => !$verbose; setup_channel 'verb', silent => !$verbose; } diff --git a/lib/Autom4te/Getopt.pm b/lib/Autom4te/Getopt.pm new file mode 100644 index 0000000..3ff4ce6 --- /dev/null +++ b/lib/Autom4te/Getopt.pm @@ -0,0 +1,118 @@ +# Copyright (C) 2012 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +package Autom4te::Getopt; + +=head1 NAME + +Autom4te::Getopt - GCS conforming parser for command line options + +=head1 SYNOPSIS + + use Autom4te::Getopt; + +=head1 DESCRIPTION + +Export a function C<parse_options>, performing parsing of command +line options in conformance to the GNU Conding standards. + +=cut + +use 5.006_002; +use strict; +use warnings FATAL => 'all'; +use Exporter (); +use Getopt::Long (); +use Autom4te::ChannelDefs qw/fatal/; +use Carp qw/croak confess/; + +use vars qw (@ISA @EXPORT); +@ISA = qw (Exporter); +@EXPORT= qw/getopt/; + +=item C<parse_options (%option_action_hash)> + +Wrapper around C<Getopt::Long>, trying to conform to the GNU +Coding Standards for error messages. + +=cut + +sub parse_options (%) +{ + my %option = @_; + + Getopt::Long::Configure ("bundling", "pass_through"); + # Unrecognized options are passed through, so GetOption can only fail + # due to internal errors or misuse of options specification. + Getopt::Long::GetOptions (%option) + or confess "error in options specification (likely)"; + + if (@ARGV && $ARGV[0] =~ /^-./) + { + my %argopts; + for my $k (keys %option) + { + if ($k =~ /(.*)=s$/) + { + map { $argopts{(length ($_) == 1) + ? "-$_" : "--$_" } = 1; } (split (/\|/, $1)); + } + } + if ($ARGV[0] eq '--') + { + shift @ARGV; + } + elsif (exists $argopts{$ARGV[0]}) + { + fatal ("option `$ARGV[0]' requires an argument\n" + . "Try `$0 --help' for more information."); + } + else + { + fatal ("unrecognized option `$ARGV[0]'.\n" + . "Try `$0 --help' for more information."); + } + } + +} + +=back + +=head1 SEE ALSO + +L<Getopt::Long> + +=cut + +1; # for require + +### Setup "GNU" style for perl-mode and cperl-mode. +## Local Variables: +## perl-indent-level: 2 +## perl-continued-statement-offset: 2 +## perl-continued-brace-offset: 0 +## perl-brace-offset: 0 +## perl-brace-imaginary-offset: 0 +## perl-label-offset: -2 +## cperl-indent-level: 2 +## cperl-brace-offset: 0 +## cperl-continued-brace-offset: 0 +## cperl-label-offset: -2 +## cperl-extra-newline-before-brace: t +## cperl-merge-trailing-else: nil +## cperl-continued-statement-offset: 2 +## End: diff --git a/lib/Autom4te/Makefile.am b/lib/Autom4te/Makefile.am index ff15fb8..ffc6f6e 100644 --- a/lib/Autom4te/Makefile.am +++ b/lib/Autom4te/Makefile.am @@ -17,6 +17,7 @@ perllibdir = $(pkgdatadir)/Autom4te dist_perllib_DATA = \ + Getopt.pm \ C4che.pm \ ChannelDefs.pm \ Channels.pm \ -- 1.7.7.3