Add ARM files
[dh-make-perl] / dev / arm / libperl-critic-perl / libperl-critic-perl-1.088 / lib / Perl / Critic / Utils / POD.pm
diff --git a/dev/arm/libperl-critic-perl/libperl-critic-perl-1.088/lib/Perl/Critic/Utils/POD.pm b/dev/arm/libperl-critic-perl/libperl-critic-perl-1.088/lib/Perl/Critic/Utils/POD.pm
new file mode 100644 (file)
index 0000000..aac78ae
--- /dev/null
@@ -0,0 +1,719 @@
+##############################################################################
+#      $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Utils/POD.pm $
+#     $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
+#   $Author: clonezone $
+# $Revision: 2489 $
+##############################################################################
+
+package Perl::Critic::Utils::POD;
+
+use 5.006001;
+use strict;
+use warnings;
+
+use English qw< -no_match_vars >;
+
+use IO::String ();
+use Pod::PlainText ();
+use Pod::Select ();
+
+# TODO: non-fatal generic?
+use Perl::Critic::Exception::Fatal::Generic qw< throw_generic >;
+use Perl::Critic::Exception::IO qw< throw_io >;
+use Perl::Critic::Utils qw< :characters >;
+
+use base 'Exporter';
+
+our $VERSION = '1.088';
+
+#-----------------------------------------------------------------------------
+
+our @EXPORT_OK = qw(
+    get_pod_file_for_module
+    get_raw_pod_section_from_file
+    get_raw_pod_section_from_filehandle
+    get_raw_pod_section_from_string
+    get_raw_pod_section_for_module
+    get_pod_section_from_file
+    get_pod_section_from_filehandle
+    get_pod_section_from_string
+    get_pod_section_for_module
+    trim_raw_pod_section
+    trim_pod_section
+    get_raw_module_abstract_from_file
+    get_raw_module_abstract_from_filehandle
+    get_raw_module_abstract_from_string
+    get_raw_module_abstract_for_module
+    get_module_abstract_from_file
+    get_module_abstract_from_filehandle
+    get_module_abstract_from_string
+    get_module_abstract_for_module
+);
+
+our %EXPORT_TAGS = (
+    all => \@EXPORT_OK,
+);
+
+#-----------------------------------------------------------------------------
+
+sub get_pod_file_for_module {
+    my ($module_name) = @_;
+
+    # No File::Spec: %INC always uses forward slashes.
+    (my $relative_path = $module_name) =~ s< :: ></>xmsg;
+    $relative_path .= '.pm';
+
+    my $absolute_path = $INC{$relative_path} or return;
+
+    (my $pod_path = $absolute_path) =~ s< [.] [^.]+ \z><.pod>xms;
+    return $pod_path if -f $pod_path;
+
+    return $absolute_path;
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_pod_section_from_file {
+    my ($file_name, $section_name) = @_;
+
+    return _get_pod_section_from_file(
+        $file_name,
+        $section_name,
+        Pod::Select->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_pod_section_from_filehandle {
+    my ($file_handle, $section_name) = @_;
+
+    return _get_pod_section_from_filehandle(
+        $file_handle,
+        $section_name,
+        Pod::Select->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_pod_section_from_string {
+    my ($source, $section_name) = @_;
+
+    return _get_pod_section_from_string(
+        $source,
+        $section_name,
+        Pod::Select->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_pod_section_for_module {
+    my ($module_name, $section_name) = @_;
+
+    my $file_name = get_pod_file_for_module($module_name)
+        or throw_generic qq<Could not find POD for "$module_name".>;
+
+    return get_raw_pod_section_from_file($file_name, $section_name);
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_pod_section_from_file {
+    my ($file_name, $section_name) = @_;
+
+    return _get_pod_section_from_file(
+        $file_name,
+        $section_name,
+        Pod::PlainText->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_pod_section_from_filehandle {
+    my ($file_handle, $section_name) = @_;
+
+    return _get_pod_section_from_filehandle(
+        $file_handle,
+        $section_name,
+        Pod::PlainText->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_pod_section_from_string {
+    my ($source, $section_name) = @_;
+
+    return _get_pod_section_from_string(
+        $source,
+        $section_name,
+        Pod::PlainText->new(),
+    );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_pod_section_for_module {
+    my ($module_name, $section_name) = @_;
+
+    my $file_name = get_pod_file_for_module($module_name)
+        or throw_generic qq<Could not find POD for "$module_name".>;
+
+    return get_pod_section_from_file($file_name, $section_name);
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_pod_section_from_file {
+    my ($file_name, $section_name, $parser) = @_;
+
+    # Grr... the handle is open for a whopping 1 statement.  Too painful to
+    # fix the policy right now.
+    ## no critic (RequireBriefOpen)
+    open my $file_handle, '<', $file_name
+        or throw_io
+            message     => qq<Could not open "$file_name": $ERRNO>,
+            file_name   => $file_name,
+            errno       => $ERRNO;
+
+    my $content =
+        _get_pod_section_from_filehandle(
+            $file_handle, $section_name, $parser,
+        );
+
+    close $file_handle
+        or throw_io
+            message     => qq<Could not close "$file_name": $ERRNO>,
+            file_name   => $file_name,
+            errno       => $ERRNO;
+    ## use critic
+
+    return $content;
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_pod_section_from_filehandle {
+    my ($file_handle, $section_name, $parser) = @_;
+
+    $parser->select($section_name);
+
+    my $content = $EMPTY;
+    my $content_handle = IO::String->new( \$content );
+
+    $parser->parse_from_filehandle( $file_handle, $content_handle );
+
+    return if $content eq $EMPTY;
+    return $content;
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_pod_section_from_string {
+    my ($source, $section_name, $parser) = @_;
+
+    my $source_handle = IO::String->new( \$source );
+
+    return
+        _get_pod_section_from_filehandle(
+            $source_handle, $section_name, $parser,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub trim_raw_pod_section {
+    my ($pod) = @_;
+
+    return if not defined $pod;
+
+    $pod =~ s< \A =head1 \b [^\n]* \n $ ><>xms;
+    $pod =~ s< \A \s+ ><>xms;
+    $pod =~ s< \s+ \z ><>xms;
+
+    return $pod;
+}
+
+#-----------------------------------------------------------------------------
+
+sub trim_pod_section {
+    my ($pod) = @_;
+
+    return if not defined $pod;
+
+    $pod =~ s< \A [^\n]* \n ><>xms;
+    $pod =~ s< \A \s* \n ><>xms;
+    $pod =~ s< \s+ \z ><>xms;
+
+    return $pod;
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_module_abstract_from_file {
+    my ($file_name) = @_;
+
+    return
+        _get_module_abstract_from_file(
+            $file_name,
+            Pod::Select->new(),
+            \&trim_raw_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_module_abstract_from_filehandle {
+    my ($file_handle) = @_;
+
+    return
+        _get_module_abstract_from_filehandle(
+            $file_handle,
+            Pod::Select->new(),
+            \&trim_raw_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_module_abstract_from_string {
+    my ($source) = @_;
+
+    return
+        _get_module_abstract_from_string(
+            $source,
+            Pod::Select->new(),
+            \&trim_raw_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_raw_module_abstract_for_module {
+    my ($module_name) = @_;
+
+    my $file_name = get_pod_file_for_module($module_name)
+        or throw_generic qq<Could not find POD for "$module_name".>;
+
+    return get_raw_module_abstract_from_file($file_name);
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_module_abstract_from_file {
+    my ($file_name) = @_;
+
+    return
+        _get_module_abstract_from_file(
+            $file_name,
+            Pod::PlainText->new(),
+            \&trim_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_module_abstract_from_filehandle {
+    my ($file_handle) = @_;
+
+    return
+        _get_module_abstract_from_filehandle(
+            $file_handle,
+            Pod::PlainText->new(),
+            \&trim_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_module_abstract_from_string {
+    my ($source) = @_;
+
+    return
+        _get_module_abstract_from_string(
+            $source,
+            Pod::PlainText->new(),
+            \&trim_pod_section,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_module_abstract_for_module {
+    my ($module_name) = @_;
+
+    my $file_name = get_pod_file_for_module($module_name)
+        or throw_generic qq<Could not find POD for "$module_name".>;
+
+    return get_module_abstract_from_file($file_name);
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_module_abstract_from_file {
+    my ($file_name, $parser, $trimmer) = @_;
+
+    # Grr... the handle is open for a whopping 1 statement.  Too painful to
+    # fix the policy right now.
+    ## no critic (RequireBriefOpen)
+    open my $file_handle, '<', $file_name
+        or throw_io
+            message     => qq<Could not open "$file_name": $ERRNO>,
+            file_name   => $file_name,
+            errno       => $ERRNO;
+
+    my $module_abstract =
+        _get_module_abstract_from_filehandle(
+            $file_handle, $parser, $trimmer,
+        );
+
+    close $file_handle
+        or throw_io
+            message     => qq<Could not close "$file_name": $ERRNO>,
+            file_name   => $file_name,
+            errno       => $ERRNO;
+    ## use critic
+
+    return $module_abstract;
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_module_abstract_from_filehandle { ## no critic (RequireFinalReturn)
+    my ($file_handle, $parser, $trimmer) = @_;
+
+    my $name_section =
+        _get_pod_section_from_filehandle( $file_handle, 'NAME', $parser );
+    return if not $name_section;
+
+    $name_section = $trimmer->($name_section);
+    return if not $name_section;
+
+    # Testing for parser class, blech.  But it's a lot simpler and it's all
+    # hidden in the implementation.
+    if ('Pod::Select' eq ref $parser) {
+        if ( $name_section =~ m< \n >xms ) {
+            throw_generic
+                qq<Malformed NAME section in "$name_section". >
+                . q<It must be on a single line>;
+        }
+    }
+    else {
+        $name_section =~ s< \s+ >< >xmsg;
+
+        # Ugh.  Pod::PlainText splits up module names.
+        if (
+            $name_section =~ m<
+                \A
+                \s*
+                (
+                    \w [ \w:]+ \w
+                )
+                (
+                    \s*
+                    -
+                    .*
+                )?
+                \z
+            >xms
+        ) {
+            my ($module_name, $rest) = ($1, $2);
+
+            $module_name =~ s/ [ ] //xms;
+
+            $name_section = $module_name . ( $rest ? $rest : $EMPTY );
+        }
+    }
+
+    if (
+        $name_section =~ m<
+            \A
+            \s*
+            [\w:]+              # Module name.
+            \s+
+            -                   # The required single hyphen.
+            \s+
+            (
+                \S              # At least one non-whitespace.
+                (?: .* \S)?     # Everything up to the last non-whitespace.
+            )
+            \s*
+            \z
+        >xms
+    ) {
+        my $module_abstract = $1;
+        return $module_abstract;
+    }
+
+    if (
+        $name_section =~ m<
+            \A
+            \s*
+            [\w:]+              # Module name.
+            (?: \s* - )?        # The single hyphen is now optional.
+            \s*
+            \z
+        >xms
+    ) {
+        return;
+    }
+
+    throw_generic qq<Malformed NAME section in "$name_section".>;
+}
+
+#-----------------------------------------------------------------------------
+
+sub _get_module_abstract_from_string {
+    my ($source, $parser, $trimmer) = @_;
+
+    my $source_handle = IO::String->new( \$source );
+
+    return
+        _get_module_abstract_from_filehandle(
+            $source_handle, $parser, $trimmer,
+        );
+}
+
+#-----------------------------------------------------------------------------
+
+1;
+
+__END__
+
+#-----------------------------------------------------------------------------
+
+=pod
+
+=for stopwords
+
+=head1 NAME
+
+Perl::Critic::Utils::POD - Utility functions for dealing with POD.
+
+
+=head1 SYNOPSIS
+
+    use Perl::Critic::Utils::POD qw< get_pod_section_from_file >;
+
+    my $synopsis =
+        get_pod_section_from_file('Perl/Critic/Utils/POD.pm', 'SYNOPSIS');
+
+    my $see_also =
+        get_pod_section_from_filehandle($file_handle, 'SEE ALSO');
+
+
+    my $see_also_content = trim_pod_section($see_also);
+
+
+    # "Utility functions for dealing with POD."
+    my $module_abstract =
+        get_module_abstract_from_file('Perl/Critic/Utils/POD.pm');
+
+    my $module_abstract =
+        get_module_abstract_from_filehandle($file_handle);
+
+
+=head1 DESCRIPTION
+
+Provides means of accessing chunks of POD.
+
+
+=head1 IMPORTABLE SUBROUTINES
+
+=over
+
+=item C<get_pod_file_for_module( $module_name )>
+
+Figure out where to find the POD for the parameter.
+
+This depends upon the module already being loaded; it will not find
+the path for arbitrary modules.
+
+If there is a file with a ".pod" extension next to the real module
+location, it will be returned in preference to the actual module.
+
+
+=item C<get_raw_pod_section_from_file( $file_name, $section_name )>
+
+Retrieves the specified section of POD (i.e. something marked by
+C<=head1>) from the file.  This is uninterpreted; escapes are not
+processed and any sub-sections will be present.  E.g. if the content
+contains "CZ<><$x>", the return value will contain "CZ<><$x>".
+
+Returns nothing if no such section is found.
+
+Throws a L<Perl::Critic::Exception::IO> if there's a problem with the
+file.
+
+
+=item C<get_raw_pod_section_from_filehandle( $file_handle, $section_name )>
+
+Does the same as C<get_raw_pod_section_from_file()>, but with a file
+handle.
+
+
+=item C<get_raw_pod_section_from_string( $source, $section_name )>
+
+Does the same as C<get_raw_pod_section_from_file()>, but with a string
+that contains the raw POD.
+
+
+=item C<get_raw_pod_section_for_module( $module_name, $section_name )>
+
+Does the same as C<get_raw_pod_section_from_file()>, but with a module
+name.
+
+Throws a L<Perl::Critic::Exception::Generic> if a file containing POD
+for the module can't be found.
+
+
+=item C<get_pod_section_from_file( $file_name, $section_name )>
+
+Retrieves the specified section of POD (i.e. something marked by
+C<=head1>) from the file.  This is interpreted into plain text.
+
+Returns nothing if no such section is found.
+
+Throws a L<Perl::Critic::Exception::IO> if there's a problem with the
+file.
+
+
+=item C<get_pod_section_from_filehandle( $file_handle, $section_name )>
+
+Does the same as C<get_pod_section_from_file()>, but with a file
+handle.
+
+
+=item C<get_pod_section_from_string( $source, $section_name )>
+
+Does the same as C<get_pod_section_from_file()>, but with a string
+that contains the raw POD.
+
+
+=item C<get_pod_section_for_module( $module_name, $section_name )>
+
+Does the same as C<get_pod_section_from_file()>, but with a module
+name.
+
+Throws a L<Perl::Critic::Exception::Generic> if a file containing POD
+for the module can't be found.
+
+
+=item C<trim_raw_pod_section( $pod_section )>
+
+Returns a copy of the parameter, with any starting C<=item1 BLAH>
+removed and all leading and trailing whitespace (including newlines)
+removed after that.
+
+For example, using one of the C<get_raw_pod_section_from_*> functions
+to get the "NAME" section of this module and then calling
+C<trim_raw_pod_section()> on the result would give you
+"Perl::Critic::Utils::POD - Utility functions for dealing with POD.".
+
+
+=item C<trim_pod_section( $pod_section )>
+
+Returns a copy of the parameter, with any starting line removed and
+leading blank lines and trailing whitespace (including newlines)
+removed after that.  Note that only leading whitespace on the first
+real line of the section will remain.
+
+Since this cannot count upon a C<=item1> marker, this is much less
+reliable than C<trim_raw_pod_section()>.
+
+
+=item C<get_raw_module_abstract_from_file( $file_name )>
+
+Attempts to parse the "NAME" section of the specified file and get the
+abstract of the module from that.  If it succeeds, it returns the
+abstract.  If it fails, either because there is no "NAME" section or
+there is no abstract after the module name, returns nothing.  If it
+looks like there's a malformed abstract, throws a
+L<Perl::Critic::Exception::Fatal::Generic>.
+
+Example "well formed" "NAME" sections without abstracts:
+
+    Some::Module
+
+    Some::Other::Module -
+
+Example "NAME" sections that will result in an exception:
+
+    Some::Bad::Module This has no hyphen.
+
+    Some::Mean::Module -- This has double hyphens.
+
+    Some::Nasty::Module - This one attempts to
+    span multiple lines.
+
+
+=item C<get_raw_module_abstract_from_filehandle( $file_handle )>
+
+Does the same as C<get_raw_module_abstract_from_file()>, but with a
+file handle.
+
+
+=item C<get_raw_module_abstract_from_string( $source )>
+
+Does the same as C<get_raw_module_abstract_from_file()>, but with a
+string that contains the raw POD.
+
+
+=item C<get_raw_module_abstract_for_module( $module_name )>
+
+Does the same as C<get_raw_module_abstract_from_file()>, but for a
+module name.
+
+
+=item C<get_module_abstract_from_file( $file_name )>
+
+Does the same as C<get_raw_module_abstract_from_file()>, but with
+escapes interpreted.
+
+
+=item C<get_module_abstract_from_filehandle( $file_handle )>
+
+Does the same as C<get_module_abstract_from_file()>, but with a file
+handle.
+
+
+=item C<get_module_abstract_from_string( $source )>
+
+Does the same as C<get_module_abstract_from_file()>, but with a string
+that contains the raw POD.
+
+
+=item C<get_module_abstract_for_module( $module_name )>
+
+Does the same as C<get_module_abstract_from_file()>, but for a module
+name.
+
+
+=back
+
+
+=head1 AUTHOR
+
+Elliot Shank <perl@galumph.com>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2008 Elliot Shank.  All rights reserved.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.  The full text of this license
+can be found in the LICENSE file included with this module.
+
+=cut
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 78
+#   indent-tabs-mode: nil
+#   c-indentation-style: bsd
+# End:
+# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :