Annotation of loncom/build/system_dependencies/perltest.pl, revision 1.9

1.1       harris41    1: #!/usr/bin/perl
                      2: 
1.6       harris41    3: # perltest.pl - script to test the status of perl modules on a LON-CAPA system
1.1       harris41    4: #
1.9     ! harris41    5: # $Id: perltest.pl,v 1.8 2002/09/08 15:53:26 harris41 Exp $
1.6       harris41    6: #
                      7: ###
                      8: 
                      9: =pod
                     10: 
                     11: =head1 NAME
                     12: 
                     13: B<perltest.pl> - Test status of perl modules installed on a LON-CAPA system.
                     14: 
                     15: =cut
                     16: 
                     17: # Written to help LON-CAPA (The LearningOnline Network with CAPA)
1.1       harris41   18: #
                     19: # YEAR=2001
                     20: # 9/30 Scott Harrison
1.6       harris41   21: # YEAR 2002 and onwards
                     22: # Scott Harrison, sharrison@users.sourceforge.net
                     23: 
                     24: =pod
                     25: 
                     26: =head1 SYNOPSIS
                     27: 
                     28: perl perltest.pl [MODE]
                     29: 
                     30: This script is located inside the LON-CAPA source code tree.
                     31: This script is invoked by test-related targets inside
                     32: F<loncapa/loncom/build/Makefile>.
                     33: 
                     34: This script is also used as a CGI script and is installed
1.7       harris41   35: at the file location of F</home/httpd/cgi-bin/perltest.pl>.
1.6       harris41   36: 
                     37: MODE, when left blank, the output defaults to 'statusreport' mode.
                     38: Except however, if $ENV{'QUERY_STRING'} exists, in which case
                     39: 'html' mode is safely assumed.
                     40: 
                     41: Here is a complete list of MODEs.
                     42: 
                     43: =over 4
                     44: 
                     45: =item html
                     46: 
                     47: A web page detailing the status of CPAN distributions on a LON-CAPA server
                     48: (as well as methods for resolution).
                     49: 
                     50: =item synopsis
                     51: 
                     52: Plain-text output which just summarizes the status of
                     53: expected CPAN distributions on a system.  (This is what a
                     54: user sees when running the ./TEST command.)
                     55: 
                     56: =item statusreport
                     57: 
                     58: Plain-text output which provides a detailed status report of
                     59: CPAN distributions on a LON-CAPA server (as well as methods
                     60: for resolution).
                     61: 
                     62: =back
                     63: 
                     64: =head1 DESCRIPTION
                     65: 
                     66: This program tests the status of perl modules installed on a LON-CAPA system.
                     67: As with the other LON-CAPA test scripts, when reasonable, I try
                     68: to avoid importing functionality from other LON-CAPA modules so as to
                     69: avoid indirectly testing software dependencies.
                     70: 
                     71: =head2 ORGANIZATION OF THIS PERL SCRIPT
                     72: 
                     73: The script is organized into the following sections.
                     74: 
                     75: =over 4
                     76: 
                     77: =item 1.
                     78: 
                     79: Process version information of this file.
                     80: 
                     81: =item 2.
                     82: 
                     83: Determine output mode for the script.
                     84: 
                     85: =item 3.
                     86: 
                     87: Output header information.
                     88: 
                     89: =item 4.
                     90: 
                     91: Make sure the perl version is suitably high.
                     92: 
                     93: =item 5.
                     94: 
                     95: Make sure we have the find command.
                     96: 
                     97: =item 6.
                     98: 
                     99: Scan for all the perl modules present on the filesystem.
                    100: 
                    101: =item 7.
                    102: 
                    103: Read in cpan_distributions.txt.
                    104: 
                    105: =item 8.
                    106: 
                    107: Loop through all of the needed CPAN distributions and probe the system.
                    108: 
                    109: =item 9
                    110: 
                    111: Output a report (dependent on output mode).
                    112: 
                    113: =item 10
                    114: 
                    115: Subroutines.
                    116: 
                    117: B<vers_cmp> - compare two version numbers and see which is greater.
                    118: 
                    119: B<have_vers> - syntax check the version number and call B<vers_cmp>.
                    120: 
                    121: =back
                    122: 
                    123: =head1 STATUS
                    124: 
                    125: Ratings: 1=horrible 2=poor 3=fair 4=good 5=excellent
                    126: 
                    127: =over 4
                    128: 
                    129: =item Organization
                    130: 
                    131: 5
                    132: 
                    133: =item Functionality
                    134: 
                    135: 5
                    136: 
                    137: =item Has it been tested?
                    138: 
                    139: 4
                    140: 
                    141: =back
                    142: 
                    143: =head1 AUTHOR
                    144: 
                    145: Scott Harrison, sharrison@users.sourceforge.net, 2001, 2002
                    146: 
                    147: This software is distributed under the General Public License,
                    148: version 2, June 1991 (which is the same terms as LON-CAPA).
                    149: 
                    150: This is free software; you can redistribute it and/or modify
                    151: it under the terms of the GNU General Public License as published by
                    152: the Free Software Foundation; either version 2 of the License, or
                    153: (at your option) any later version.
                    154: 
                    155: This software is distributed in the hope that it will be useful,
                    156: but WITHOUT ANY WARRANTY; without even the implied warranty of
                    157: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                    158: GNU General Public License for more details.
                    159: 
                    160: You should have received a copy of the GNU General Public License
                    161: along with this software; if not, write to the Free Software
                    162: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                    163: 
                    164: =cut
                    165: 
                    166: # =================================== Process version information of this file.
