# 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.
#
# Note: except for 'init', this modules does not provide any rules for end
# users.

import feature ;
import regex ;
import sequence ;
import common ;
import os ;
import modules ;
import path ;

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)
    {
        xsltproc = [ modules.peek : XSLTPROC ] ;
    }

    if ! $(.initialized)
    {
        .initialized = true ;
        .xsltproc = $(xsltproc) ;
        .is-cygwin = [ .is-cygwin $(xsltproc:E=xsltproc) ] ;
    }
}

# Returns a non-empty string if a cygwin xsltproc binary was specified.
rule is-cygwin ( )
{
    if ! $(.initialized)
    {
        init ;
    }
    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 * )
{
    local flags ;

    # Raw flags.
    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 )
{
    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)"
}
