blob: d8476461c30b74fdd904fde3178a6a801ab40762 [file] [log] [blame]
# Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# This module defines rules to apply an XSLT stylesheet to an XML file using the
# xsltproc driver, part of libxslt.
import common ;
import feature ;
import modules ;
import os ;
import path ;
import regex ;
import sequence ;
feature.feature xsl:param : : free ;
feature.feature xsl:path : : free ;
feature.feature catalog : : free ;
# Initialize xsltproc support. The parameters are:
# xsltproc: The xsltproc executable
#
rule init ( xsltproc ? )
{
if $(xsltproc)
{
modify-config ;
.xsltproc = $(xsltproc) ;
check-xsltproc ;
}
}
rule freeze-config ( )
{
if ! $(.config-frozen)
{
.config-frozen = true ;
.xsltproc ?= [ modules.peek : XSLTPROC ] ;
.xsltproc ?= xsltproc ;
check-xsltproc ;
.is-cygwin = [ .is-cygwin $(.xsltproc) ] ;
}
}
rule modify-config ( )
{
if $(.config-frozen)
{
import errors ;
errors.user-error
"xsltproc: Cannot change xsltproc command after it has been used." ;
}
}
rule check-xsltproc ( )
{
if $(.xsltproc)
{
local status = [ SHELL "\"$(.xsltproc)\" -V" : no-output : exit-status ]
;
if $(status[2]) != 0
{
import errors ;
errors.user-error "xsltproc: Could not run \"$(.xsltproc)\" -V." ;
}
}
}
# Returns a non-empty string if a cygwin xsltproc binary was specified.
#
rule is-cygwin ( )
{
freeze-config ;
return $(.is-cygwin) ;
}
rule .is-cygwin ( xsltproc )
{
if [ os.on-windows ]
{
local file = [ path.make [ modules.binding $(__name__) ] ] ;
local dir = [ path.native [ path.join [ path.parent $(file) ] xsltproc ]
] ;
if [ os.name ] = CYGWIN
{
dir = $(dir:W) ;
}
local command =
"\"$(xsltproc)\" \"$(dir)\\test.xsl\" \"$(dir)\\test.xml\" 2>&1" ;
local status = [ SHELL $(command) : no-output : exit-status ] ;
if $(status[2]) != "0"
{
return true ;
}
}
}
rule compute-xslt-flags ( target : properties * )
{
# Raw flags.
local flags = [ feature.get-values <flags> : $(properties) ] ;
# Translate <xsl:param> into command line flags.
for local param in [ feature.get-values <xsl:param> : $(properties) ]
{
local namevalue = [ regex.split $(param) "=" ] ;
flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ;
}
# Translate <xsl:path>.
for local path in [ feature.get-values <xsl:path> : $(properties) ]
{
flags += --path \"$(path:G=)\" ;
}
# Take care of implicit dependencies.
local other-deps ;
for local dep in [ feature.get-values <implicit-dependency> : $(properties)
]
{
other-deps += [ $(dep:G=).creating-subvariant ] ;
}
local implicit-target-directories ;
for local dep in [ sequence.unique $(other-deps) ]
{
implicit-target-directories += [ $(dep).all-target-directories ] ;
}
for local dir in $(implicit-target-directories)
{
flags += --path \"$(dir:T)\" ;
}
return $(flags) ;
}
local rule .xsltproc ( target : source stylesheet : properties * : dirname ? :
action )
{
freeze-config ;
STYLESHEET on $(target) = $(stylesheet) ;
FLAGS on $(target) += [ compute-xslt-flags $(target) : $(properties) ] ;
NAME on $(target) = $(.xsltproc) ;
for local catalog in [ feature.get-values <catalog> : $(properties) ]
{
CATALOG = [ common.variable-setting-command XML_CATALOG_FILES :
$(catalog:T) ] ;
}
if [ os.on-windows ] && ! [ is-cygwin ]
{
action = $(action).windows ;
}
$(action) $(target) : $(source) ;
}
rule xslt ( target : source stylesheet : properties * )
{
return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) : :
xslt-xsltproc ] ;
}
rule xslt-dir ( target : source stylesheet : properties * : dirname )
{
return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) :
$(dirname) : xslt-xsltproc-dir ] ;
}
actions xslt-xsltproc.windows
{
$(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:W)" "$(>:W)"
}
actions xslt-xsltproc bind STYLESHEET
{
$(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:T)" "$(>:T)"
}
actions xslt-xsltproc-dir.windows bind STYLESHEET
{
$(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:W)" "$(>:W)"
}
actions xslt-xsltproc-dir bind STYLESHEET
{
$(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:T)" "$(>:T)"
}