File Coverage

blib/lib/Module/Metadata/CoreList.pm
Criterion Covered Total %
statement 99 158 62.6
branch 19 52 36.5
condition 14 32 43.7
subroutine 15 19 78.9
pod 7 8 87.5
total 154 269 57.2


line stmt bran cond sub pod time code
1             package Module::Metadata::CoreList;
2              
3 3     3   209242 use strict;
  3         7  
  3         120  
4 3     3   19 use warnings;
  3         6  
  3         94  
5              
6 3     3   16 use Config;
  3         6  
  3         175  
7              
8 3     3   2926 use Date::Simple;
  3         29119  
  3         131  
9              
10 3     3   26 use File::Spec;
  3         6  
  3         85  
11              
12 3     3   2967 use Hash::FieldHash ':all';
  3         4379  
  3         609  
13              
14 3     3   7850 use Module::CoreList;
  3         122743  
  3         43  
15              
16 3     3   3901 use Module::Metadata::CoreList::Config;
  3         14  
  3         110  
17              
18 3     3   3581 use Text::Xslate 'mark_raw';
  3         37519  
  3         14938  
19              
20             fieldhash my %config => 'config';
21             fieldhash my %dir_name => 'dir_name';
22             fieldhash my %file_name => 'file_name';
23             fieldhash my %module_name => 'module_name';
24             fieldhash my %perl_version => 'perl_version';
25             fieldhash my %report_type => 'report_type';
26              
27             our $VERSION = '1.07';
28              
29             # ------------------------------------------------
30              
31             sub _build_environment
32             {
33 0     0   0 my($self) = @_;
34              
35 0         0 my(@environment);
36              
37             # mark_raw() is needed because of the HTML tag .
38              
39 0         0 push @environment,
40             {left => 'Author', right => mark_raw(qq|Ron Savage|)},
41             {left => 'Date', right => Date::Simple -> today},
42             {left => 'OS', right => 'Debian V 6.0.4'},
43             {left => 'Perl', right => $Config{version} };
44              
45 0         0 return \@environment;
46             }
47             # End of _build_environment.
48              
49             # -----------------------------------------------
50              
51             sub check_perl_for_module
52             {
53 0     0 1 0 my($self) = @_;
54 0         0 my($module_name) = $self -> module_name;
55 0         0 my($perl_version) = $self -> perl_version;
56              
57 0 0 0     0 if ($module_name && $perl_version)
58             {
59 0 0 0     0 if ($Module::CoreList::version{$perl_version} && exists $Module::CoreList::version{$perl_version}{$module_name})
60             {
61 0 0       0 print exists $Module::CoreList::version{$perl_version}{$module_name} ? $Module::CoreList::version{$perl_version}{$module_name} : 'undef', "\n";
62             }
63             else
64             {
65 0         0 die "Unknown version of Perl ($perl_version), or unknown module ($module_name)\n";
66             }
67             }
68             else
69             {
70 0         0 die "Either module_name or perl_version not specified\n";
71             }
72              
73             # Return 0 for success and 1 for failure.
74              
75 0         0 return 0;
76              
77             } # End of check_perl_for_module.
78              
79             # -----------------------------------------------
80              
81             sub check_perl_module
82             {
83 1     1 1 1446 my($self) = @_;
84 1         7 my($module_name) = $self -> module_name;
85 1         5 my($perl_version) = $self -> perl_version;
86              
87 1 50       5 if ($module_name)
    0          
88             {
89 1 50       21 my($prefix) = "Module names which match the regexp qr/$module_name/" . ($perl_version ? " in Perl V $perl_version: " : ': ');
90              
91 1 50       23 print $prefix, join(', ', Module::CoreList::find_modules(qr/$module_name/, $perl_version ? $perl_version : () ) ), ". \n";
92             }
93             elsif ($perl_version)
94             {
95 0 0       0 print 'Module::CoreList ', (Module::CoreList::find_version($perl_version) ? 'recognizes' : 'does not recognize'), " V $perl_version of Perl. \n";
96             }
97             else
98             {
99 0         0 die "Neither module_name nor perl_version specified\n";
100             }
101              
102             # Return 0 for success and 1 for failure.
103              
104 1         27035 return 0;
105              
106             } # End of check_perl_module.
107              
108             # -----------------------------------------------
109              
110             sub _init
111             {
112 2     2   5 my($self, $arg) = @_;
113 2         75 $$arg{config} = Module::Metadata::CoreList::Config -> new -> config;
114 2   50     65 $$arg{dir_name} ||= '.'; # Caller can set.
115 2   50     15 $$arg{file_name} ||= ''; # Caller can set.
116 2   100     13 $$arg{module_name} ||= ''; # Caller can set.
117 2   50     8 $$arg{perl_version} ||= ''; # Caller can set.
118 2   50     13 $$arg{report_type} ||= 'text'; # Caller can set.
119              
120 2         39 return from_hash($self, $arg);
121              
122             } # End of _init.
123              
124             # -----------------------------------------------
125              
126             sub new
127             {
128 2     2 0 42 my($class, %arg) = @_;
129 2         10 my($self) = bless {}, $class;
130 2         16 $self = $self -> _init(\%arg);
131              
132 2         13 return $self;
133              
134             } # End of new.
135              
136             # -----------------------------------------------
137              
138             sub process_build_pl
139             {
140 1     1 1 2 my($self, $line_ara) = @_;
141              
142             # Assumed input format:
143             # build_requires =>
144             # {
145             # "Test::More" => 0,
146             # 'Test::Pod' => 0,
147             # },
148             # configure_requires =>
149             # {
150             # Module::Build => 0,
151             # },
152             # requires =>
153             # {
154             # Module::CoreList => 0,
155             # },
156              
157 1         3 my(@name);
158              
159 1         2 my($candidate) = 0;
160              
161 1         4 for my $line (@$line_ara)
162             {
163 48 100 100     379 if ($line =~ /^\s*(?:build_|configure_|)requires/i)
    100 100        
    100          
164             {
165 3         6 $candidate = 1;
166             }
167             elsif ($candidate && $line =~ /^\s*}/)
168             {
169 3         6 $candidate = 0;
170             }
171             elsif ($candidate && ($line =~ /^\s*(['"])?([\w:]+)\1?\s*=>\s*(.+),/) )
172             {
173 18         68 push @name, [$2, $3];
174             }
175             }
176              
177 1         6 return [sort{$$a[0] cmp $$b[0]} @name];
  48         63  
178              
179             } # End of process_build_pl.
180              
181             # -----------------------------------------------
182              
183             sub process_makefile_pl
184             {
185 0     0 1 0 my($self, $line_ara) = @_;
186              
187             # Assumed input format:
188             # PREREQ_PM =>
189             # {
190             # Module::CoreList => 0,
191             # 'Test::More' => 0,
192             # "Test::Pod" => 0,
193             # },
194              
195 0         0 my(@name);
196              
197 0         0 my($candidate) = 0;
198              
199 0         0 for my $line (@$line_ara)
200             {
201 0 0 0     0 if ($line =~ /^\s*PREREQ_PM/i)
    0 0        
    0          
202             {
203 0         0 $candidate = 1;
204             }
205             elsif ($candidate && $line =~ /^\s*}/)
206             {
207 0         0 $candidate = 0;
208             }
209             elsif ($candidate && ($line =~ /^\s*(['"])?([\w:]+)\1?\s*=>\s*(.+),/) )
210             {
211 0         0 push @name, [$2, $3];
212             }
213             }
214              
215 0         0 return [sort{$$a[0] cmp $$b[0]} @name];
  0         0  
216              
217             } # End of process_makefile_pl.
218              
219             # -----------------------------------------------
220              
221             sub report_as_html
222             {
223 0     0 1 0 my($self, $module_list) = @_;
224 0         0 my($templater) = Text::Xslate -> new
225             (
226             input_layer => '',
227 0         0 path => ${$self -> config}{template_path},
228             );
229              
230 0         0 my(%module_list) = map{($$_[0] => undef)} @$module_list;
  0         0  
231 0         0 my(%module_version) = map{($$_[0] => $$_[1])} @$module_list;
  0         0  
232 0         0 my($perl_version) = $self -> perl_version;
233 0         0 my(@present) = [{td => 'Module'}, {td => $self -> file_name}, {td => 'CoreList'}];
234              
235 0         0 for my $name (@$module_list)
236             {
237 0         0 for my $module (sort keys %{$Module::CoreList::version{$perl_version} })
  0         0  
238             {
239 0 0       0 if ($module eq $$name[0])
240             {
241 0   0     0 $module_list{$module} = $Module::CoreList::version{$perl_version}{$module} || 0;
242              
243 0         0 push @present, [{td => $$name[0]}, {td => $$name[1]} , {td => $module_list{$module} }];
244             }
245             }
246             }
247              
248 0         0 my(@absent) = [{td => 'Module'}, {td => $self -> file_name}];
249              
250 0         0 for my $name (sort keys %module_list)
251             {
252 0 0       0 if (! defined $module_list{$name})
253             {
254 0         0 push @absent, [{td => $name} ,{td => $module_version{$name} }];
255             }
256             }
257              
258 0         0 my($config) = $self -> config;
259 0         0 my(@module_list) =
260             (
261             'Module::CoreList',
262             'Module::Metadata::CoreList',
263             );
264              
265 0 0       0 push @module_list, 'Data::Session' if ($ENV{AUTHOR_TESTING});
266              
267 0         0 print $templater -> render
268             (
269             'web.page.tx',
270             {
271 0         0 absent_heading => "Modules found in @{[$self -> file_name]} but not in Module::CoreList V $Module::CoreList::VERSION",
272             absent_modules => [@absent],
273             default_css => "$$config{css_url}/default.css",
274             environment => $self -> _build_environment,
275             fancy_table_css => "$$config{css_url}/fancy.table.css",
276             module_list => mark_raw(join(', ', @module_list) ),
277 0         0 options => "-d @{[$self -> dir_name]} -f @{[$self -> file_name]} -p @{[$self -> perl_version]}",
  0         0  
  0         0  
278 0         0 present_heading => "Modules found in @{[$self -> file_name]} and in Module::CoreList V $Module::CoreList::VERSION",
279             present_modules => [@present],
280             version => $VERSION,
281             }
282             );
283              
284             } # End of report_as_html.
285              
286             # -----------------------------------------------
287              
288             sub report_as_text
289             {
290 1     1 1 3 my($self, $module_list) = @_;
291              
292 1         2 print "Options: -d @{[$self -> dir_name]} -f @{[$self -> file_name]} -p @{[$self -> perl_version]}. \n";
  1         8  
  1         5  
  1         88  
293              
294 1         5 my(%module_list) = map{($$_[0] => undef)} @$module_list;
  18         49  
295 1         4 my(%module_version) = map{($$_[0] => $$_[1])} @$module_list;
  18         41  
296              
297 1         5 print "Modules found in @{[$self -> file_name]} and in Module::CoreList V $Module::CoreList::VERSION:\n";
  1         19  
298              
299 1         5 my($perl_version) = $self -> perl_version;
300              
301 1         4 for my $name (@$module_list)
302             {
303 18         33 for my $module (sort keys %{$Module::CoreList::version{$perl_version} })
  18         198  
304             {
305 6372 100       55657 if ($module eq $$name[0])
306             {
307 8   100     112 $module_list{$module} = $Module::CoreList::version{$perl_version}{$module} || 0;
308              
309 8         457 print "$module => $$name[1] and $module_list{$module}. \n";
310             }
311             }
312             }
313              
314 1         5 print "Modules found in @{[$self -> file_name]} but not in Module::CoreList V $Module::CoreList::VERSION: \n";
  1         32  
315              
316 1         17 for my $name (sort keys %module_list)
317             {
318 18 100       53 if (! defined $module_list{$name})
319             {
320 10         114 print "$name => $module_version{$name}. \n";
321             }
322             }
323              
324             } # End of report_as_text.
325              
326             # -----------------------------------------------
327              
328             sub run
329             {
330 1     1 1 1764 my($self) = @_;
331 1         8 my($file_name) = $self -> file_name;
332              
333 1 50       5 if (! $file_name)
    0          
334             {
335 1         3 $file_name = 'Build.PL|Makefile.PL';
336             }
337             elsif ($file_name !~ /^(?:Build.PL|Makefile.PL)$/i)
338             {
339 0         0 die "The file_name option's value must be either Build.PL or Makefile.PL\n";
340             }
341              
342 1 50       48 opendir(INX, $self -> dir_name) || die "Can't opendir(@{[$self -> dir_name]}): $!\n";
  0         0  
343 1         82 my(@file) = sort grep{/^(?:$file_name)$/} readdir INX;
  23         118  
344 1         23 closedir INX;
345              
346 1 50       6 if ($#file < 0)
347             {
348 0         0 die "Can't find either Build.PL or Makefile.PL in directory '@{[$self -> dir_name]}'\n";
  0         0  
349             }
350              
351             # Read whatever name ends up in $file[0].
352              
353 1         7 $self -> file_name($file[0]);
354              
355 1 50       49 open(INX, File::Spec -> catfile($self -> dir_name, $file[0]) ) || die "Can't open($file[0]): $!\n";
356 1         55 my(@line) = ;
357 1         14 close INX;
358              
359 1         5 chomp @line;
360              
361 1         2 my($module_list);
362              
363 1 50       5 if ($file[0] eq 'Build.PL')
364             {
365 1         7 $module_list = $self -> process_build_pl(\@line);
366             }
367             else
368             {
369 0         0 $module_list = $self -> process_makefile_pl(\@line);
370             }
371              
372 1 50       14 if ($self -> report_type =~ /^h/i)
373             {
374 0         0 $self -> report_as_html($module_list);
375             }
376             else
377             {
378 1         4 $self -> report_as_text($module_list);
379             }
380              
381             # Return 0 for success and 1 for failure.
382              
383 1         33 return 0;
384              
385             } # End of run.
386              
387             # -----------------------------------------------
388              
389             1;
390              
391             =head1 NAME
392              
393             Module::Metadata::CoreList - Scripts to cross-check Build.PL/Makefile.PL with Module::CoreList, etc
394              
395             =head1 Synopsis
396              
397             These scripts are shipped in the bin/ directory of the distro, and hence are installed along with the modules,
398             and will then be on your $PATH.
399              
400             =head2 bin/cc.corelist.pl
401              
402             bin/cc.corelist.pl is a parameterized version of the following code.
403              
404             Try running cc.corelist.pl -h.
405              
406             #!/usr/bin/env perl
407              
408             use strict;
409             use warnings;
410              
411             use Module::Metadata::CoreList;
412              
413             # -----------------------------------------------
414              
415             Module::Metadata::CoreList -> new
416             (
417             dir_name => '/home/ron/perl.modules/Data-Session',
418             perl_version => '5.012001',
419             report_type => 'html',
420             ) -> run;
421              
422             =head2 bin/cc.perlmodule.pl
423              
424             bin/cc.perlmodule.pl is a parameterized version of the following code.
425              
426             Try running cc.perlmodule.pl -h.
427              
428             =head3 Usage with just a Perl version specified:
429              
430             #!/usr/bin/env perl
431              
432             use strict;
433             use warnings;
434              
435             use Module::Metadata::CoreList;
436              
437             # -----------------------------------------------
438              
439             Module::Metadata::CoreList -> new
440             (
441             perl_version => '5.012001',
442             ) -> check_perl_module;
443              
444             Output:
445              
446             Module::CoreList recognizes V 5.012001 of Perl.
447              
448             But try running it with perl_version => '5.012005' and the output is:
449              
450             Module::CoreList does not recognize V 5.012005 of Perl.
451              
452             =head3 Usage with module_name specified, with or without perl_version specified:
453              
454             #!/usr/bin/env perl
455              
456             use strict;
457             use warnings;
458              
459             use Module::Metadata::CoreList;
460              
461             # -----------------------------------------------
462              
463             Module::Metadata::CoreList -> new
464             (
465             module_name => 'warnings',
466             ) -> check_perl_module;
467              
468             Output:
469              
470             Module names which match the regexp qr/warnings/: encoding::warnings, warnings, warnings::register.
471              
472             Now add perl_version => '5.008001', and the output is:
473              
474             Module names which match the regexp qr/warnings/ in Perl V 5.008001: warnings, warnings::register.
475              
476             This means encoding::warnings was not shipped in V 5.8.1 of Perl.
477              
478             =head2 cc.whichperlmodule.pl
479              
480             Run this module as:
481              
482             cc.whichperlmodule.pl -p 5.008001 -m Module::CoreList
483             cc.whichperlmodule.pl -p 5.014001 -m Module::CoreList
484             cc.whichperlmodule.pl -p 5.014002 -m strict
485              
486             and the outputs will be:
487              
488             Unknown version of Perl (5.008001), or unknown module (Module::CoreList)
489             2.49_01
490             1.04
491              
492             meaning that if the module was shipped with that version of Perl, the version # of the module is reported.
493              
494             There is no -report_type option for this program. Output is just 1 line of text.
495             This means there is no need to edit the config file to run cc.whichperlmodule.pl.
496              
497             =head1 Description
498              
499             L is a pure Perl module.
500              
501             =head2 Usage via method check_perl_for_module()
502              
503             This usage cross-checks a module's existence within the modules shipped with a specific version of Perl.
504              
505             It's aim is to aid module authors in fine-tuning the versions of modules listed in Build.PL and Makefile.PL.
506              
507             See L as discussed in the synopsis.
508              
509             =head2 Usage via method check_perl_module()
510              
511             This usage tells you whether or not you've correctly specified a Perl version number, as recognized by L,
512             by calling the latter module's find_version() function.
513              
514             Further, you can detrmine whether or not a specific module is shipped with a specific version of Perl, by calling
515             L's function find_modules().
516              
517             See L as discussed in the synopsis.
518              
519             =head2 Usage via method run()
520              
521             This usage cross-checks a module's pre-requisites with the versions shipped with a specific version of Perl.
522              
523             It's aim is to aid module authors in fine-tuning the versions of modules listed in Build.PL and Makefile.PL.
524              
525             It does this by reading Build.PL or Makefile.PL to get a list of pre-requisites, and looks
526             up those module names in L.
527              
528             The output report can be in either text or HTML.
529              
530             Here is a sample HTML report: L.
531              
532             This report is shipped in htdocs/.
533              
534             See L as discussed in the synopsis.
535              
536             =head2 Inheritance model
537              
538             To keep this module light-weight, it uses L mutators for managing object attributes.
539              
540             =head1 Distributions
541              
542             This module is available as a Unix-style distro (*.tgz).
543              
544             See http://savage.net.au/Perl-modules.html for details.
545              
546             See http://savage.net.au/Perl-modules/html/installing-a-module.html for
547             help on unpacking and installing.
548              
549             =head1 Installation
550              
551             =head2 The Module Itself
552              
553             Install L as you would for any C module:
554              
555             Run:
556              
557             cpanm Module::Metadata::CoreList
558              
559             or run:
560              
561             sudo cpan Module::Metadata::CoreList
562              
563             or unpack the distro, and then either:
564              
565             perl Build.PL
566             ./Build
567             ./Build test
568             sudo ./Build install
569              
570             or:
571              
572             perl Makefile.PL
573             make (or dmake or nmake)
574             make test
575             make install
576              
577             =head2 The Configuration File
578              
579             All that remains is to tell L your values for some options.
580              
581             For that, see config/.htmodule.metadata.corelist.conf.
582              
583             The default value for template_path is /dev/shm/html/assets/templates/module/metadata/corelist,
584             where /dev/shm/ is Debian's RAM disk, since on my dev box I have the web server's doc root dir
585             set to /dev/shm/html/.
586              
587             The template files are shipped in htdocs/assets/templates/module/metadata/corelist.
588              
589             If you are using Build.PL, running Build (without parameters) will run scripts/copy.config.pl,
590             as explained next.
591              
592             If you are using Makefile.PL, running make (without parameters) will also run scripts/copy.config.pl.
593              
594             Either way, before editing the config file, ensure you run scripts/copy.config.pl. It will copy
595             the config file using L, to a directory where the run-time code in
596             L will look for it. Run it manually like this:
597              
598             shell>cd Module-Metadata-CoreList-1.00
599             shell>perl scripts/copy.config.pl
600              
601             Under Debian, this directory will be $HOME/.perl/Module-Metadata-CoreList/. When you
602             run copy.config.pl, it will report where it has copied the config file to.
603              
604             Check the docs for L to see what your operating system returns for a
605             call to my_dist_config().
606              
607             The point of this is that after the module is installed, the config file will be
608             easily accessible and editable without needing permission to write to the directory
609             structure in which modules are stored.
610              
611             That's why L and L are pre-requisites for this module.
612              
613             All modules which ship with their own config file are advised to use the same mechanism
614             for storing such files.
615              
616             =head1 Constructor and initialization
617              
618             new(...) returns an object of type L.
619              
620             This is the class's contructor.
621              
622             Usage: C<< Module::Metadata::CoreList -> new() >>.
623              
624             This method takes a hash of options.
625              
626             Call C as C<< new(option_1 => value_1, option_2 => value_2, ...) >>.
627              
628             Available options:
629              
630             =over 4
631              
632             =item o dir_name => $dir_name
633              
634             Specify the directory to search in for Build.PL and/or Makefile.PL.
635              
636             Default: '.'.
637              
638             This key is optional.
639              
640             =item o file_name => Build.PL or Makefile.PL
641              
642             Specify that you only want to process the given file.
643              
644             This means the code searches for both Build.PL and Makefile.PL,
645             and processes the first one after sorting the names alphabetically.
646              
647             Default: ''.
648              
649             This key is optional.
650              
651             =item o module_name => $module_name
652              
653             Specify the name of the module to use, in the call to check_perl_module().
654              
655             When method run() is called, this value is ignored.
656              
657             Default: ''.
658              
659             This key is optional, but if omitted then perl_version must be specified.
660              
661             =item o perl_version => $version
662              
663             Specify the specific version of Perl to consider, when accessing L.
664              
665             Perl V 5.10.1 must be written as 5.010001, and V 5.12.1 as 5.012001.
666              
667             Default: ''.
668              
669             This key is mandatory when calling run(), but when calling check_perl_module() it need only
670             be specified if module_name is not specified.
671              
672             =item o report_type => 'html' or 'text'
673              
674             Specify what type of report to produce. This report is written to STDOUT.
675              
676             Default: 'text'.
677              
678             This key is optional.
679              
680             Here is a sample HTML report: L.
681              
682             This report is shipped in htdocs/.
683              
684             =back
685              
686             =head1 Methods
687              
688             =head2 check_perl_for_module()
689              
690             As the name says, Perl itself is checked to see if a module ships with a given version of perl.
691              
692             See L as discussed in the synopsis.
693              
694             Method check_perl_for_module() always returns 0 (for success).
695              
696             =head2 check_perl_module()
697              
698             This module first checks the value of the module_name option.
699              
700             =over 4
701              
702             =item o If the user has specified a module name...
703              
704             Use both the specified module name, and the perl version (if any), to call L's
705             find_modules() function.
706              
707             The output is a single line of text. The value of report_type is ignored.
708              
709             =item o If the user has not specified a module name...
710              
711             Use just the perl version to call L's find_version() function.
712              
713             The output is a single line of text. The values of module_name and report_type are ignored.
714              
715             =back
716              
717             See L as discussed in the synopsis.
718              
719             Method check_perl_module() always returns 0 (for success).
720              
721             =head2 process_build_pl($line_ara)
722              
723             Process Build.PL.
724              
725             $line_ara is an arrayref of lines, chomped, read from Build.PL.
726              
727             Returns an arrayref of module names extracted from the build_requires, configure_requires and requires
728             sections of Build.PL.
729              
730             Each element of the returned arrayref is an arrayref of 2 elements: The module name and the version #.
731              
732             The arrayref is sorted by module name.
733              
734             Called from L.
735              
736             =head2 process_makefile_pl($line_ara)
737              
738             Process Makefile.PL.
739              
740             $line_ara is an arrayref of lines, chomped, read from Makefile.PL.
741              
742             Returns an arrayref of module names extracted from the PREREQ_PM section of Makefile.PL.
743              
744             Each element of the returned arrayref is an arrayref of 2 elements: The module name and the version #.
745              
746             The arrayref is sorted by module name.
747              
748             Called from L.
749              
750             =head2 report_as_html($module_list)
751              
752             $module_list is the arrayref returned from L and L.
753              
754             Outputs a HTML report to STDOUT.
755              
756             Called from L.
757              
758             =head2 report_as_text($module_list)
759              
760             $module_list is the arrayref returned from L and L.
761              
762             Outputs a text report to STDOUT.
763              
764             Called from L.
765              
766             =head2 run()
767              
768             Does all the work.
769              
770             Calls either L or L, then calls either
771             L or L.
772              
773             See L as discussed in the synopsis.
774              
775             Method run() always returns 0 (for success).
776              
777             =head1 Author
778              
779             L was written by Ron Savage Iron@savage.net.auE> in 2011.
780              
781             Home page: L.
782              
783             =head1 Copyright
784              
785             Australian copyright (c) 2011, Ron Savage.
786              
787             All Programs of mine are 'OSI Certified Open Source Software';
788             you can redistribute them and/or modify them under the terms of
789             The Artistic License, a copy of which is available at:
790             http://www.opensource.org/licenses/index.html
791              
792             =cut