1.9     ! harris41  167: my $VERSION = sprintf("%d.%02d", q$Revision: 1.8 $ =~ /(\d+)\.(\d+)/);
1.6       harris41  168: 
                    169: # ========================== Determine the mode that this script should run in.
                    170: my $mode;
                    171: $mode=shift(@ARGV) if @ARGV;
                    172: unless ( $mode )
                    173:   {
                    174:     $mode = 'statusreport';
                    175:   }
                    176: if ( defined($ENV{'QUERY_STRING'}) )
                    177:   {
                    178:     $mode = 'html';
                    179:   }
                    180: 
                    181: # ================================================== Output header information.
                    182: my $hostname = `hostname`; chomp($hostname);
                    183: my $date = `date`; chomp($date);
                    184: 
                    185: # --- html mode blurb
                    186: if ($mode eq "html") {
                    187:     print(<<END);
                    188: Content-type: text/html
                    189: 
1.8       harris41  190: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                    191:  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1.6       harris41  192: <html>
                    193: <head>
1.8       harris41  194: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
1.6       harris41  195: <title>CPAN perl status report; $hostname; $date</title>
                    196: </head>
1.8       harris41  197: <body bgcolor="white">
1.6       harris41  198: <h1>CPAN perl status report</h1>
                    199: <pre>
                    200: END
                    201: }
                    202: 
                    203: print('Running perltest.pl, version '.$VERSION.'.'."\n");
                    204: print('(Test status of perl modules installed on a LON-CAPA system).'."\n");
                    205: 
                    206: # This program is only a "modest" effort to LOOK and see whether
1.1       harris41  207: # necessary perl system dependencies are present.  I do not yet
                    208: # try to actually run tests against each needed perl module.
