#!/usr/local/bin/perl5
# 
# TFMPKtest.pl : control the checksum of pk font (use the tfm font).  
# Can delete bad pk font with checksum  missmatch and recreate it with mktexpk.
# Can also control TFM files by generating new TFM with the MF files and mf.
# TFMPKtest.pl need pktype, tftopl and mf.
# 
# License: LaTeX Project Public License (lppl)
# (CTAN:/help/Catalogue/licenses.lppl.html)
#
# Dominique Larchey (e-mail: larchey@loria.fr web: http://www.loria.fr/~larchey)
# Denis Roegel (e-mail: roegel@loria.fr web: http://www.loria.fr/~roegel)
# Christian Rossi (e-mail: rossi@loria.fr web: http://www.loria.fr/~rossi)
# 
# This perl script is on the web :  http://www.loria.fr/~rossi/tfmpktest.pl
#
# (La)TEX Navigator (http://www.loria.fr/services/tex/)
# CTAN Navigator (http://ctan.loria.fr/)
# LORIA (http://www.loria.fr/) - Nancy - France
# 2000/07/08

# options 

use Getopt::Long;
GetOptions('dir=s',\@dir,'c!','control!','d!','del!','t!','tfm!','v!','verbose!','h!','help!');

# if -h or --h or -help or --help 

if (($opt_h) || ($opt_help))
  {
    print "tfmpktest.pl v. 0.11 by DL/DR/CR - LORIA\n";
    print "Usage: tfmpktest.pl [OPTIONS] \n\n";
    print "--help                  for more information\n";
    print "--control               control pkfont (default)\n";
    print "--del                   delete pkfont with checksum\n";
    print "                        mismatch and create the new pk\n";
    print "--tfm                   control TFM files\n";
    print "--dir DIR1 [, DIR2...]  pk font directories\n";    
    print "--verbose               verbose\n";
    print "\n";
    print "TFMPKtest.pl : control the checksum of pk font (use the tfm font).\n";  
    print "Can delete bad pk font with checksum missmatch and recreate it with mktexpk.\n";
    print "Can also control TFM files by generating new TFM with the MF files and mf.\n";
    print "TFMPKtest.pl need pktype and tftopl for pk control and TFM control need mf.\n";
    print "\n";
    exit;
  }

# pid for the logfile name 
$pid = $$;
if (($opt_tfm) || ($opt_t)) 
  {
    $logfile="/tmp/tfmtest." . $pid . ".log";
  } else
  {
    $logfile="/tmp/pktest." . $pid . ".log";
  }

print "PKtest v0.1 by DL/DR/CR - LORIA\n\n";
print "Logfile : $logfile \n";

open(LOGFILE,">$logfile");

# no buffer for the print command on the logfile and on stdout

select(LOGFILE); 
$| = 1;  
select(STDOUT);
$| = 1;

# dir for the tfm font 
if (($opt_tfm) || ($opt_t)) 
  {
    $testmkdir =  mkdir("/tmp/tfmtest.$pid",0777);  
    if (! $testmkdir) {
      print "Cannot mkdir /tmp/tfmtest.$pid\n";
    }
    $currentpwd = `pwd`;
    chdir("/tmp/tfmtest.$pid");
  }

# test if -dir or --dir option for the pk font directories

$numberofdir=@dir;

# if no -dir use kpsewhich to find the font directories

if ( $numberofdir == 0 ) 
  {
    $vartexfonts=`kpsewhich -expand-var '\$VARTEXFONTS'`;
    $texmf=`kpsewhich -expand-var '\$TEXMF'`;
    $texmf =~ s/[{}!! \n]//g;
    @dir_list = split(/,/,$texmf);
    @new_dir_list = ();
    
    # add strings /fonts/pk to $TEXMF
    
    foreach $path (@dir_list)
      {
        if (($opt_tfm) || ($opt_t))
	  {
	    $path = $path . "/fonts/tfm";
	  } else
	    {
	      $path = $path . "/fonts/tk";
	    }	
	@new_dir_list = (@new_dir_list,$path);
      }
    # add /pk to $vartexfonts
    chop($vartexfonts);
    $ext=pk;
    if (($opt_tfm) || ($opt_t)) { 
      $ext=tfm;
    } 
    @new_dir_list = ("$vartexfonts/$ext",@new_dir_list);    
  } 
else 
  { 
    @new_dir_list = @dir;
  }

# main loop 
foreach $path (@new_dir_list)
  {
    $dir = $path;
    print "\nDirectory: $dir\n";
    print LOGFILE "\n\nDirectory: $dir\n\n";
    $numberfont = 0;
    $notfm = 0;
    $mismatch = 0;
    $nodelete = 0;
    $nbdifftfm = 0;
    $mfnotfound = 0;
    $newtfmnotok = 0;
    # number of file 
    
    open(LISTE,"du -a $dir|");
    # loop for each file or directory of du 
    while (<LISTE>)
      {
	# use only ligne with .pk at the end
	if (($opt_tfm) || ($opt_t)) 
	  {  
	    if (/\.tfm$/)
	      {
		$tab[$numberfont]=$_;
		$numberfont = $numberfont + 1;
	      }
	  }
	else {
	  if (/\..*pk$/)
	    {
	      $tab[$numberfont]=$_;
	      $numberfont = $numberfont + 1;
	    }
        }
      }
    
    print "Number of files: $numberfont \n";
    
    # inc to use for the display of % 
    
    $inc = $numberfont / 100;
    $incint= int($inc) + 1;
    
    $i=0;
    $j=0;
    $val = 0;
    print " 0% ";
    
    for ($indice=0; $indice < $numberfont ; $indice++)
      {
	$longname=$tab[$indice];
	($block,$filename) = split(/\t/,$longname);
	
	# work only with the file *.pk or *.tfm
	$tfm_test = (($opt_tfm) || ($opt_t));
	
	if (((! $tfm_test) && ($filename =~ /\..*pk$/)) || (($tfm_test) && ($filename =~ /\.tfm$/)))  
	  {
	    $i = $i + 1;
	    $res = $i % $incint;
	    # need to display the % ?
	    if (! $res)
	      {
		$j= $j + 1;
		$val = $j; 
		if (($val > 9) && ! (($val) % 10))
		  {
		    print "\n";
		  }
		if  ($val < 10)
		  {print " $val% ";}
		else{
		  print "$val% ";
		}
	      }
	    
	    if  ($tfm_test)     
	      { 
		
		&chk_font_tfm($filename); 
		
	      } else
		{
		  $dpi="";
		  $shortnamepk="";
		  $fontname="";
		  
		  @field=split(/\//,$filename);
		  
		  $numberfield=@field;
		  # name of printer
		  $previous="";
		  foreach $n (reverse @field) {
		    if ($n eq pk) {
		      $printer=$previous;
		    }
		    $previous=$n;
		  }
		  # try to find dpi 
		  $shortnamepk = $field[$numberfield - 1];	    
		  split(/\//,$filename);	    
		  chop($shortnamepk);
		  ($fontname,$dpi)=split(/\./,$shortnamepk);
		  $dpi =~ s/pk//;
		  
		  if (! $dpi)
		    {
		      @dir=split(/\//,$longname);
		      $number = @dir;
		      $number = $number - 2;
		      $dpi=$dir[$number];
		      $dpi =~ s/dpi//;
		    }
		  # now check each font  
		  if ($dpi)
		    {
		      &chk_font_pk($shortnamepk,$fontname);
		    }
		}
	  }
	
      }
    # display the last % 
    for ($inc = $val + 1 ; $inc < 100; $inc++) {
      if (($inc > 9) && ! (($inc) % 10))
	{
	  print "\n";
	}
      if  ($inc < 10)
	{
	  print " $inc% ";
	}
      else 
	{
	  print "$inc% ";
	} 
    }
    # result of the check
    print "100%\n";
    if ($tfm_test)
      {   
        print "\n---> TFM font that differ: $nbdifftfm - MF file not found: $mfnotfound - TFM not generated: $newtfmnotok\n";    
	print LOGFILE "\n---> TFM font that differ: $nbdifftfm - MF file not found: $mfnotfound - TFM not generated: $newtfmnotok\n"; 
      } else {
	print "\n---> TFM font not found: $notfm - Checksum mismatch: $mismatch";    
	print LOGFILE "\n---> TFM font not found: $notfm - checksum mismatch: $mismatch"; 
	if  ($nodelete)
	  {
	    print " - Impossible delete: $nodelete\n"; 
	    print LOGFILE " - Impossible delete: $nodelete\n";     
	  } else
	    {
	      print LOGFILE "\n";
	      print "\n"; 
	    } 
      }
  }

chdir("$currentpwd");
print "\n";
print "Logfile: $logfile \n";
print LOGFILE "\n";
print "\n";

#-----------------------------------------------------------------------
# chk_font_pk - test the  Checksum of the pk and tfm files
#  
#-----------------------------------------------------------------------

sub  chk_font_pk
  {
    
    local($fontpk,$fonttfm);
    
    ($fontpk,$fonttfm) = @_;
    
    $chk_pk   = `pktype $fontpk  2>/dev/null | grep Checksum`;
    $chk_tfm  = `tftopl $fonttfm 2>/dev/null | grep CHECKSUM`;
    
    $_ = $chk_pk;  
    /^Checksum = (.*)/;  
    $chk_pk  = sprintf("0%lo", $1);
    
    $_ = $chk_tfm;
    /^[^\d]*(\d*).*/;
    $chk_tfm = sprintf("0%s",  $1);
    
    if ($chk_pk != $chk_tfm) {       
      if ($chk_tfm == 0)
	{
	  if (($opt_v == 1) || ($opt_verbose == 1))
	    {
	      print "TFM file doesn't exist: $fonttfm.tfm\n";
	    }
	  print LOGFILE "TFM file doesn't exist: $fonttfm.tfm \n";
	  $notfm = $notfm + 1 ;
	} 
      else
	{
	  $bdpi=600;
	  if (($opt_d == 1) || ($opt_del == 1))
	    {
	      chop($filename);
	      $testrm=unlink($filename);
	      if   ($testrm)
		{    
		  if (($opt_v == 1) || ($opt_verbose == 1))
		    {
		      print "Delete file: $filename \n";
		    }
		  print LOGFILE "Delete file: $filename\n";
		  $result=`mktexpk --mfmode $printer --bdpi $bdpi --mag ${dpi}/${bdpi} --dpi $dpi $fonttfm 2>&1`;
		  (($opt_v == 1) || ($opt_verbose == 1)) and print "$result\n";
		  print LOGFILE "$result\n";
		} else
		  {
		    print LOGFILE  "Impossible delete: $filename \n";
		    $nodelete = $nodelete + 1; 
		    if (($opt_v == 1) || ($opt_verbose == 1))
		      {
			print "Impossible delete: : $filename \n";
		      }
		  }
	    }
	  else
	    {  
              $longfonttfm=`kpsewhich $fonttfm.tfm`;
		chop($longfonttfm);
	      if (($opt_v == 1) || ($opt_verbose == 1))
		{
		  print "Cheksum missmatch: $shortnamepk and $longfonttfm \n";
		}
	      chop($filename);
	      print LOGFILE "Cheksum missmatch: $filename and $longfonttfm \n";
	    }
	  $mismatch = $mismatch + 1;
	}
      
    }
  }

#-----------------------------------------------------------------------
# chk_font_tfm - test the Checksum of the mf and tfm files
#  
#-----------------------------------------------------------------------

sub  chk_font_tfm
  {
    
    local($fonttfm);
    ($fonttfm) = @_;
    @field=split(/\//,$fonttfm);
    $numberfield = @field;
    $shortnametfm = $field[$numberfield - 1];
    ($name,$extfile) = split(/\./,$shortnametfm);
    
    $testkpse = system("kpsewhich $name.mf >/dev/null 2>&1");
    if (! $testkpse)
      {
	$resulttfm=`mf '\\mode=localfont;input $name' -interaction=nonstopmode 2>&1`;
	if (-f "/tmp/tfmtest.$pid/$name.tfm") 
	  {
	    if (($opt_v == 1) || ($opt_verbose == 1))
	      {
		#print "$resulttfm\n";
	      }
	    #print LOGFILE "$resulttfm\n";
	    chop($shortnametfm);
            $usename = "/tmp/tfmtest." . $pid . "/" . $shortnametfm;         
            #$testdiff=system("cmp -s $usename $fonttfm");;
            
            if ($testdiff)
	      {
		if (($opt_v == 1) || ($opt_verbose == 1))
		  {
		    print "TFM file differ: $shortnametfm\n";
		  }
		
		print LOGFILE "TFM file differ: $fonttfm";
		$nbdifftfm = $nbdifftfm + 1;
	      }            
	    unlink("/tmp/tfmtest.$pid/$name.tfm");
	    unlink("/tmp/tfmtest.$pid/$name.log");
	    unlink("/tmp/tfmtest.$pid/$name.600gf"); 
	  }
	else
	  {
	    if (($opt_v == 1) || ($opt_verbose == 1)) 
	      {
		print "TFM file not generated: $name.tfm\n"; 
	      } 
	    print LOGFILE "TFM file not generated: $name.tfm\n";
	    $newtfmnotok = $newtmfnotok + 1;
            unlink("/tmp/tfmtest.$pid/$name.log");
	    unlink("/tmp/tfmtest.$pid/$name.600gf"); 
	  }
      }
    else 
      {
	if (($opt_v == 1) || ($opt_verbose == 1)) 
	  {
	    print "MF file not found: $name.mf\n"; 
	  } 
	print LOGFILE "MF file not found: $name.mf\n";
        $mfnotfound = $mfnotfound + 1;	
      }        
  }
