Find-Lib-1.04/000755 000765 000024 00000000000 11635220212 013124 5ustar00yannstaff000000 000000 Find-Lib-1.04/Changes000644 000765 000024 00000004051 11635220201 014415 0ustar00yannstaff000000 000000 Revision history for Find-Lib 1.04 Sat Sep 17 15:33:00 PDT 2011 - Fix a minor bug where Cwd module is not required. RT#70768 1.03 Mon Jul 4 00:20:00 PDT 2011 - Making this the final 1.03. All tests pass on cpantesters. 1.03_01 Wed Jun 29 11:05:00 PDT 2011 - Revert 1.02 change, but keep a default to Cwd::cwd() 1.02 Mon Jun 20 22:00:00 PDT 2011 - Fix a portabality issue s/$ENV{PWD}/Cwd::cwd()/ RT#68967 Thanks to Tatsuhiko Miyagawa and Jesse Luehrs. 1.01 Tue Nov 10 12:30:00 PDT 2009 - Fix a problem with File::Spec::Functions use of Exporter making Find::Lib->cat(dir|file) behaving incorrectly. 1.0 Tue Oct 27 13:40:00 PDT 2009 *** Incompatible changes see details in 0.99 releases below. *** - Better diagnostics for some obscur test issues on obscur OSes 0.99_02 Fri Oct 23 18:00:00 PDT 2009 - test change to try to make CPANTESTERS happy 0.99_01 Thu Oct 22 14:00:00 PDT 2009 - Adds the shorter form "Find::Lib 'lib1', 'lib2', 'lib3';" - Add convenience base(), catfile(), catdir() methods *** INCOMPATIBLE CHANGES *** - 'pkg' option is gone - the list arguments won't do any 'use' anymore 0.06 Thu May 8 22:30:00 PDT 2009 - Still working on the test suite (I wish I could use cpantesters without making a release) 0.05 Thu May 7 19:52:00 PDT 2009 - Minor fixes attempt for the test suite (CPANTESTERS) 0.04 Mon May 5 21:05:00 PDT 2009 - Fixed the test suite for a warning that generates tons of FAIL report 0.03 Mon May 5 14:05:00 PDT 2009 - Uses $ENV{PWD} to allow more DWIM, compared to the previous method that used resolved paths all over the place. Teamed up with Jonathan Steinert (hachi) for this idea. 0.02 Sat Dec 8 11:16:09 PDT 2007 - POD fixes - Changed tests suite to make it compatible with perl 5.005 (hopefully) 0.01 Fri Dec 7 19:30:31 PDT 2007 First version, released on an unsuspecting world. Find-Lib-1.04/lib/000755 000765 000024 00000000000 11635220212 013672 5ustar00yannstaff000000 000000 Find-Lib-1.04/Makefile.PL000644 000765 000024 00000001064 11635217741 015114 0ustar00yannstaff000000 000000 use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Find::Lib', AUTHOR => 'Yann Kerherve ', VERSION_FROM => 'lib/Find/Lib.pm', ABSTRACT_FROM => 'lib/Find/Lib.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, 'File::Spec' => 0, }, test => { TESTS => 't/*.t t/moretests/*t' }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Find-Lib-*' }, ); Find-Lib-1.04/MANIFEST000644 000765 000024 00000001127 11602663373 014273 0ustar00yannstaff000000 000000 Changes lib/Find/Lib.pm Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.yml README t/00-compile.t t/01-basic.t t/02-use.t t/03-missinginc.t t/06-empty.t t/07-libs.t t/08-dupe-slashes.t t/libs/Foo.pm t/moretests/01-relative.t t/moretests/02-dollar0-begin.t t/moretests/02-dollar0.t t/moretests/03-chdir-begin.t t/moretests/03-chdir-topbegin.t t/moretests/03-chdir.t t/moretests/03-pwd-begin.t t/moretests/04-symlinks.t t/moretests/05-backcompat.t t/moretests/06-conflict.t t/moretests/mytestlib/MyLib.pm t/moretests/symlink_test.pl t/mylib/MyLib.pm t/mylib/MyLibNoTest.pm t/testutils.pl Find-Lib-1.04/MANIFEST.SKIP000644 000765 000024 00000000515 10726203760 015034 0ustar00yannstaff000000 000000 .shipit # Avoid version control files. \B\.git\b \B\.gitignore\b \bRCS\b \bCVS\b ,v$ \B\.svn\b # Avoid Makemaker generated and utility files. \bMANIFEST\.bak \bMakefile$ \bblib/ \bMakeMaker-\d \bpm_to_blib$ # Avoid Module::Build generated and utility files. \bBuild$ \b_build/ # Avoid temp and backup files. ~$ \.old$ \#$ \b\.# Find-Lib-1.04/META.yml000644 000765 000024 00000001120 11635220212 014367 0ustar00yannstaff000000 000000 --- #YAML:1.0 name: Find-Lib version: 1.04 abstract: Helper to smartly find libs to use in the filesystem tree author: - Yann Kerherve license: unknown distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: File::Spec: 0 Test::More: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.57_05 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 Find-Lib-1.04/README000644 000765 000024 00000002537 11302602154 014013 0ustar00yannstaff000000 000000 Find-Lib The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it to get an idea of the module's uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc Find::Lib You can also look for information at: RT, CPAN's request tracker http://rt.cpan.org/NoAuth/Bugs.html?Dist=Find-Lib AnnoCPAN, Annotated CPAN documentation http://annocpan.org/dist/Find-Lib CPAN Ratings http://cpanratings.perl.org/d/Find-Lib Search CPAN http://search.cpan.org/dist/Find-Lib COPYRIGHT AND LICENCE Copyright (C) 2007 Yann Kerherve This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Find-Lib-1.04/t/000755 000765 000024 00000000000 11635220212 013367 5ustar00yannstaff000000 000000 Find-Lib-1.04/t/00-compile.t000644 000765 000024 00000000074 11602664446 015441 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 1; use_ok 'Find::Lib'; Find-Lib-1.04/t/01-basic.t000644 000765 000024 00000001114 11602664446 015067 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 9; require 't/testutils.pl'; use File::Spec; use Find::Lib 'mylib'; use_ok 'MyLib'; in_inc( 'mylib' ); my $base = Find::Lib->base; ok $base, 'base() returns the directory of your script'; is $base, $Find::Lib::Base, "It's accessible from outside"; is (Find::Lib->catfile('something'), File::Spec->catfile($base, 'something')); is (Find::Lib->catdir('dir'), File::Spec->catdir($base, 'dir')); is (Find::Lib->catdir('..', 'dir'), File::Spec->catdir($base, '..', 'dir')); unlike (Find::Lib->catdir("x"), qr/Find::Lib/, 'Bug with dumb Exporter use'); Find-Lib-1.04/t/02-use.t000644 000765 000024 00000000303 11602664446 014602 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; require 't/testutils.pl'; use Find::Lib 'mylib'; use MyLib; ok my $path = $INC{ 'MyLib.pm' }, "MyLib used"; like $path, qr/mylib/, "just to be sure :)"; Find-Lib-1.04/t/03-missinginc.t000644 000765 000024 00000000173 11602664446 016157 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 1; require 't/testutils.pl'; use Find::Lib 'unexistent'; not_in_inc( 'unexistent' ); Find-Lib-1.04/t/06-empty.t000644 000765 000024 00000000176 11602664446 015160 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 2; require 't/testutils.pl'; use Find::Lib 'libs'; ok "compiled..."; in_inc( 'libs' ); Find-Lib-1.04/t/07-libs.t000644 000765 000024 00000000204 11602664446 014744 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 2; require 't/testutils.pl'; use Find::Lib 'libs'; use Foo a => 1, b => 42; in_inc( 'libs' ); Find-Lib-1.04/t/08-dupe-slashes.t000644 000765 000024 00000000171 11602664446 016414 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 2; require 't/testutils.pl'; use Find::Lib './///libs'; use Foo; in_inc( 'libs' ); Find-Lib-1.04/t/libs/000755 000765 000024 00000000000 11635220212 014320 5ustar00yannstaff000000 000000 Find-Lib-1.04/t/moretests/000755 000765 000024 00000000000 11635220212 015414 5ustar00yannstaff000000 000000 Find-Lib-1.04/t/mylib/000755 000765 000024 00000000000 11635220212 014503 5ustar00yannstaff000000 000000 Find-Lib-1.04/t/testutils.pl000644 000765 000024 00000000362 11602664446 016004 0ustar00yannstaff000000 000000 use strict; sub _in_inc { my $path = shift; my @match = grep { m/$path/ } @INC; return scalar @match; } sub in_inc { ok _in_inc(@_), "$_[0] is in inc"; } sub not_in_inc { ok ! _in_inc(@_), "$_[0] is NOT in inc"; } 1; Find-Lib-1.04/t/mylib/MyLib.pm000644 000765 000024 00000000226 11602664446 016074 0ustar00yannstaff000000 000000 package MyLib; use Test::More; use vars '%imported'; sub import { my $class = shift; %imported = @_; } ok 1, __PACKAGE__ . " loaded"; 1; Find-Lib-1.04/t/mylib/MyLibNoTest.pm000644 000765 000024 00000000153 11602664446 017230 0ustar00yannstaff000000 000000 package MyLibNoTest; use vars '%imported'; sub import { my $class = shift; %imported = @_; } 1; Find-Lib-1.04/t/moretests/01-relative.t000644 000765 000024 00000000246 11602664446 017653 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; use Find::Lib '../mylib', 'mytestlib'; use MyLib a => 1, b => 42+42; ok $MyLib::imported{'a'}; is $MyLib::imported{'b'}, 84; Find-Lib-1.04/t/moretests/02-dollar0-begin.t000644 000765 000024 00000000445 11602664446 020461 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 1; # this screws everything :/ BEGIN { $0 = "[ren/am/med]" }; use Find::Lib; eval { Find::Lib->import('../mylib'); eval "use MyLib a => 1, b => 42;"; die $@ if $@; }; chomp $@; ok $@, "we die if \$0 ($0) doesn't make sense"; diag "ERROR was: $@"; Find-Lib-1.04/t/moretests/02-dollar0.t000644 000765 000024 00000000441 11602664446 017373 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; $0 = "Renammed"; use Find::Lib '../mylib'; use MyLib a => 1, b => 42; ok $MyLib::imported{'a'}; is $MyLib::imported{'b'}, 42; ## would that BEGIN moved up before the 'use' ## it would break Find::Lib, see the other test BEGIN { $0 = "Renammed"; } Find-Lib-1.04/t/moretests/03-chdir-begin.t000644 000765 000024 00000000400 11602664446 020205 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 2; use Find::Lib; BEGIN { chdir '/tmp' }; eval { Find::Lib->import('../mylib'); eval "use MyLib a => 1, b => 42;"; die $@ if $@; }; ok ! $@, "we didn't die, because initial Find::Lib compilation saved cwd"; Find-Lib-1.04/t/moretests/03-chdir-topbegin.t000644 000765 000024 00000000414 11602664446 020735 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 2; BEGIN { chdir '/tmp' }; use Find::Lib; eval { Find::Lib->import('../mylib'); eval "use MyLib a => 1, b => 42;"; die $@ if $@; }; ok !$@, "we didn't die because chdir doesn't change PWD, so we are safe" or diag $@; Find-Lib-1.04/t/moretests/03-chdir.t000644 000765 000024 00000000273 11602664446 017133 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; chdir "/"; use Find::Lib '../mylib'; use MyLib a => 1, b => 42; ok $MyLib::imported{'a'}; is $MyLib::imported{'b'}, 42; BEGIN { chdir '/tmp' }; Find-Lib-1.04/t/moretests/03-pwd-begin.t000644 000765 000024 00000000520 11602664446 017711 0ustar00yannstaff000000 000000 use strict; use Test::More; BEGIN { if ($^O eq 'MSWin32' or $^O eq 'os2') { plan skip_all => "irrelevant on dosish OS"; } $ENV{PWD} = '/tmp'; chdir '/tmp'; }; plan tests => 1; use Find::Lib; eval { Find::Lib->import('../mylib', 'MyLib', a => 1, b => 42); }; ok $@, "we die because chdir and PWD are changed"; Find-Lib-1.04/t/moretests/04-symlinks.t000644 000765 000024 00000003114 11602664446 017711 0ustar00yannstaff000000 000000 use strict; use warnings; use Test::More; use File::Copy; use File::Spec; use Cwd; our $cwd; our $PWD; our @dirs = ("testdir_$$", "testdir"); our $link = "symlink_$$"; my $script = 'symlink_test.pl'; my $nested_dir = File::Spec->catdir(@dirs); my $srcfile = File::Spec->catfile('t', 'moretests', $script); my $dstfile = File::Spec->catfile(@dirs, $script); BEGIN { $cwd = Cwd::cwd(); $PWD = $ENV{PWD}; if ($^O eq 'MSWin32' or $^O eq 'os2') { plan skip_all => "irrelevant on dosish OS"; } unless (eval { symlink(".", "symlinktest$$") } ) { plan 'skip_all' => "symlink support is missing on this FS"; } } plan tests => 2; END { chdir $cwd; ## restore original directory unlink "symlinktest$$"; unlink $link; unlink $dstfile; rmdir $nested_dir; rmdir $dirs[0]; } ## let's create some stuff mkdir $dirs[0]; mkdir $nested_dir; symlink $nested_dir, $link or die "Couldn't symlink the test directory '$nested_dir $link': $!"; copy $srcfile, $dstfile; ## this is where we do the real test; { ## Go into the symlinked directory chdir $link or die "couldn't chdir to $link"; ## damn chdir doesn't update PWD unless coming from Cwd (which might not be installed?) local $ENV{PWD} = File::Spec->catdir( $ENV{PWD}, $link ); ## execute from there, if all is ok, succeeds my $ret = system $^X, $script; ok !$ret, "script succeeded, meaning that compilation with symlink worked" or diag "cwd=$cwd, PWD=$PWD script=$script"; $ret = system $^X, ".///$script"; ok !$ret, "crufty path doesn't make it blow up"; } Find-Lib-1.04/t/moretests/05-backcompat.t000644 000765 000024 00000000262 11602664446 020146 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; use Find::Lib libs => [ '../mylib', 'mytestlib']; use MyLib a => 1, b => 42+42; ok $MyLib::imported{'a'}; is $MyLib::imported{'b'}, 84; Find-Lib-1.04/t/moretests/06-conflict.t000644 000765 000024 00000000417 11602664446 017646 0ustar00yannstaff000000 000000 use strict; use Test::More tests => 3; ## this is potentially conflicting with backward ## except that we're smart enough to detect it use Find::Lib 'libs', '../mylib', 'mytestlib'; use MyLib a => 1, b => 42+42; ok $MyLib::imported{'a'}; is $MyLib::imported{'b'}, 84; Find-Lib-1.04/t/moretests/mytestlib/000755 000765 000024 00000000000 11635220212 017430 5ustar00yannstaff000000 000000 Find-Lib-1.04/t/moretests/symlink_test.pl000644 000765 000024 00000000232 11602664446 020512 0ustar00yannstaff000000 000000 #!perl ## this is not a test in itself, don't execute ## this is a script that is executed by a test use Find::Lib '../t/mylib'; use MyLibNoTest; exit 0; Find-Lib-1.04/t/moretests/mytestlib/MyLib.pm000644 000765 000024 00000000203 11602664446 021014 0ustar00yannstaff000000 000000 package MyLib; use Test::More; sub import { ok 0, "Shouldn't be imported because another path should take precedence"; } 1; Find-Lib-1.04/t/libs/Foo.pm000644 000765 000024 00000000100 11602664446 015407 0ustar00yannstaff000000 000000 package Foo; use Test::More; ok 1, __PACKAGE__ . " loaded"; 1; Find-Lib-1.04/lib/Find/000755 000765 000024 00000000000 11635220212 014552 5ustar00yannstaff000000 000000 Find-Lib-1.04/lib/Find/Lib.pm000644 000765 000024 00000020375 11635220044 015630 0ustar00yannstaff000000 000000 package Find::Lib; use strict; use warnings; use lib; use File::Spec(); use vars qw/$Base $VERSION @base/; use vars qw/$Script/; # compat =head1 NAME Find::Lib - Helper to smartly find libs to use in the filesystem tree =head1 VERSION Version 1.01 =cut $VERSION = '1.04'; =head1 SYNOPSIS #!/usr/bin/perl -w; use strict; ## simple usage use Find::Lib '../mylib'; ## more libraries use Find::Lib '../mylib', 'local-lib'; ## More verbose and backward compatible with Find::Lib < 1.0 use Find::Lib libs => [ 'lib', '../lib', 'devlib' ]; ## resolve some path with minimum typing $dir = Find::Lib->catdir("..", "data"); $path = Find::Lib->catfile("..", "data", "test.yaml"); $base = Find::Lib->base; # or $base = Find::Lib::Base; =head1 DESCRIPTION The purpose of this module is to replace use FindBin; use lib "$FindBin::Bin/../bootstrap/lib"; with something shorter. This is specially useful if your project has a lot of scripts (For instance tests scripts). use Find::Lib '../bootstrap/lib'; The important differences between L and L are: =over 4 =item * symlinks and '..' If you have symlinks in your path it respects them, so basically you can forget you have symlinks, because Find::Lib will do the natural thing (NOT ignore them), and resolve '..' correctly. L breaks if you do: use lib "$Bin/../lib"; and you currently are in a symlinked directory, because $Bin resolved to the filesystem path (without the symlink) and not the shell path. =item * convenience it's faster too type, and more intuitive (Exporting C<$Bin> always felt weird to me). =back =head1 DISCUSSION =head2 Installation and availability of this module The usefulness of this module is seriously reduced if L is not already in your @INC / $ENV{PERL5LIB} -- Chicken and egg problem. This is the big disavantage of L over L: FindBin is distributed with Perl. To mitigate that, you need to be sure of global availability of the module in the system (You could install it via your favorite package managment system for instance). =head2 modification of $0 and chdir (BEGIN blocks, other 'use') As soon as L is compiled it saves the location of the script and the initial cwd (current working directory), which are the two pieces of information the module relies on to interpret the relative path given by the calling program. If one of cwd, $ENV{PWD} or $0 is changed before Find::Lib has a chance to do its job, then Find::Lib will most probably die, saying "The script cannot be found". I don't know a workaround that. So be sure to load Find::Lib as soon as possible in your script to minimize problems (you are in control!). (some programs alter $0 to customize the display line of the process in the system process-list (C on unix). (Note, see L for explanation of $0) =head1 USAGE =head2 import All the work is done in import. So you need to C<'use Find::Lib'> and pass a list of paths to add to @INC. See L section for more retails on this topic. The paths given are (should) be relative to the location of the current script. The paths won't be added unless the path actually exists on disk =cut use Carp(); use Cwd(); $Script = $Base = guess_base(); sub guess_base { my $base; $base = guess_shell_path(); return $base if $base && -e $base; return guess_system_path(); } ## we want to use PWD if it exists (it's not guaranteed on all platforms) ## so that we have a sense of the shell current working dir, with unresolved ## symlinks sub guess_pwd { return $ENV{PWD} || Cwd::cwd(); } sub guess_shell_path { my $pwd = guess_pwd(); my ($volume, $path, $file) = File::Spec->splitpath($pwd); my @path = File::Spec->splitdir($path); pop @path unless $path[-1]; @base = (@path, $file); my @zero = File::Spec->splitdir($0); pop @zero; # get rid of the script ## a clean base is also important for the pop business below #@base = grep { $_ && $_ ne '.' } shell_resolve(\@base, \@zero); @base = shell_resolve(\@base, \@zero); return File::Spec->catpath( $volume, (File::Spec->catdir( @base )), '' ); } ## naive method, but really DWIM from a developer perspective sub shell_resolve { my ($left, $right) = @_; while (@$right && $right->[0] eq '.') { shift @$right } while (@$right && $right->[0] eq '..') { shift @$right; ## chop off @left until we removed a significant path part my $part; while (@$left && !$part) { $part = pop @$left; } } return (@$left, @$right); } sub guess_system_path { my @split = (File::Spec->splitpath( File::Spec->rel2abs($0) ))[ 0, 1 ]; return File::Spec->catpath( @split, '' ); } sub import { my $class = shift; return unless @_; Carp::croak("The script/base dir cannot be found") unless -e $Base; my @libs; if ($_[0] eq 'libs') { if ($_[1] && ref $_[1] && ref $_[1] eq 'ARRAY') { ## backward compat mode; @libs = @{ $_[1] }; } } @libs = @_ unless @libs; for ( reverse @libs ) { my @lib = File::Spec->splitdir($_); if (@lib && ! $lib[0]) { # '/abs/olute/' path lib->import($_); next; } my $dir = File::Spec->catdir( shell_resolve( [ @base ], \@lib ) ); unless (-d $dir) { ## Try the old way (<0.03) $dir = File::Spec->catdir($Base, $_); } next unless -d $dir; lib->import( $dir ); } } =head2 base Returns the detected base (the directory where the script lives in). It's a string, and is the same as C<$Find::Lib::Base>. =cut sub base { return $Base } =head2 catfile A shorcut to L using B's base. =cut sub catfile { my $class = shift; return File::Spec->catfile($Base, @_); } =head2 catdir A shorcut to L using B's base. =cut sub catdir { my $class = shift; return File::Spec->catdir($Base, @_); } =head1 BACKWARD COMPATIBILITY in versions <1.0 of Find::Lib, the import arguments allowed you to specify a Bootstrap package. This option is now B breaking backward compatibility. I'm sorry about that, but that was a dumb idea of mine to save more typing. But it saves, like, 3 characters at the expense of readability. So, I'm sure I didn't break anybody, because probabaly no one was relying on a stupid behaviour. However, the multiple libs argument passing is kept intact: you can still use: use Find::Lib libs => [ 'a', 'b', 'c' ]; where C is a reference to a list of path to add to C<@INC>. The short forms implies that the first argument passed to import is not C or C. An example of usage is given in the SYNOPSIS section. =head1 SEE ALSO L, L, L, L, L L =head1 AUTHOR Yann Kerherve, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 ACKNOWLEDGEMENT Six Apart hackers nourrished the discussion that led to this module creation. Jonathan Steinert (hachi) for doing all the conception of 0.03 shell expansion mode with me. =head1 SUPPORT & CRITICS I welcome feedback about this module, don't hesitate to contact me regarding this module, usage or code. You can find documentation for this module with the perldoc command. perldoc Find::Lib You can also look for information at: =over 4 =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * RT: CPAN's request tracker L =item * Search CPAN L =back =head1 COPYRIGHT & LICENSE Copyright 2007, 2009 Yann Kerherve, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;