-#!/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 <dir>' 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";
+ }
+ }
+}
-#!/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";
+ }
+ }
+}
-#!/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;
-}
-#!/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";
+ }
+ }
+}