From dc018b5e0d65b5fa0390a395f0815a53fcf60b33 Mon Sep 17 00:00:00 2001 From: Norman Walsh Date: Wed, 14 Dec 2005 11:52:39 +0000 Subject: [PATCH] Rewrite to use local config instead of jumping through hoops trying to figure it all out --- cvstools/saxon | 640 +++++++++++++++++++++++----------------------- cvstools/xalan | 505 +++++++++++++++++++++--------------- cvstools/xslt | 157 +----------- cvstools/xsltproc | 286 ++++++++++++++++++--- 4 files changed, 889 insertions(+), 699 deletions(-) diff --git a/cvstools/saxon b/cvstools/saxon index a6707c16f..80183a1fe 100755 --- a/cvstools/saxon +++ b/cvstools/saxon @@ -1,320 +1,326 @@ -#!/bin/bash - -# This script is usually called by the xslt script. +#!/usr/bin/perl -w -- # -*- Perl -*- +# +# This script runs the Saxon XSLT processor. It relies on a configuration +# file to identify java versions, class paths, etc. +# +# Usage: saxon [opts] input style [output] [params] +# +# Options: # -# Usage: saxon [shellopts] src.xml style.xsl output.{xml|html} [styleopts] +# -6... Specifies Saxon 6 or some specific version of Saxon 6 +# -8... Specifies Saxon 8 or some specific version of Saxon 8 +# -8...sa Specifies "Schema Aware" Saxon. Requires a license. +# -8...b Specifies basic Saxon. +# -debug Debugging +# -config Where is the config file? Defaults to ~/.xmlc +# -opts id Use additional options 'id' from the config file. +# The -opts option may be specified more than once # +# Any other options are passed to Saxon unchanged +# +# Default version is calculated by looking at the stylesheet. So the +# -6/-8 option is usually unnecessary. + +use strict; +use English; +use XML::XPath; +use XML::XPath::XMLParser; + +my $usage = "saxon [opts] input style [output] [params]\n"; + +my $version = undef; +my $saxonsa = undef; +my $debug = 0; +my $config = "~/.xmlc"; +my @opts = (); + +while (@ARGV) { + if ($ARGV[0] =~ /^\-6/) { + $version = substr($ARGV[0],1); + shift @ARGV; + } elsif ($ARGV[0] =~ /^\-(8.*?)-?(sa|b)?$/) { + $version = $1; + $saxonsa = $2 if defined($2); + shift @ARGV; + } elsif ($ARGV[0] eq '-debug') { + $debug = 1; + shift @ARGV; + } elsif ($ARGV[0] eq '-config') { + shift @ARGV; + $config = shift @ARGV; + } elsif ($ARGV[0] eq '-opts') { + shift @ARGV; + push(@opts, shift @ARGV); + } else { + last; + } +} + +my @params = (); +while (@ARGV && $ARGV[$#ARGV] =~ /=/) { + unshift (@params, pop @ARGV); +} + +my $input = undef; +my $style = undef; +my $output = undef; + +my $opt_a = 0; +foreach my $opt (@ARGV) { + $opt_a = 1 if $opt eq '-a'; + last if $opt_a; +} + +if ($opt_a) { + $output = pop @ARGV; + $input = pop @ARGV; + + # What if the user didn't specify an output location? + if (!defined($input) || $input =~ /^-/) { + push (@ARGV, $input) if defined($input); + $input = $output; + $output = undef; + } +} else { + $output = pop @ARGV; + $style = pop @ARGV; + $input = pop @ARGV; + + # What if the user didn't specify an output location? + if (!defined($input) || $input =~ /^-/) { + push (@ARGV, $input) if defined($input); + $input = $style; + $style = $output; + $output = undef; + } +} + +# Everything else goes to Saxon +my @saxonopts = @ARGV; +push (@saxonopts, "-o $output") if defined($output) && $output ne '-'; + +die $usage if !defined($input) || (!defined($style) && !$opt_a); + +if (!defined($version)) { + if (defined($style)) { + open (F, $style) || die "Cannot open stylesheet: $style\n$usage"; + read (F, $_, 4096); + close (F); + + if (/<\S+:?import-schema/s) { + $version = "8" if !defined($version); + $saxonsa = "sa" if !defined($saxonsa); + } elsif (/<\S+:?stylesheet[^>]*\sversion=.2\.0/s + || /<\S+:?transform[^>]*\sversion=.2\.0/s) { + $version = "8" if !defined($version); + $saxonsa = "b" if !defined($saxonsa) && $version =~ /^8/; + } else { + $version = "6" if !defined($version); + } + } else { + $style = ""; + $version = "6" if !defined($version); + } +} + +my $optsname = "saxon"; +$optsname .= $saxonsa if defined($saxonsa); +$optsname .= "-$version"; + +# Inelegantly, these are used as globals by several functions +my %seenopts = (); +my $classname = ""; +my $java = ""; +my @systemprops = (); +my @javaopts = (); +my @classpath = (); + +$config = (glob($config))[0]; # hack to expand ~/.xmlc to right place + +die "Cannot read config: $config\n$usage" if ! -f $config; +my $xp = XML::XPath->new('filename' => $config); +my $doc = ($xp->find("/config")->get_nodelist())[0]; +die "Unexpected root element in configuration file.\n" if !$doc; + +# Figure out the class path separator before we go any further +my $cpseparator = $doc->getAttribute('classpath-separator'); +# Default to ';' if it appears in $CLASSPATH, otherwise ':' +$cpseparator = ($ENV{'CLASSPATH'} =~ /;/ ? ";" : ":") + if !defined($cpseparator) or $cpseparator eq ''; + +foreach my $name (@opts, $optsname) { + applyOpts($xp, $name); +} + +$java = "java" if $java eq ''; + +foreach my $path (reverse split(/$cpseparator/, $ENV{'CLASSPATH'})) { + unshift(@classpath, $path); +} + +showVars() if $debug; + +die "No classname?\n" if !defined($classname); + +my $jopts = join(" ", @javaopts); +my $jprops = join(" ", @systemprops); +my $jcp = join($cpseparator, @classpath); +my $sopts = join(" ", @saxonopts); +my $sparam = join(" ", @params); + +if ($cpseparator eq ';') { + # This must be cygwin or some windows flavor, let's try to make it work + $jcp =~ s/\//\\\\/sg; # turn / into \\ in classpath paths + $jcp =~ s/\;/\\\;/sg; # escape semicolons + if (@params) { + $sparam = "\"" . join("\" \"", @params) . "\""; + } else { + $sparam = ""; + } +} + +print "$java $jopts $classname $sopts $input $style $sparam\n" if $debug; +exec("$java $jopts -cp $jcp $jprops $classname $sopts $input $style $sparam"); + +# ============================================================ + +sub applyOpts { + my $xp = shift; + my $id = shift; + + # Avoid loops + if ($seenopts{$id}) { + print STDERR "Skipping $id (already seen)\n" if $debug; + return; + } + $seenopts{$id} = 1; + + my $saxon = ($xp->find("/config/*[\@xml:id='$id']")->get_nodelist())[0]; + + die "Config $config does not contain $id.\n" if !defined($saxon); + + print STDERR "Loading $id from $config\n" if $debug; + + $classname = $saxon->getAttribute('class') + if $classname eq ''; + + $java = $saxon->getAttribute('java') + if $java eq ''; + + foreach my $path (configPath($saxon, 'classpath', $cpseparator)) { + addOpt(\@classpath, $path); + } + + foreach my $prop (configArgs($saxon, 'system-property', '-D', '=')) { + addOpt(\@systemprops, $prop, '='); + } + + foreach my $arg (configArgs($saxon, 'arg', '-', ' ')) { + addOpt(\@saxonopts, $arg, ' '); + } + + foreach my $opt (configArgs($saxon, 'java-option', '-', '=')) { + addOpt(\@javaopts, $opt, ' '); + } + + foreach my $param (configArgs($saxon, 'param', '', '=')) { + addOpt(\@params, $param, '='); + } + + my $extends = $saxon->getAttribute('extends'); + applyOpts($xp, $extends) if $extends ne ''; +} + +sub configArgs { + my $context = shift; + my $elemname = shift; + my $prefix = shift; + my $sep = shift; + my @opts = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $name = $arg->getAttribute('name'); + my $value = $arg->getAttribute('value'); + if (defined($value) && $value ne '') { + push(@opts, "$prefix$name$sep$value"); + } else { + push(@opts, "$prefix$name"); + } + } + } + + return @opts; +} + +sub configPath { + my $context = shift; + my $elemname = shift; + my $sep = shift || ":"; + my @path = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $dir = $arg->getAttribute('path'); + if ($dir ne '') { + foreach my $f (split(/$sep/, $dir)) { + if (-d $f || -f $f) { + push (@path, $f); + } else { + warn "Invalid path component: $f\n"; + } + } + } else { + warn "Invalid path component (no \@dir)\n"; + } + } + } + + return @path; +} + +sub addOpt { + my $arrayref = shift; + my $newopt = shift; + my $sep = shift; + my $newname = $newopt; + + $newname = $1 if defined($sep) && $newopt =~ /^(.*?)$sep/; + + foreach my $opt (@{$arrayref}) { + my $name = $opt; + $name = $1 if defined($sep) && $opt =~ /^(.*?)$sep/; + return if $name eq $newname; + } + + push(@{$arrayref}, $newopt); +} + +sub showVars { + print STDERR "config: $config\n"; + print STDERR "java: $java\n"; + print STDERR "optsname: $optsname\n"; + showArr("opts", @opts); + showArr("saxon opts", @saxonopts); + print STDERR "input: $input\n" if defined($input); + print STDERR "style: $style\n" if defined($style); + showArr("params", @params); + showArr("java opts", @javaopts); + showArr("system props", @systemprops); + print STDERR "cpseparator: $cpseparator\n"; + showArr("classpath", @classpath); +} + +sub showArr { + my $name = shift; + my @arr = @_; -DONE=0 -VERSION=653 -EXTVERSION=643 -DEBUG=0 -XARG="" -YARG="" -RARG="" -MEMORY="" -VALIDATE="" -# which parser to use -PARSER=auto - -MYDIR=`dirname $0` -. $MYDIR/common-functions.sh - -# identify the directory for DocBook XSL -for dir in "/sourceforge/docbook/xsl" \ - "$MYDIR/xsl" \ - "/usr/share/sgml/docbook/stylesheet/xsl/nwalsh" ; do - if [ -d "$dir" ]; then - DOCBOOKXSL="$dir" - break - fi -done - -while [ "$DONE" = "0" ]; do - case $1 in - -d) DEBUG=1; - shift; - ;; - -6*) VERSION=$1; - shift; - ;; - -7*) VERSION=$1; - shift; - ;; - -8*) VERSION=$1; - EXTVERSION=8 - shift; - ;; - -x) shift; - XARG="-x $1"; - shift; - ;; - -y) shift; - YARG="-y $1"; - shift; - ;; - -r) shift; - RARG="-r $1"; - shift; - ;; - -m) shift - MEMORY="-Xmx$1"; - shift; - ;; - -parser) shift - PARSER="$1" - shift - ;; - -q) shift - VERBOSE=false - ;; - -val) shift - VALIDATE=-val - ;; - -v) shift - VERBOSE=true - ;; - -X) shift - DOCBOOKXSL="$1"; - shift; - ;; - -*) DONE=1; - echo "unexpected argument: $*" 1>&2 - exit 1 - ;; - *) DONE=1 - esac -done - -XMLSRC=$1; shift -XMLSTY=$1; shift -OUTPUT=$1; shift - -if [ "$OUTPUT" = "-" ]; then - OUTPUT=""; -fi - -if [ "$OUTPUT" != "" ]; then - OUTPUT="-o $OUTPUT" -fi - -if [ ! -d "$DOCBOOKXSL" ]; then - echo "DocBook XSL dir '$DOCBOOKXSL' doesn't exist" 1>&2 - echo " Try using the '-X ' argument" 1>&2 - exit 1 -fi - -# Toss the leading hyphen -VERSION=`echo $VERSION | sed -e 's/^-//'` - -case $VERSION in - 8a) - VERSION="sa-8.0"; - ;; - 8b) - VERSION="b8.0"; - ;; - 77|751|653|652|651|65|644|643) - : # handled normally below - ;; - *) echo "unexpected Saxon version $VERSION" 1>&2 - exit 1 - ;; -esac - -case $PARSER in - auto|xerces2|xerces1|crimson|native) - : # handled normally below - ;; - *) echo "unexpected parser selected, '$PARSER'" 1>&2 - echo "must be one of 'auto', 'xerces2', 'xerces1', 'crimson', or 'native'" 1>&2 - exit 1 - ;; -esac - - -DOTTEDVERSION=`echo $VERSION | sed -e 's/\([0-9]\)\([0-9]\)/\1.\2/g; s/\([0-9]\)\([0-9]\)/\1.\2/g;'` - -## -## locate saxon.jar -## -SAXON= -for jar in "/usr/local/java/saxon-$DOTTEDVERSION/saxon.jar" \ - "/usr/local/java/saxon-$DOTTEDVERSION/saxon7.jar" \ - "/usr/local/java/saxon-$DOTTEDVERSION/saxon8sa.jar" \ - "/usr/local/java/saxon$DOTTEDVERSION/saxon8sa.jar" \ - "/usr/local/share/java/saxon-$DOTTEDVERSION/saxon.jar" \ - "/usr/local/share/java/saxon-$DOTTEDVERSION/saxon7.jar" \ - "/usr/local/share/java/saxon$DOTTEDVERSION/saxon8sa.jar" \ - "/usr/share/java/saxon-$DOTTEDVERSION.jar" \ - "/usr/local/java/saxon/saxon.jar" \ - "/usr/local/share/java/saxon/saxon.jar" \ - "/usr/share/java/saxon.jar"; do - if [ -f "$jar" -a "$SAXON" = "" ]; then - SAXON="$jar" - break - fi -done -if [ ! -f "$SAXON" ]; then - echo "warning: cannot locate Saxon JAR file" 1>&2 -fi - -## -## DocBook extensions -## -if [ ! "$NDWEXT" ]; then - for ext in "$DOCBOOKXSL/extensions/saxon$EXTVERSION/.classes" \ - "$DOCBOOKXSL/extensions/saxon$EXTVERSION.jar" \ - "/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/extensions/saxon$EXTVERSION.jar" ; do - if [ -d $ext -o -f $ext ]; then - NDWEXT=$ext; - break - fi - done - if [ ! "$NDWEXT" ]; then - echo "warning: cannot locate DocBook XSL Saxon extensions" 1>&2 - fi -fi - -## -## Saxon debugging stuff -## -if [ "$DEBUG" = "1" ]; then - for try in "/usr/local/java/saxon-$DOTTEDVERSION/.classes" \ - "/usr/local/share/java/saxon-$DOTTEDVERSION/.classes" \ - "/usr/share/java/saxon-$DOTTEDVERSION/.classes"; do - if [ -d "$try" ]; then - SAXON="$try:$SAXON" - fi - done -fi - -## -## set the desired parser -## -## From SAXON documentation: -## -## SAXON comes with a bundled XML parser, a modified copy of the -## AElred parser, adapted to notify comments to the application. SAXON -## has been tested successfully in the past with Xerces, Lark, SUN -## Project X, Crimson, Oracle XML, xerces, xml4j, and xp. Use of a -## SAX2-compliant parser is preferred, as SAX1 does not allow XML -## comments to be passed to the application. However, SAXON works with -## either. All the relevant classes must be installed on your Java -## CLASSPATH. -## -## These are the settings which control the parser: -## javax.xml.parsers.DocumentBuilderFactory -## javax.xml.parsers.SAXParserFactory -## - -# first choice is xerces2 -if [ "$PARSER" = "xerces2" -o "$PARSER" = "auto" ]; then - PARSERCLASS=`findxerces2` - if [ "$PARSERCLASS" ]; then - DBFACTORY="-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" - SPFACTORY="-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl" - fi -fi - -# next choice is xerces1 -if [ "$PARSER" = "xerces1" ] || [ ! "$PARSERCLASS" -a "$PARSER" = "auto" ]; then - PARSERCLASS=`findxerces1` - if [ "$PARSERCLASS" ]; then - DBFACTORY="-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" - SPFACTORY="-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl" - fi -fi - -# next choice is crimson -if [ "$PARSER" = "crimson" ] || [ ! "$PARSERCLASS" -a "$PARSER" = "auto" ]; then - PARSERCLASS=`findcrimson` - if [ "$PARSERCLASS" ]; then - DBFACTORY="-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl" - SPFACTORY="-Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl" - fi -fi - -if [ "$PARSER" != "native" -a ! "$PARSERCLASS" ]; then - echo "warning: cannot locate an alternate SAX parser, PEs may not work correctly" 1>&2 -fi - -## -## selecting the transformer not handled. xalan2 can provide this, -## javax.xml.transform.TransformerFactory -## = org.apache.xalan.processor.TransformerFactoryImpl -TRANSFACTORY=com.icl.saxon.TransformerFactoryImpl - -## -## optionally replace the URI resolver with the Apache -## resolver classes -## FIXME: do we specifically *not* want to use the sun resolver? -## -RESOLVER=`findresolver` -if [ -f "$RESOLVER" -o -d "$RESOLVER" ]; then - # use the apache resolver - XARG=${XARG:--x org.apache.xml.resolver.tools.ResolvingXMLReader} - YARG=${YARG:--y org.apache.xml.resolver.tools.ResolvingXMLReader} - RARG=${RARG:--r org.apache.xml.resolver.tools.CatalogResolver} -fi - -CLASSPATH=`fixclasspath "$SAXON:$NDWEXT:$RESOLVER:$PARSERCLASS:$CLASSPATH"` - -TFLAG= -if [ "$DEBUG" != "0" ]; then - TFLAG="-T" -fi - -HTTP_PROXY= -HTTPS_PROXY= - -if [ "$http_proxy_host" != "" ]; then - HTTP_PROXY="-Dhttp.proxyHost=$http_proxy_host -Dhttp.proxyPort=$http_proxy_port" - HTTPS_PROXY="-Dhttps.proxyHost=$http_proxy_host -Dhttps.proxyPort=$http_proxy_port" -fi - -if [ ${VERBOSE} ] && ${VERBOSE}; then - echo java $MEMORY -cp $CLASSPATH $DBFACTORY $SPFACTORY \ - -Djavax.xml.transform.TransformerFactory=$TRANSFACTORY \ - com.icl.saxon.StyleSheet $TFLAG $VALIDATE \ - $XARG $YARG $RARG $OUTPUT $XMLSRC $XMLSTY "$@" -fi - -#echo VERSION=$VERSION - -if [ "$VERSION" = "sa-8.0" ]; then - JAVA_HOME=/usr/local/jdk1.4.2 - JAVA=$JAVA_HOME/bin/java -# exec $JAVA $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH $DBFACTORY $SPFACTORY \ -# -Djavax.xml.transform.TransformerFactory=$TRANSFACTORY \ -# com.saxonica.Transform $TFLAG $VALIDATE $SAXONOPT \ -# $XARG $YARG $RARG $OUTPUT $XMLSRC $XMLSTY "$@" - CLASSPATH=/usr/local/java/saxonsa-8.0/saxon8sa.jar:/home/ndw/java - exec $JAVA $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH \ - com.saxonica.Transform $TFLAG $VALIDATE $SAXONOPT \ - $OUTPUT $XMLSRC $XMLSTY "$@" -else if [ "$VERSION" = "b8.0" ]; then - JAVA_HOME=/usr/local/jdk1.4.2 - JAVA=$JAVA_HOME/bin/java - CLASSPATH=/usr/local/java/saxonb-8.0/saxon8.jar:/home/ndw/java - echo $JAVA $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH \ - net.sf.saxon.Transform $TFLAG $VALIDATE $SAXONOPT \ - $OUTPUT $XMLSRC $XMLSTY "$@" - exec $JAVA $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH \ - net.sf.saxon.Transform $TFLAG $VALIDATE $SAXONOPT \ - $OUTPUT $XMLSRC $XMLSTY "$@" -else if [ "$VERSION" = "77" ]; then - JAVA_HOME=/usr/local/jdk1.4.2 - JAVA=$JAVA_HOME/bin/java - exec $JAVA $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH $DBFACTORY $SPFACTORY \ - -Djavax.xml.transform.TransformerFactory=$TRANSFACTORY \ - net.sf.saxon.Transform $TFLAG \ - $XARG $YARG $RARG $OUTPUT $XMLSRC $XMLSTY "$@" -else - exec java $HTTP_PROXY $HTTPS_PROXY $MEMORY -cp $CLASSPATH $DBFACTORY $SPFACTORY \ - -Djavax.xml.transform.TransformerFactory=$TRANSFACTORY \ - com.icl.saxon.StyleSheet $TFLAG \ - $XARG $YARG $RARG $OUTPUT $XMLSRC $XMLSTY "$@" -fi -fi -fi \ No newline at end of file + if (@arr) { + print STDERR "$name:\n"; + foreach my $p (@arr) { + print STDERR "\t$p\n"; + } + } +} diff --git a/cvstools/xalan b/cvstools/xalan index 9e8d23049..04bebd6dd 100755 --- a/cvstools/xalan +++ b/cvstools/xalan @@ -1,203 +1,304 @@ -#!/bin/bash - -DONE=0 -DEBUG=false # not used -VERSION=2 -MEMORY="" -USECRIMSON=false -USERESOLVER=true -RESOLVERS="" - -MYDIR=`dirname $0` -. $MYDIR/common-functions.sh - -while [ "$DONE" = "0" ]; do - case $1 in - -m) shift - MEMORY="-Xmx$1" - shift - ;; - -crimson) - shift - USECRIMSON=true - ;; - -noresolver) - shift - USERESOLVER=false - ;; - -d) shift - DEBUG=true - ;; - -q) shift - VERBOSE=false - ;; - -v) shift - VERBOSE=true - ;; - -1) shift - VERSION=1 - ;; - -2*) VERSION=${1#-} - shift - ;; - -X) shift - DOCBOOKXSL="$1" - shift - ;; - -*) DONE=1 - ;; - *) DONE=1 - ;; - esac -done - - -## -## optionally replace the SAXParser with crimson -## -if $USECRIMSON; then - CRIMSON=`findcrimson` - if [ ! "$CRIMSON" ]; then - echo "crimson requested but cannot be found" 1>&2 - exit 1 - else - SAXPARSER="-Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl" - fi -fi - -# FIXME: do this right -NDWEXT="/sourceforge/docbook/xsl/extensions/xalan2/.classes"; - -if [ "$VERSION" = "1" ]; then - if [ ! "$XALAN" ]; then - ## - ## find xalan 1 - ## - for path in "${XALANROOT}" \ - "${XALANROOT}/xalan.jar" \ - "/usr/local/java/xalan-1.2.2" \ - "/usr/local/share/java/xalan-1.2.2" \ - "/usr/share/java/xalan.jar"; do - if [ -f "$path" -o -d "$path" ]; then - XALAN="$path" - break - fi - done - # find bsf - for path in "${XALANROOT}/bsf.jar" \ - "/usr/local/java/bsf.jar" \ - "/usr/local/share/java/bsf.jar" \ - "/usr/share/java/bsf.jar"; do - if [ -f "$path" ]; then - XALAN="$XALAN:$path" - break - fi - done - fi - - # resolver isn't supported - RESOLVERS= - - ## - ## use the appropriate xerces - ## - XERCES=`findxerces1` - if [ ! "$XERCES" ]; then - echo "cannot locate Xerces (xerces.jar)" 1>&2 - exit 1 - # see http://xml.apache.org/xalan-j/usagepatterns.html#plug - # no need to set these - # -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl - # -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl" - fi - -else - ## - ## xalan 2 - ## - - if [ ! "$XALAN" ]; then - STRIKEVERSION=`echo $VERSION | sed -e 's/\([0-9]\)\([0-9]\)/\1_\2/g; s/\([0-9]\)\([0-9D]\)/\1_\2/g;'` - DOTVERSION=`echo $VERSION | sed -e 's/\([0-9]\)\([0-9]\)/\1.\2/g; s/\([0-9]\)\([0-9D]\)/\1.\2/g;'` - ## - ## first find xalan2.jar or directory for compiled classes - ## - for path in "${XALANROOT}/build/classes" \ - "${XALANROOT}" \ - "${XALANROOT}/xalan2.jar" \ - "${XALANROOT}/bin/xalan2.jar" \ - "/projects/apache/xml-xalan/java/build/classes" \ - "/usr/local/java/xalan-j_${STRIKEVERSION}/bin/xalan.jar" \ - "/usr/local/share/java/xalan-j_${STRIKEVERSION}/bin/xalan.jar" \ - "/usr/local/share/java/xalan-$STRIKEVERSION.jar" \ - "/usr/local/share/java/xalan-$DOTVERSION.jar" \ - "/usr/local/share/java/xalan2.jar" \ - "/usr/local/java/xalan-$STRIKEVERSION.jar" \ - "/usr/local/java/xalan-$DOTVERSION.jar" \ - "/usr/local/java/xalan2.jar" \ - "/usr/share/java/xalan-$STRIKEVERSION.jar" \ - "/usr/share/java/xalan-$DOTVERSION.jar" \ - "/usr/share/java/xalan2.jar"; do - if [ -f "$path" -o -d "$path" ]; then - if [ ${VERBOSE} ] && ${VERBOSE}; then - echo "found xalan2 in $path" 1>&2 - fi - XALAN="$path" - break - fi - done - if [ ! "$XALAN" ]; then - echo "xalan $VERSION cannot be found" 1>&2 - exit 1 - fi - - ## - ## we also need xml-apis.jar - ## - XALANDIR=`dirname $XALAN` - for path in "${XALANDIR}/xml-apis.jar" \ - "${XALANROOT}/xml-apis.jar" \ - "${XALANROOT}/bin/xml-apis.jar"; do - if [ -f "$path" -o -d "$path" ]; then - XALAN="${XALAN}:$path" - break - fi - done - fi - - ## - ## use the appropriate xerces - ## - XERCES=`findxerces2` - if [ ! "$XERCES" ]; then - echo "cannot locate Xerces 2" 1>&2 - exit 1 - fi - - ## - ## resolver - ## - if $USERESOLVER; then - RESOLVER=`findresolver` - if [ ${RESOLVER/sun/} != ${RESOLVER} ]; then - # guess this is the sun resolver - RESOLVERS="-URIRESOLVER com.sun.resolver.tools.CatalogResolver -ENTITYRESOLVER com.sun.resolver.tools.CatalogResolver" - else - # guess this is the Apache resolver - RESOLVERS="-URIRESOLVER org.apache.xml.resolver.tools.CatalogResolver -ENTITYRESOLVER org.apache.xml.resolver.tools.CatalogResolver" - fi - fi -fi - -RESOLVERS="" -echo java $MEMORY $SAXPARSER org.apache.xalan.xslt.Process $RESOLVERS $@ - -CLASSPATH=`fixclasspath "$NDWEXT:$XALAN:$JAXP:$RESOLVER:$XERCES:$CLASSPATH"` - -#echo $CLASSPATH - -if [ ${VERBOSE} ] && ${VERBOSE}; then - echo java $MEMORY $SAXPARSER org.apache.xalan.xslt.Process $RESOLVERS $@ -fi -exec java -cp $CLASSPATH $MEMORY $SAXPARSER org.apache.xalan.xslt.Process $RESOLVERS $@ +#!/usr/bin/perl -w -- # -*- Perl -*- +# +# This script runs the Xalan XSLT processor. It relies on a configuration +# file to identify java versions, class paths, etc. +# +# Usage: xalan [opts] input style [output] [params] +# +# Options: +# +# -2... Specifies a particular version +# -debug Debugging +# -config Where is the config file? Defaults to ~/.xmlc +# -opts id Use additional options 'id' from the config file. +# The -opts option may be specified more than once +# +# The default config is "xalan" or "xalan-{version}" if a version +# is specified. If -xsltc is passed as a Xalan option, then the +# default config is "xsltc" or "xsltc-{version}" +# +# Any other options are passed to Xalan unchanged +use strict; +use English; +use XML::XPath; +use XML::XPath::XMLParser; + +my $usage = "xalan [opts] input style [output] [params]\n"; + +my $version = ""; +my $debug = 0; +my $config = "~/.xmlc"; +my @opts = (); + +while (@ARGV) { + if ($ARGV[0] =~ /^-\d/) { + $version = substr($ARGV[0],1); + shift @ARGV; + } elsif ($ARGV[0] eq '-debug') { + $debug = 1; + shift @ARGV; + } elsif ($ARGV[0] eq '-config') { + shift @ARGV; + $config = shift @ARGV; + } elsif ($ARGV[0] eq '-opts') { + shift @ARGV; + push(@opts, shift @ARGV); + } else { + last; + } +} + +my @params = (); +while (@ARGV && $ARGV[$#ARGV] =~ /=/) { + unshift (@params, pop @ARGV); +} + +my $output = pop @ARGV; +my $style = pop @ARGV; +my $input = pop @ARGV; + +# What if the user didn't specify an output location? +if (!defined($input) || $input =~ /^-/) { + push (@ARGV, $input) if defined($input); + $input = $style; + $style = $output; + $output = undef; +} + +# Everything else goes to Xalan +my @xalanopts = @ARGV; +push (@xalanopts, "-OUT $output") if defined($output) && $output ne '-'; + +die $usage if !defined($input) || !defined($style); + +my $optsname = "xalan"; +foreach my $opt (@xalanopts) { + $optsname = "xsltc" if $opt =~ /-xsltc/i; +} +$optsname .= "-$version" if $version ne ''; + +# Inelegantly, these are used as globals by several functions +my %seenopts = (); +my $classname = ""; +my $java = ""; +my @systemprops = (); +my @javaopts = (); +my @classpath = (); + +$config = (glob($config))[0]; # hack to expand ~/.xmlc to right place + +die "Cannot read config: $config\n$usage" if ! -f $config; +my $xp = XML::XPath->new('filename' => $config); +my $doc = ($xp->find("/config")->get_nodelist())[0]; +die "Unexpected root element in configuration file.\n" if !$doc; + +# Figure out the class path separator before we go any further +my $cpseparator = $doc->getAttribute('classpath-separator'); +# Default to ';' if it appears in $CLASSPATH, otherwise ':' +$cpseparator = ($ENV{'CLASSPATH'} =~ /;/ ? ";" : ":") + if !defined($cpseparator) or $cpseparator eq ''; + +foreach my $name (@opts, $optsname) { + applyOpts($xp, $name); +} + +$java = "java" if $java eq ''; + +foreach my $path (reverse split(/$cpseparator/, $ENV{'CLASSPATH'})) { + unshift(@classpath, $path); +} + +showVars() if $debug; + +die "No classname?\n" if !defined($classname); + +my $jopts = join(" ", @javaopts); +my $jprops = join(" ", @systemprops); +my $jcp = join($cpseparator, @classpath); +my $xopts = join(" ", @xalanopts); + +my $xparam = ""; +foreach my $param (@params) { + my $name = ""; + my $value = ""; + if ($param =~ /^(.*?)=(.*)$/) { + $name = $1; + $value = $2; + } else { + $name = $param; + } + + $xparam .= "-PARAM $name \"$value\" "; +} + +if ($cpseparator eq ';') { + # This must be cygwin or some windows flavor, let's try to make it work + $jcp =~ s/\//\\\\/sg; # turn / into \\ in classpath paths + $jcp =~ s/\;/\\\;/sg; # escape semicolons + if (@params) { + $xparam = "\"" . join("\" \"", @params) . "\""; + } else { + $xparam = ""; + } +} + +print "$java $jopts $classname $xopts -IN $input -XSL $style $xparam\n" if $debug; +exec("$java $jopts -cp $jcp $jprops $classname $xopts -IN $input -XSL $style $xparam"); + +# ============================================================ + +sub applyOpts { + my $xp = shift; + my $id = shift; + + # Avoid loops + if ($seenopts{$id}) { + print STDERR "Skipping $id (already seen)\n" if $debug; + return; + } + $seenopts{$id} = 1; + + my $node = ($xp->find("/config/*[\@xml:id='$id']")->get_nodelist())[0]; + + die "Config $config does not contain $id.\n" if !defined($node); + + print STDERR "Loading $id from $config\n" if $debug; + + $classname = $node->getAttribute('class') + if $classname eq ''; + + $java = $node->getAttribute('java') + if $java eq ''; + + foreach my $path (configPath($node, 'classpath', $cpseparator)) { + addOpt(\@classpath, $path); + } + + foreach my $prop (configArgs($node, 'system-property', '-D', '=')) { + addOpt(\@systemprops, $prop, '='); + } + + foreach my $arg (configArgs($node, 'arg', '-', ' ')) { + addOpt(\@xalanopts, $arg, ' '); + } + + foreach my $opt (configArgs($node, 'java-option', '-', '=')) { + addOpt(\@javaopts, $opt, ' '); + } + + foreach my $param (configArgs($node, 'param', '', '=')) { + addOpt(\@params, $param, '='); + } + + my $extends = $node->getAttribute('extends'); + applyOpts($xp, $extends) if $extends ne ''; +} + +sub configArgs { + my $context = shift; + my $elemname = shift; + my $prefix = shift; + my $sep = shift; + my @opts = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $name = $arg->getAttribute('name'); + my $value = $arg->getAttribute('value'); + if (defined($value) && $value ne '') { + push(@opts, "$prefix$name$sep$value"); + } else { + push(@opts, "$prefix$name"); + } + } + } + + return @opts; +} + +sub configPath { + my $context = shift; + my $elemname = shift; + my $sep = shift || ":"; + my @path = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $dir = $arg->getAttribute('path'); + if ($dir ne '') { + foreach my $f (split(/$sep/, $dir)) { + if (-d $f || -f $f) { + push (@path, $f); + } else { + warn "Invalid path component: $f\n"; + } + } + } else { + warn "Invalid path component (no \@dir)\n"; + } + } + } + + return @path; +} + +sub addOpt { + my $arrayref = shift; + my $newopt = shift; + my $sep = shift; + my $newname = $newopt; + + $newname = $1 if defined($sep) && $newopt =~ /^(.*?)$sep/; + + foreach my $opt (@{$arrayref}) { + my $name = $opt; + $name = $1 if defined($sep) && $opt =~ /^(.*?)$sep/; + return if $name eq $newname; + } + + push(@{$arrayref}, $newopt); +} + +sub showVars { + print STDERR "config: $config\n"; + print STDERR "java: $java\n"; + print STDERR "optsname: $optsname\n"; + showArr("opts", @opts); + showArr("xalan opts", @xalanopts); + print STDERR "input: $input\n" if defined($input); + print STDERR "style: $style\n" if defined($style); + if (@params) { + print STDERR "params:\n"; + foreach my $param (@params) { + my $name = ""; + my $value = ""; + if ($param =~ /^(.*?)=(.*)$/) { + $name = $1; + $value = $2; + } else { + $name = $param; + } + + print STDERR "\t-PARAM $name \"$value\"\n"; + } + } + showArr("java opts", @javaopts); + showArr("system props", @systemprops); + print STDERR "cpseparator: $cpseparator\n"; + showArr("classpath", @classpath); +} + +sub showArr { + my $name = shift; + my @arr = @_; + + if (@arr) { + print STDERR "$name:\n"; + foreach my $p (@arr) { + print STDERR "\t$p\n"; + } + } +} diff --git a/cvstools/xslt b/cvstools/xslt index 9aea61fba..699a697c2 100755 --- a/cvstools/xslt +++ b/cvstools/xslt @@ -1,149 +1,20 @@ -#!/usr/bin/perl -- # --*-Perl-*-- +#!/bin/bash -use strict; -use Getopt::Long; +PROC=saxon -my $defaultProc = $ENV{'XSLTPROC'} || 'saxon'; -my $defaultOpts = $ENV{'XSLTPROCOPTS'} || undef; +case $1 in + -xsltproc) PROC=xsltproc; + shift; + ;; + -xalan) PROC=xalan + shift; + ;; + -saxon) PROC=saxon + shift; + ;; +esac -my $usage = "Usage: $0 [options] files\n"; +exec `dirname $0`/$PROC "$@" -my %option = ('debug' => 0, - 'quiet' => 0, - 'verbose' => 0, - 'time' => 0, - 'extensions' => 1, - 'version' => undef, - 'memory' => undef, - 'xml' => undef, - 'xsl' => undef, - 'output' => undef, - 'opts' => $defaultOpts, - 'processor' => $defaultProc); -my %opt = (); -&GetOptions(\%opt, - 'debug+', - 'quiet+', - 'verbose', - 'time', - 'extensions!', - 'version=s', - 'memory=s', - 'xml=s', - 'xsl=s', - 'output=s', - 'opts=s', - 'processor=s') || die $usage; -foreach my $key (keys %option) { - $option{$key} = $opt{$key} if exists($opt{$key}); -} - -my @args = (); -my %param = (); - -$param{'use.extensions'} = 1 if $option{'extensions'}; -$param{'use.extensions'} = 0 if $option{'processor'} eq 'xsltproc'; - -while ($_ = shift @ARGV) { - if (/^([^\s=]+)=(.*)$/) { - $param{$1} = $2; - } else { - push (@args, $_); - } -} - -my $processor = $option{'processor'}; -my $procopt = $option{'opts'}; -my $xmlFile = $option{'xml'} || shift @args; -my $xslFile = $option{'xsl'} || shift @args; -my $outFile = $option{'output'} || shift @args; -my $time = $option{'time'}; -my $version = $option{'version'}; -my $quiet = $option{'quiet'}; -my $verbose = $option{'verbose'}; -my $memory = $option{'memory'}; -my $debug = $option{'debug'}; - -my $cmd = ""; -my $exedir; -($exedir = $0) =~ s/\/[^\/]+$//; - -if ($processor eq 'saxon') { - $cmd = "$exedir/saxon"; - $cmd .= " $procopt" if $procopt; - $cmd .= " -q" if $quiet; - $cmd .= " -v" if $verbose; - $cmd .= " -d" if $debug; - $cmd .= " -$version" if $version; - $cmd .= " -m $memory" if $memory; - $cmd .= " $xmlFile $xslFile"; - $outFile = "-" if $outFile eq ''; - $cmd .= " $outFile" if $outFile; - foreach my $key (keys %param) { - $cmd .= " $key=\"" . $param{$key} . "\""; - } -} elsif ($processor eq 'xalan') { - $cmd = "$exedir/xalan"; - $cmd .= " $procopt" if $procopt; - $cmd .= " -q" if $quiet; - $cmd .= " -v" if $verbose; - $cmd .= " -d" if $debug; - $cmd .= " -$version" if $version; - $cmd .= " -m $memory" if $memory; - $cmd .= " -IN $xmlFile -XSL $xslFile"; - $cmd .= " -OUT $outFile" if $outFile; - foreach my $key (keys %param) { - $cmd .= " -PARAM $key \"" . $param{$key} . "\""; - } -} elsif ($processor eq 'xsltproc') { - $cmd = "$exedir/xsltproc"; - $cmd .= " $procopt" if $procopt; - $cmd .= " -q" if $quiet; - $cmd .= " -v" if $verbose; - foreach my $key (keys %param) { - $cmd .= " -param $key \"'" . $param{$key} . "'\""; - } - $cmd .= " --output $outFile" if $outFile; - $cmd .= " $xslFile $xmlFile"; -} elsif ($processor eq '4xslt') { - $cmd = "$exedir/4xslt"; - $cmd .= " $procopt" if $procopt; - $cmd .= " -q" if $quiet; - $cmd .= " -v" if $verbose; - foreach my $key (keys %param) { - $cmd .= " --define=$key=\"" . $param{$key} . "\""; - } - $cmd .= " --outfile $outFile" if $outFile; - $cmd .= " $xmlFile $xslFile"; -} elsif ($processor eq 'xt') { - $cmd = "$exedir/xt"; - $cmd .= " $procopt" if $procopt; - $cmd .= " -q" if $quiet; - $cmd .= " -v" if $verbose; - $cmd .= " $xmlFile $xslFile"; - $outFile = "-" if $outFile eq ''; - $cmd .= " $outFile" if $outFile; - foreach my $key (keys %param) { - $cmd .= " $key=\"" . $param{$key} . "\""; - } -} else { - print STDERR "Unknown processor: $processor\n"; - exit 1; -} - -my $startTime = time(); -if (! $quiet) { - print "$cmd\n"; -} -my $retVal = system($cmd); -my $endTime = time(); - -print "Time: ", $endTime - $startTime, "s\n" if $time; - -if ($retVal) { - exit $retVal / 256; -} else { - exit 0; -} diff --git a/cvstools/xsltproc b/cvstools/xsltproc index a43efbf6e..a9c30da1d 100755 --- a/cvstools/xsltproc +++ b/cvstools/xsltproc @@ -1,38 +1,250 @@ -#!/bin/bash - -DONE=0 -DEBUG=0 -QUIET=0 -OPTS="" - -while [ "$DONE" = "0" ]; do - case $1 in - -d) DEBUG=1; - shift; - ;; - -q) shift - QUIET=1 - ;; - -*) DONE=1; - ;; - *) DONE=1 - ;; - esac -done - -if [ "$DEBUG" = "1" ]; then - OPTS="--verbose" -fi - -if [ "$QUIET" = "0" ]; then - echo xsltproc $OPTS "$@" -fi - -/usr/bin/xsltproc --catalogs $OPTS "$@" - -if [ $? != 0 ]; then - echo "" - echo FAILED - echo "" -fi +#!/usr/bin/perl -w -- # -*- Perl -*- +# +# This script runs the xsltproc XSLT processor. It relies on a configuration +# file to identify the specific executable, parameters, etc. +# +# Usage: xsltproc [opts] input style [output] [params] +# +# Options: +# +# -2... Specifies a particular version +# -debug Debugging +# -config Where is the config file? Defaults to ~/.xmlc +# -opts id Use additional options 'id' from the config file. +# The -opts option may be specified more than once +# +# The default config is "xsltproc" or "xsltproc-{version}" if a version +# is specified. +# +# Any other options are passed to xsltproc unchanged +use strict; +use English; +use XML::XPath; +use XML::XPath::XMLParser; + +my $usage = "xsltproc [opts] input style [output] [params]\n"; + +my $version = ""; +my $debug = 0; +my $config = "~/.xmlc"; +my @opts = (); + +while (@ARGV) { + if ($ARGV[0] =~ /^-\d/) { + $version = substr($ARGV[0],1); + shift @ARGV; + } elsif ($ARGV[0] eq '-debug') { + $debug = 1; + shift @ARGV; + } elsif ($ARGV[0] eq '-config') { + shift @ARGV; + $config = shift @ARGV; + } elsif ($ARGV[0] eq '-opts') { + shift @ARGV; + push(@opts, shift @ARGV); + } else { + last; + } +} + +my @params = (); +while (@ARGV && $ARGV[$#ARGV] =~ /=/) { + unshift (@params, pop @ARGV); +} + +my $output = pop @ARGV; +my $style = pop @ARGV; +my $input = pop @ARGV; + +# What if the user didn't specify an output location? +if (!defined($input) || $input =~ /^-/) { + push (@ARGV, $input) if defined($input); + $input = $style; + $style = $output; + $output = undef; +} + +# Everything else goes to xsltproc +my @xsltprocopts = @ARGV; +push (@xsltprocopts, "-o $output") if defined($output) && $output ne '-'; + +die $usage if !defined($input) || !defined($style); + +my $optsname = "xsltproc"; +$optsname .= "-$version" if $version ne ''; + +# Inelegantly, these are used as globals by several functions +my %seenopts = (); +my $execname = ''; + +$config = (glob($config))[0]; # hack to expand ~/.xmlc to right place + +die "Cannot read config: $config\n$usage" if ! -f $config; +my $xp = XML::XPath->new('filename' => $config); +my $doc = ($xp->find("/config")->get_nodelist())[0]; +die "Unexpected root element in configuration file.\n" if !$doc; + +foreach my $name (@opts, $optsname) { + applyOpts($xp, $name); +} + +showVars() if $debug; + +die "No execname?\n" if !defined($execname); + +my $xopts = join(" ", @xsltprocopts); + +my $xparam = ""; +foreach my $param (@params) { + my $name = ""; + my $value = ""; + if ($param =~ /^(.*?)=(.*)$/) { + $name = $1; + $value = $2; + } else { + $name = $param; + } + + $xparam .= "-stringparam $name \"$value\" "; +} + +print "$execname $xopts $style $input\n" if $debug; +exec("$execname $xopts $style $input"); + +# ============================================================ + +sub applyOpts { + my $xp = shift; + my $id = shift; + + # Avoid loops + if ($seenopts{$id}) { + print STDERR "Skipping $id (already seen)\n" if $debug; + return; + } + $seenopts{$id} = 1; + + my $node = ($xp->find("/config/*[\@xml:id='$id']")->get_nodelist())[0]; + + die "Config $config does not contain $id.\n" if !defined($node); + + print STDERR "Loading $id from $config\n" if $debug; + + $execname = $node->getAttribute('exec') + if $execname eq ''; + + foreach my $arg (configArgs($node, 'arg', '-', ' ')) { + addOpt(\@xsltprocopts, $arg, ' '); + } + + foreach my $param (configArgs($node, 'param', '', '=')) { + addOpt(\@params, $param, '='); + } + + my $extends = $node->getAttribute('extends'); + applyOpts($xp, $extends) if $extends ne ''; +} + +sub configArgs { + my $context = shift; + my $elemname = shift; + my $prefix = shift; + my $sep = shift; + my @opts = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $name = $arg->getAttribute('name'); + my $value = $arg->getAttribute('value'); + if (defined($value) && $value ne '') { + push(@opts, "$prefix$name$sep$value"); + } else { + push(@opts, "$prefix$name"); + } + } + } + + return @opts; +} + +sub configPath { + my $context = shift; + my $elemname = shift; + my $sep = shift || ":"; + my @path = (); + + if ($context) { + my $args = $context->find($elemname); + foreach my $arg ($args->get_nodelist()) { + my $dir = $arg->getAttribute('path'); + if ($dir ne '') { + foreach my $f (split(/$sep/, $dir)) { + if (-d $f || -f $f) { + push (@path, $f); + } else { + warn "Invalid path component: $f\n"; + } + } + } else { + warn "Invalid path component (no \@dir)\n"; + } + } + } + + return @path; +} + +sub addOpt { + my $arrayref = shift; + my $newopt = shift; + my $sep = shift; + my $newname = $newopt; + + $newname = $1 if defined($sep) && $newopt =~ /^(.*?)$sep/; + + foreach my $opt (@{$arrayref}) { + my $name = $opt; + $name = $1 if defined($sep) && $opt =~ /^(.*?)$sep/; + return if $name eq $newname; + } + + push(@{$arrayref}, $newopt); +} + +sub showVars { + print STDERR "config: $config\n"; + print STDERR "optsname: $optsname\n"; + showArr("opts", @opts); + showArr("xsltproc opts", @xsltprocopts); + print STDERR "input: $input\n" if defined($input); + print STDERR "style: $style\n" if defined($style); + if (@params) { + print STDERR "params:\n"; + foreach my $param (@params) { + my $name = ""; + my $value = ""; + if ($param =~ /^(.*?)=(.*)$/) { + $name = $1; + $value = $2; + } else { + $name = $param; + } + + print STDERR "\t-stringparam $name \"$value\"\n"; + } + } +} + +sub showArr { + my $name = shift; + my @arr = @_; + + if (@arr) { + print STDERR "$name:\n"; + foreach my $p (@arr) { + print STDERR "\t$p\n"; + } + } +} -- 2.40.0