1.6       harris41  209: # Eventually, all modules will be version-checked, and reasonable
                    210: # testing implemented.
                    211: 
                    212: # ================================ Make sure the perl version is suitably high.
                    213: print('Checking version of perl'."\n");
                    214: print(`perl --version`);
                    215: unless (eval("require 5.005"))
                    216:   {
                    217:     die('**** ERROR **** DEPENDENCY FAILURE: require perl version >= 5.005.'.
                    218: 	"\n".'Do you even have perl installed on your system?'."\n");
                    219:   }
                    220: else
                    221:   {
                    222:     print('Perl >= 5.005...okay'."\n");
                    223:   }
                    224: 
                    225: # ========================================= Make sure we have the find command.
                    226: my $ret = system("find --version 1>/dev/null");
                    227: if ($ret)
                    228:   {
                    229:     die('**** ERROR **** DEPENDENCY FAILURE: perltest.pl requires the GNU '.
                    230: 	"'find'".' utility.'."\n");
                    231:   }
                    232: else
                    233:   {
                    234:     print('find command exists...okay'."\n");
                    235:   }
                    236: 
                    237: # ==================== Scan for all the perl modules present on the filesystem.
                    238: print('Scanning for perl modules...'."\n");
                    239: my $big_module_string; # All the modules glued together in a string.
                    240: my $number_of_modules = 0; # The total number of modules available in system.
                    241: # --- Build a pattern matching string.
                    242: foreach my $inc (@INC)
                    243:   {
                    244:     my @m = `find $inc -maxdepth 2000 -type f -name '*.pm'`;
                    245:     foreach my $module (@m)
                    246:       {
                    247: 	$big_module_string .= $module;
                    248: 	$number_of_modules++;
                    249:       }
                    250:   }
                    251: # --- Notify user of the number of modules.
                    252: print('There are '.$number_of_modules.
                    253:       ' perl modules present on your filesystem.'."\n");
                    254: 
                    255: my %dist_module_hash; # Relate the distributions to their VersionFrom modules.
                    256: my %module_name_on_filesystem; # Relate module name to filesystem syntax.
                    257: my %dist_dev_version_hash; # Expected development version of CPAN distribution.
                    258: my %dist_stable_version_hash; # Expected stable version of CPAN distribution.
                    259: my %module_dev_version_hash; # development version of versionfrom_module.
                    260: my %module_stable_version_hash; # stable version of versionfrom_module.
                    261: 
                    262: # ============================================= Read in cpan_distributions.txt.
                    263: 
                    264: # A brief description of CPAN (Comprehensive Perl Archive Network):
                    265: # CPAN software is not released as separate perl modules.
                    266: # CPAN software is released as "distributions" (also called "dists").
                    267: # Each distribution consists of multiple perl modules.
                    268: # For instance, the dist HTML-Tree (http://search.cpan.org/dist/HTML-Tree/)
                    269: # consists of the modules HTML::AsSubs, HTML::Element, HTML::Element::traverse,
                    270: # HTML::Parse, HTML::TreeBuilder, and HTML::Tree.
                    271: # Most (but not all) distributions have versions which are defined
                    272: # by one of their modules.  For the syntax of cpan_distributions.txt,
                    273: # please read the comments inside cpan_distributions.txt.
                    274: 
                    275: # Open cpan_distributions.txt.
                    276: open(IN,'<cpan_distributions.txt') or
                    277:     die('**** ERROR **** Cannot find cpan_distributions.txt'."\n");
                    278: 
                    279: while(<IN>) # Loop through the lines.
                    280:   {
                    281:     next if /^\#/; # Ignore commented lines.
                    282:     next unless /\S/; # Ignore blank lines.
                    283: 
                    284:     chomp; # Get rid of the newline at the end of the line.
                    285: 
                    286:     # Parse the line.
                    287:     my ($dist_name,$dist_dev_version,$dist_stable_version,$versionfrom_info) =
                    288: 	split(/\s+/); # Parse apart the line fields.
                    289:     $versionfrom_info =~ /^(.*)\((.*)\)$/; # Parse apart the versionfrom info.
                    290:     my ($version_module,$version_match) = ($1,$2); # Parse vals into variables.
                    291: 
                    292:     # Calculate DevVersion and StableVersion for the VersionFrom module.
                    293:     my $module_dev_version;
                    294:     my $module_stable_version;
                    295:     if ($version_match eq "*") # There is a dist=module version relationship.
                    296:       {
                    297: 	$module_dev_version = $dist_dev_version; # module=dist.
                    298: 	$module_stable_version = $dist_stable_version; # module=dist.
                    299:       }
                    300:     else # There is not a dist=module version relationship.
                    301:       {
                    302: 	($module_dev_version,$module_stable_version) = 
                    303: 	    split(/\,/,$version_match); # module set to customized settings.
                    304:       }
                    305: 
                    306:     $dist_module_hash{$dist_name} = $version_module; # The big dist index.
                    307: 
                    308:     # What the module "looks like" on the filesystem.
                    309:     my $version_modulefs = $version_module;
                    310:     $version_modulefs =~ s!::!/!g; $version_modulefs.='.pm';
                    311:     $modulefs_hash{$version_module} = $version_modulefs;
                    312: 
                    313:     # Indexing the expected versions.
                    314:     $module_dev_version_hash{$version_module} = $module_dev_version;
                    315:     $module_stable_version_hash{$version_module} = $module_stable_version;
                    316:     $dist_dev_version_hash{$dist_name} = $dist_dev_version;
                    317:     $dist_stable_version_hash{$dist_name} = $dist_stable_version;
                    318:   }
                    319: close(IN);
                    320: 
                    321: # "MISSING"  means that no module is present inside the include path.
                    322: # "OUTDATED" means that a module is present inside the include path but is
                    323: #            an earlier version than expected.
                    324: # "VERYOKAY" means that the module version is an exact match for the expected
                    325: #            version.
                    326: # "OKAY"     means that the module version is more recent than the expected
                    327: #            version, so things are "probably" okay....  It is still possible
                    328: #            that LON-CAPA is incompatible with the newer distribution version
                    329: #            (corresponding to the module version).
                    330: my @dev_missing;
                    331: my @dev_outdated;
                    332: my @dev_okay;
                    333: my @dev_veryokay;
                    334: my @stable_missing;
                    335: my @stable_outdated;
                    336: my @stable_okay;
                    337: my @stable_veryokay;
                    338: 
                    339: # ===== Loop through all of the needed CPAN distributions and probe the system.
                    340: foreach my $dist (keys %dist_module_hash)
                    341:   {
                    342:     my $module = $dist_module_hash{$dist};
                    343:     my $fs = $modulefs_hash{$module};
                    344:     my $fsflag = 0;
                    345:     if ($big_module_string =~ /$fs/)
                    346:       {
                    347:         $fsflag = 1;
                    348:       }
                    349:     my ($vok,$vstr);
                    350:     ($vok,$vstr) = have_vers($module,$module_dev_version_hash{$module});
                    351:     # print "fsflag: $fsflag, vok: $vok, vstr: $vstr, fs: $fs\n";
                    352:     if ($fsflag and !$vok and $vstr=~/not found/)
                    353:       {
                    354: 	push(@dev_missing,'MISSING  '.$dist.' (want distribution version '.
                    355: 	     $dist_dev_version_hash{$dist}.') ?'."\n");
                    356: 	# The question mark indicates there was a pattern match in the
                    357: 	# big_module_string which would be unexpected.
                    358: 	# There is no usual reason to tell the normal LON-CAPA user about this
                    359: 	# question mark.  This is just source code magic.
                    360:       }
                    361:     elsif (!$fsflag and !$vok and $vstr=~/not found/)
                    362:       {
                    363: 	push(@dev_missing,'MISSING  '.$dist.' (want distribution version '.
                    364: 	     $dist_dev_version_hash{$dist}.')'."\n");
                    365:       }
                    366:     elsif ($fsflag and !$vok and $vstr!~/not found/)
                    367:       {
                    368: 	push(@dev_outdated,'OUTDATED '.$dist.' wanted module: v'.
                    369: 	     $module_dev_version_hash{$module}.'; '.$vstr.' (VERSION_FROM is '.
                    370: 	     $fs.') want dist version '.$dist_dev_version_hash{$dist}.'.'.
                    371: 	     "\n");
                    372:       }
                    373:     elsif ($fsflag)
                    374:       {
                    375: 	$vstr=~/found v(.*)/;
                    376: 	my $vc=$1;
                    377: 	if ($vc eq $module_dev_version_hash{$module})
                    378:           {
                    379: 	    push(@dev_veryokay,'VERYOKAY '.$dist.' wanted: v'.
                    380: 		 $module_dev_version_hash{$module}.'; '.$vstr.
                    381: 		 ' (VERSION_FROM is '.$fs.') want dist version '.
                    382: 		 $dist_dev_version_hash{$dist}."\n");
                    383: 	  }
                    384: 	else
                    385:           {
                    386: 	    push(@dev_okay,'OKAY     '.$dist.' wanted: v'.
                    387: 		  $module_dev_version_hash{$module}.'; '.$vstr.
                    388: 		  ' (VERSION_FROM is '.$fs.').'."\n");
                    389: 	  }
                    390:       }
                    391:     ($vok,$vstr) = have_vers($module,$module_stable_version_hash{$module});
                    392:     if ($fsflag and !$vok and $vstr=~/not found/)
                    393:       {
                    394: 	push(@stable_missing,'MISSING  '.$dist.' (want distribution version '.
                    395: 	     $dist_stable_version_hash{$dist}.') ?'."\n");
                    396: 	# The question mark indicates there was a pattern match in the
                    397: 	# big_module_string which would be unexpected.
                    398: 	# There is no usual reason to tell the normal LON-CAPA user about this
                    399: 	# question mark.  This is just source code magic.
                    400:       }
                    401:     elsif (!$fsflag and !$vok and $vstr=~/not found/)
                    402:       {
                    403: 	push(@stable_missing,'MISSING  '.$dist.' (want distribution version '.
                    404: 	     $dist_stable_version_hash{$dist}.')'."\n");
                    405:       }
                    406:     elsif ($fsflag and !$vok and $vstr!~/not found/)
                    407:       {
                    408: 	push(@stable_outdated,'OUTDATED '.$dist.' wanted module: v'.
                    409: 	     $module_stable_version_hash{$module}.'; '.$vstr.
                    410: 	     ' (VERSION_FROM is '.$fs.') want dist version '.
                    411: 	     $dist_stable_version_hash{$dist}.'.'."\n");
                    412:       }
                    413:     elsif ($fsflag)
                    414:       {
                    415: 	$vstr=~/found v(.*)/;
                    416: 	my $vc=$1;
                    417: 	if ($vc eq $module_stable_version_hash{$module})
                    418:           {
                    419: 	    push(@stable_veryokay,'VERYOKAY '.$dist.' wanted: v'.
                    420: 		 $module_stable_version_hash{$module}.'; '.$vstr.
                    421: 		 ' (VERSION_FROM is '.$fs.') want dist version '.
                    422: 		 $dist_stable_version_hash{$dist}."\n");
                    423: 	  }
                    424: 	else
                    425:           {
                    426: 	    push(@stable_okay,'OKAY     '.$dist.' wanted: v'.
                    427: 		  $module_stable_version_hash{$module}.'; '.$vstr.
                    428: 		  ' (VERSION_FROM is '.$fs.').'."\n");
                    429: 	  }
                    430:       }
                    431:   }
