=pod

=head1 NAME

Getopt::Guided - getopts implementation that follows POSIX utility guidelines

=head1 SYNOPSIS

  use Getopt::Guided qw( getopts getopts3 );

  local @ARGV = qw( -d dv1 -c -v -a av1 -d dv2 -a av2 -d -- -vv v1 v2 );

  getopts 'a:bcd,v+', my %opts;

  # or

  getopts3 @ARGV, 'a:bcd,v+', my %opts;

  # result
  # %opts == ( a => 'av2', c => !!1, d => [ 'dv1', 'dv2', '--' ], v => 3 )
  # @ARGV == ( 'v1', 'v2' )


=head1 ABOUT OPTIONS

An option (command-line option) has a name that is a single alphanumeric
(C<[[:alnum:]]>) character. It has a delimiter (prefix delimiter) that is
a hyphen (C<->) character.

Some options require an argument (option-argument). If an option requires an
argument, an indicator (option-argument indicator) character is attached to
its name. A common option has a colon (C<:>) indicator. A list option has
a comma (C<,>) indicator. The POSIX standard knows only common options.

An option that requires no argument is called a flag.  A flag can optionally
have an indicator (flag indicator) character. A negatable flag has an
exclamation mark (C<!>) indicator. An incrementable flag has a plus sign
(C<+>) indicator. The POSIX standard doesn't know flag indicators.

=head1 DESCRIPTION

This module reimplements the C<getopts()> function of the L<Getopts::Std>
core module.  The new implementation supports only the two-parameter form
of C<getopts()> where the second parameter is not a hash reference but a hash.

The first parameter is the "options specification" C<$spec>. It is a
non-empty string that contains a joined list of options (C<E<lt>nameE<gt>
[ E<lt>indicatorE<gt> ]>).

The second parameter is the "name-value map" C<%opts>. It is an empty hash
(passed by reference) that stores the C<getopts()> processing result. Each
hash key refers to an option name and the corresponding hash value refers
to the option-argument value (or C<!!1> if it is a flag).

This module exports the C<getopts()> function on request.

The new implementation follows the L<POSIX utility syntax
guidelines|https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap12.html#tag_12_02>
4 to 10, inclusive. C<getopts()> warns and returns false if a processing error
occurs; otherwise the function returns true. The processing error types are:

=over 3

=item 1.

illegal option

=item 2.

option requires an argument

=item 3.

option with argument isn't last one in group

=back

The second processing error occurs if either no argument or the C<undef>
value is provided for an option that requires an option-argument.

If any of the processing errors occurs, C<getopts()> restores C<@ARGV>
before it warns and returns false.

As of version 1.1.0 this module provides the additional function C<getopts3()>.
This function has a 3rd leading parameter. The parameter is an array (passed
by reference) of command-line argument values. It replaces the implicit use
of C<@ARGV>. This module exports the C<getopts3()> function on request too.

=head1 REPEATING OPTIONS

If a flag with no indicator is repeated, its initial C<%opts> hash value
C<!!1> will not change.

If a negatable flag is repeated, its initial C<%opts> hash value C<!!1>
will be logically negated on each occurrence.

If an incrementable flag is repeated, its initial C<%opts> hash value C<1>
will be incremented by one on each occurrence.  For example, this is useful
for incrementing a verbosity level represented by the C<v+> flag.

If a common option is repeated, the option-arguments overwrite each other
and the last argument wins that means it is the C<%opts> hash value.

If a list option is repeated, the option-arguments are pushed to an array. A
reference to that array is the C<%opts> hash value.

=head1 CAVEAT

Even if you are currently using the two-parameter form of the C<getopts()>
function of C<Getopts::Std>, the new implementation isn't a drop in
replacement. The most crucial change is the type of the second parameter. The
second parameter is not a hash reference anymore but a hash.

=head1 SEE ALSO

=over 2

=item *

L<getopts|https://pubs.opengroup.org/onlinepubs/9799919799/utilities/getopts.html>

=item *

L<Tacit list of POSIX short options|https://stackoverflow.com/questions/56131811/is-there-a-tacit-list-of-reserved-names-for-posix-short-options>

=back

=head1 AUTHOR

Sven Willenbuecher <sven.willenbuecher@gmx.de>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2025 by Sven Willenbuecher.

This is free software; you can redistribute it and/or modify it under the
same terms as the Perl 5 programming language system itself.

=cut
