Blob Blame History Raw
#!/usr/bin/perl

# This script tests docbook2X by mass-converting a set of XML DocBook
# documents to man pages and Texinfo documents.  The author
# uses this script on Doclifter-generated refentry documents.
#
# This script differs from ../doclifter/test.pl 
# in that it does not invoke doclifter directly
# (newer versions of doclifter has a mass conversion command,
# manlifter).  It also works much faster, as xsltproc and
# db2x_manxml/db2x_texixml are only loaded once for each
# set of documents.
# 
# It will automatically log any syntactical errors, but other sorts
# of errors (i.e. incorrect rendering) will have to be found with 
# manual insepection.  Timings of the conversion process 
# are also printed out.
# 
# To use this script, the following programs need to be installed:
#  * perl
#  * libxslt (xsltproc) XSLT processor
#  * xmllint from libxml2
#  * makeinfo from Texinfo package
#  * groff from GNU Troff package
#
# IMPORTANT:
# If the executables of docbook2X are not in the directory tree
# that this script lives, then you have to modify the paths below
# before running this script.
# 

use FindBin qw($RealBin);
my $db2x_home = "${RealBin}/../../";

# build directory if not the same as source dir.
my $db2x_build = $db2x_home; 

use strict;
use Getopt::Long;

my $mandir_sect = '';
my $tag = '';
my $type = 'man';
my $components = 'dxu';

Getopt::Long::Configure ("bundling");
my $res = GetOptions ("tag|t=s" => \$tag,         # tag for log filenames
                      "s=s" => \$type,
                      "c=s" => \$components);
die if !$res;

$tag = 'TEST' if $tag eq '';

open(STDERR, "| tee -a $tag.log");

my @dirs = @ARGV;

# Current timings; see process_timings subroutine
my $current_cutm = 0;
my $current_cstm = 0;

foreach my $dir (@dirs)
{
  $dir =~ s/\/$//;
#  my @sources = glob("$dir/*.xml");

  if($type eq 'man') {
  
    if($components =~ /d/) {
      # DocBook to Man-XML step
      my $cmd = "xsltproc --stringparam doctype-system ${db2x_home}dtd/Man-XML --stringparam path $dir ${db2x_home}test/mass/sep-man.xsl $dir/*.xml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    if($components =~ /D/) {
      $ENV{db2x_dtd} = "${db2x_home}dtd/Man-XML";
      my $cmd = "xsltproc --stringparam lowercase-file 1 ${db2x_home}xslt/man/docbook.xsl $dir/*.xml | ${db2x_home}test/mass/collect-manpageset.sed > $dir/$tag.Mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }

    if($components =~ /v/) {
      my $cmd = "xmllint --stream --valid $dir/*.mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    if($components =~ /V/) {
      my $cmd = "xmllint --stream --valid $dir/$tag.Mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }

    if($components =~ /x/) {
      # Man-XML to man pages step
      my $cmd = "${db2x_build}perl/db2x_manxml --list-files --output-dir=$dir --encoding=utf-8 $dir/*.mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    if($components =~ /X/) {
      # Man-XML to man pages step
      my $cmd = "${db2x_build}perl/db2x_manxml --list-files --output-dir=$dir --encoding=utf-8 $dir/$tag.Mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    
    if($components =~ /y/) {
      # DocBook to Man-XML step
      my $cmd = "xsltproc --stringparam output-dir $dir ${db2x_home}xslt/backend/db2x_manxml.xsl $dir/*.mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    if($components =~ /Y/) {
      # DocBook to Man-XML step
      my $cmd = "xsltproc --stringparam output-dir $dir ${db2x_home}xslt/backend/db2x_manxml.xsl $dir/$tag.Mxml";
      my $err = system3($cmd);
      if($err) { next; }
    }
      
    if($components =~ /u/) {
      # utf8trans step
      my $cmd = "${db2x_build}utf8trans/utf8trans -m ${db2x_home}charmaps/roff.charmap $dir/*.[1-9]*";
      my $err = system3($cmd);
      if($err) { next; }
    }

    if($components =~ /g/) {
      # Test by running through groff
      my $cmd = "groff -t -Tutf8 -w all -man $dir/*.[1-9]* >$dir/$tag.g";
      my $err = system3($cmd);
      if($err) { next; }
    }
    
    if($components =~ /h/) {
      # Test by running through ../htest-man.pl
      my $cmd = "perl ${db2x_home}test/htest-man.pl $dir/*.[1-9]*";
      my $err = system3($cmd);
      if($err) { next; }
    }

  }

  elsif($type eq 'texi') {

    if($components =~ /d/) {
      # DocBook to Texi-XML step
      my $cmd = "xsltproc --stringparam doctype-system ${db2x_home}dtd/Texi-XML --stringparam path $dir ${db2x_home}test/mass/sep-texi.xsl $dir/*.xml";
      my $err = system3($cmd);
      if($err) { next; }
    }
    
    if($components =~ /v/) {
      my $cmd = "xmllint --stream --valid $dir/*.txml";
      my $err = system3($cmd);
      if($err) { next; }
    }

    if($components =~ /x/) {
      # Texi-XML to Info step
      my $cmd = "${db2x_build}perl/db2x_texixml --list-files --output-dir=$dir --encoding=utf-8//TRANSLIT $dir/*.txml";
      my $err = system3($cmd);
      if($err) { next; }
    }

    if($components =~ /u/) {
      # utf8trans step
      my $cmd = "${db2x_build}utf8trans/utf8trans -m ${db2x_home}charmaps/texi.charmap $dir/*.texi";
      my $err = system3($cmd);
      if($err) { next; }
    }
    
    if($components =~ /g/) {
      # Test by running through makeinfo
      my $cmd = "cd $dir && makeinfo --no-split *.texi";
      my $err = system3($cmd);
      if($err) { next; }
    }
  }

}

sub system3
{
  my $cmd = shift @_;
  print STDERR "<<< starting executing $cmd >>>\n";
  my $err = system2($cmd);
  my ($cutm,$cstm) = process_timings();
  print STDERR " user ${cutm}s, system ${cstm}s\n";
  if($err) {
    print STDERR "<<< error executing $cmd >>>\n\n";
  } else {
    print STDERR "<<< finished executing $cmd >>>\n\n";
  }
  return $err;
}


sub system2
{
    system(@_);
    if ($? == -1) {
        die "failed to execute: $!\n";
    }
    elsif ($? & 127) {
        printf "child died with signal %d, %s coredump\n",
            ($? & 127),  ($? & 128) ? 'with' : 'without';
        return -1;
    }
    else {
        return $? >> 8;
    }
}

sub process_timings()
{
  # utm means "user time"
  # stm means "system time", etc.
  # 
  my ($utm,$stm,$new_cutm,$new_cstm) = times;

  my $last_cutm = $new_cutm - $current_cutm;
  my $last_cstm = $new_cstm - $current_cstm;

  $current_cutm = $new_cutm;
  $current_cstm = $new_cstm;

  return ($last_cutm, $last_cstm);
}