1.1       harris41  432: 
1.6       harris41  433: print("\n".'SYNOPSIS'."\n");
                    434: 
                    435: # ========================================================== The stable report.
                    436: print('**** STABLE REPORT (what a production server should worry about)'."\n");
1.9     ! harris41  437: if (@stable_missing)
        !           438:   {
1.6       harris41  439:     print('There are '.scalar(@stable_missing).' CPAN distributions missing '.
                    440: 	  'from this LON-CAPA system.'."\n");
1.9     ! harris41  441:   }
        !           442: else
        !           443:   {
1.6       harris41  444:     print('All perl modules needed by LON-CAPA appear to be present.'."\n");
1.9     ! harris41  445:   }
        !           446: if (@stable_outdated)
        !           447:   {
1.6       harris41  448:     print(scalar(@stable_outdated).' CPAN distributions are out-dated '.
                    449: 	  'on this LON-CAPA system.'."\n");
1.9     ! harris41  450:   }
        !           451: if (@stable_veryokay)
        !           452:   {
1.6       harris41  453:     print(scalar(@stable_veryokay).' CPAN distributions are an exact match '.
                    454: 	  '(based on version number).'."\n");
                    455: #    print @stable_veryokay;
1.9     ! harris41  456:   }
        !           457: if (@stable_okay)
        !           458:   {
1.6       harris41  459:     print(scalar(@stable_okay).' CPAN dists have a version number '.
                    460: 	  'higher than expected'.
                    461: 	  ' (probably okay).'. "\n");
1.9     ! harris41  462:   }
1.6       harris41  463: print("\n");
1.1       harris41  464: 
1.6       harris41  465: # ===================================================== The development report.
                    466: print('**** DEVELOPMENT REPORT (do not worry about this unless you are a'.
                    467:       ' coder)'."\n");
1.9     ! harris41  468: if (@dev_missing)
        !           469:   {
1.6       harris41  470:     print('There are '.scalar(@dev_missing).' CPAN distributions missing '.
                    471: 	  'from this LON-CAPA system.'."\n");
1.9     ! harris41  472:   }
        !           473: else
        !           474:   {
1.6       harris41  475:     print('All perl modules needed by LON-CAPA appear to be present.'."\n");
1.9     ! harris41  476:   }
        !           477: if (@dev_outdated)
        !           478:   {
1.6       harris41  479:     print(scalar(@dev_outdated).' CPAN distributions are out-dated '.
                    480: 	  'on this LON-CAPA system.'."\n");
1.9     ! harris41  481:   }
        !           482: if (@dev_veryokay)
        !           483:   {
1.6       harris41  484:     print(scalar(@dev_veryokay).' CPAN distributions are an exact match '.
                    485: 	  '(based on version number).'."\n");
                    486: #    print @dev_veryokay;
1.9     ! harris41  487:   }
        !           488: if (@dev_okay)
        !           489:   {
1.6       harris41  490:     print(scalar(@stable_okay).' CPAN dists have a version number '.
                    491: 	  'higher than expected'.
                    492: 	  ' (probably okay).'. "\n");
1.9     ! harris41  493:   }
1.6       harris41  494: 
1.9     ! harris41  495: my $detailstream;
        !           496: if ($mode eq 'synopsis')
        !           497:   {
1.6       harris41  498:     print("\n".'**** NOTE ****'."\n".
                    499: 	  'After everything completes, please view the CPAN_STATUS_REPORT'.
                    500: 	  ' file for more '."\n".'information on resolving your perl modules.'.
                    501: 	  "\n");
                    502: 
                    503:     print('* HIT RETURN WHEN READY TO CONTINUE *'."\n");
                    504:     my $returnkey=<>;
1.9     ! harris41  505:     open(OUT,'>CPAN_STATUS_REPORT');
        !           506:     $detailstream=\*OUT;
        !           507:   }
        !           508: else
        !           509:   {
        !           510:     $detailstream=\*STDOUT;
        !           511:   }
        !           512: print($detailstream 
        !           513:       "\n".'DETAILED STATUS REPORT'."\n"); # Header of status report.
1.6       harris41  514: 
1.9     ! harris41  515: # Print advisory notices.
        !           516: print($detailstream
        !           517:       "\n".'(Consult loncapa/doc/otherfiles/perl_modules.txt for '.
        !           518:       'information on'."\n".
        !           519:       ' manual build instructions.)'."\n");
        !           520: print($detailstream
        !           521:       "\n".'(**** IMPORTANT NOTICE **** HTML-Parser needs to be patched '.
        !           522:       "\n".' as described in loncapa/doc/otherfiles/perl_modules.txt)'.
        !           523:       "\n");
        !           524: 
        !           525: print($detailstream
        !           526:       "\n".'For manual installation of CPAN distributions, visit'."\n".
        !           527:       'http://search.cpan.org/dist/DistName'."\n".
        !           528:       'where DistName is something like "HTML-Parser" or "libwww-perl".'.
        !           529:       "\n");
        !           530: 
        !           531: print($detailstream
        !           532:       "\n".'For automatic installation of CPAN distributions, visit'."\n".
        !           533:       'http://install.lon-capa.org/resources/cpanauto/DistName.bin'."\n".
        !           534:       'where DistName.bin is something like "HTML-Parser.bin" or '.
        !           535:       '"libwww-perl.bin".'."\n");
        !           536: 
        !           537: # Print detailed report of stable.
        !           538: print($detailstream
        !           539:       "\n".'STABLE (DETAILED REPORT)'."\n");
        !           540: print $detailstream @stable_missing;
        !           541: print $detailstream @stable_outdated;
        !           542: print $detailstream @stable_veryokay;
        !           543: print $detailstream @stable_okay;
        !           544: print($detailstream "\n".'DEVELOPMENT (DETAILED REPORT)'."\n");
        !           545: print $detailstream @dev_missing;
        !           546: print $detailstream @dev_outdated;
        !           547: print $detailstream @dev_veryokay;
        !           548: print $detailstream @dev_okay;
1.6       harris41  549: 
1.9     ! harris41  550: if ($mode eq "html")
        !           551:   {
1.6       harris41  552:     print(<<END);
                    553: </pre>
                    554: </body>
                    555: </html>
1.5       harris41  556: END
1.9     ! harris41  557:   }
1.6       harris41  558: 
                    559: # ================================================================ Subroutines.
                    560: # Note that "vers_cmp" and "have_vers" are adapted from a bugzilla version 2.16
                    561: # "checksetup.pl" script.
                    562: 
                    563: # ------------ vers_cmp : compare two version numbers and see which is greater.
                    564: # vers_cmp is adapted from Sort::Versions 1.3 1996/07/11 13:37:00 kjahds,
                    565: # which is not included with Perl by default, hence the need to copy it here.
                    566: # Seems silly to require it when this is the only place we need it...
                    567: sub vers_cmp
                    568:   {
                    569:     if (@_ < 2) { die "not enough parameters for vers_cmp" }
                    570:     if (@_ > 2) { die "too many parameters for vers_cmp" }
                    571:     my ($a, $b) = @_;
                    572:     my (@A) = ($a =~ /(\.|\d+|[^\.\d]+)/g);
                    573:     my (@B) = ($b =~ /(\.|\d+|[^\.\d]+)/g);
                    574:     my ($A,$B);
                    575:     while (@A and @B)
                    576:       {
                    577:         $A = shift @A;
                    578:         $B = shift @B;
                    579:         if ($A eq "." and $B eq ".")
                    580:           {
                    581:             next;
                    582:           }
                    583:         elsif ( $A eq "." )
                    584:           {
                    585:             return -1;
                    586:           }
                    587:         elsif ( $B eq "." )
                    588:           {
                    589:             return 1;
                    590:           }
                    591:         elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/)
                    592:           {
                    593:             return $A <=> $B if $A <=> $B;
                    594:           }
                    595:         else
                    596:           {
                    597:             $A = uc $A;
                    598:             $B = uc $B;
                    599:             return $A cmp $B if $A cmp $B;
                    600:           }
                    601:       }
                    602:     @A <=> @B;
                    603:   }
                    604: 
                    605: # --------------- have_vers: syntax check the version number and call vers_cmp.
                    606: # This was originally clipped from the libnet Makefile.PL, adapted here to
                    607: # use the above vers_cmp routine for accurate version checking.
                    608: sub have_vers
                    609:   {
                    610:     my ($pkg, $wanted) = @_;
                    611:     my ($msg, $vnum, $vstr);
                    612:     no strict 'refs';
                    613:     # printf("Checking for %15s %-9s ", $pkg, !$wanted?'(any)':"(v$wanted)");
                    614: 
                    615:     eval { my $p; ($p = $pkg . ".pm") =~ s!::!/!g; require $p; };
                    616: 
                    617:     $vnum = ${"${pkg}::VERSION"} || ${"${pkg}::Version"} || 0;
                    618:     $vnum = -1 if $@;
                    619: 
                    620:     if ($vnum eq "-1") # string compare just in case it's non-numeric
                    621:       {
                    622:         $vstr = "not found";
                    623:       }
                    624:     elsif (vers_cmp($vnum,"0") > -1)
                    625:       {
                    626:         $vstr = "found v$vnum";
                    627:       }
                    628:     else
                    629:       {
                    630:         $vstr = "found unknown version";
                    631:       }
                    632: 
                    633:     my $vok = (vers_cmp($vnum,$wanted) > -1);
                    634:     # print ((($vok) ? "ok: " : " "), "$vstr\n");
                    635:     return ($vok,$vstr);
                    636:   }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>