+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Name: include/defs.xml
+ Purpose: Common declarations for buildbot
+ Author: Mike Wetherell
+ RCS-ID: $Id$
+ Copyright: (c) 2007 Mike Wetherell
+ Licence: wxWidgets licence
+-->
+
+<bot xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:func="http://exslt.org/functions"
+ xmlns:get="local"
+ xsl:extension-element-prefixes="func"
+ xsl:version="1.0">
+
+<!--
+ Constants
+-->
+<xsl:template name="SVN_URL">http://svn.wxwidgets.org/svn/wx/wxWidgets/</xsl:template>
+<xsl:template name="STABLE_BRANCH">branches/WX_2_8_BRANCH</xsl:template>
+<xsl:variable name="STABLE_BRANCH"><STABLE_BRANCH/></xsl:variable>
+
+<!--
+ checkout - build step for source checkout.
+
+ Usage: as <svn> with defaults for <baseURL> and <defaultBranch>
+
+ Typically just:
+ <checkout/>
+ for the trunk, or:
+ <checkout branch="branches/WX_2_8_BRANCH"/>
+ to checkout a branch.
+-->
+<xsl:template name="checkout">
+ <xsl:param name="content"/>
+ <xsl:param name="branch" select="'trunk'"/>
+ <xsl:variable name="nodes" select="exsl:node-set($content)"/>
+ <svn>
+ <xsl:if test="not($nodes/svnurl)">
+ <xsl:if test="not($nodes/baseURL)">
+ <baseURL><SVN_URL/></baseURL>
+ </xsl:if>
+ <xsl:if test="not($nodes/defaultBranch)">
+ <defaultBranch><xsl:value-of select="$branch"/></defaultBranch>
+ </xsl:if>
+ </xsl:if>
+ <xsl:copy-of select="$content"/>
+ </svn>
+</xsl:template>
+
+<!--
+ configure - add the options attribute to <configure>
+
+ Usage: <configure options="-with-foobar"/>
+-->
+<xsl:template name="configure">
+ <xsl:param name="content"/>
+ <xsl:param name="options"/>
+ <configure>
+ <copy-with-defaults content="{$content}">
+ <command>./configure <xsl:value-of select="normalize-space($options)"/></command>
+ </copy-with-defaults>
+ </configure>
+</xsl:template>
+
+<!--
+ make - specify the make command.
+
+ Usage: <make>nmake -f makefile.vc SHARED=1</make>
+
+ Used as a child of <build> to specify the make command used by the
+ <compile> elements below, if omitted 'make' is used.
+-->
+<xsl:template name="make"/>
+
+<!--
+ compile - modifiy <compile> to default to the command given by <make>
+
+ Usage: as <compile>
+
+ The <make> element of <build> spcecifies the make command used by all
+ compile build steps in the build. If <make> is not given 'make' is used.
+
+ The command for a particular compile build step can be further overridden
+ using its <command> element:
+ <compile>
+ <command>myscript</command>
+ </compile>
+-->
+<xsl:template name="compile">
+ <xsl:param name="content"/>
+ <compile>
+ <copy-with-defaults content="{$content}">
+ <command><get name="make" default="make"/></command>
+ </copy-with-defaults>
+ </compile>
+</xsl:template>
+
+<!--
+ Adds build steps to compile the library and the usual subdirectories.
+
+ Usage: as <compile> with the additional attributes below.
+
+ Usually the attributes default to suitable values, so typical usage
+ is just <compile-all/>.
+
+ <compile-all [ gui = 'true'|'false' ]
+ [ msw = 'true'|'false' ]
+ [ wx = 'true'|'false' ]
+ [ samples = 'true'|'false' ]
+ [ utils = 'true'|'false' ]
+ [ demos = 'true'|'false' ]
+ [ contrib = 'true'|'false' ]
+ [ tests = 'true'|'false' ] />
+
+ gui - if 'true' then build fully the subdirectories specified,
+ otherwise only the wxBase subset of the directories are built.
+ msw - if 'true' then build the directory 'build/msw' when building the
+ library instead of the root.
+ wx - build the library itself.
+ samples, utils, demos, contrib, tests
+ - build subdirectories.
+-->
+<xsl:template name="compile-all">
+ <xsl:param name="content"/>
+
+ <xsl:param name="gui"><is-gui/></xsl:param>
+ <xsl:param name="msw"><is-msw/></xsl:param>
+
+ <xsl:param name="wx" select="'true'"/>
+ <xsl:param name="samples" select="'true'"/>
+ <xsl:param name="utils" select="'true'"/>
+ <xsl:param name="demos" select="$gui"/>
+ <xsl:param name="contrib"><has-contrib/></xsl:param>
+ <xsl:param name="tests"><has-tests/></xsl:param>
+
+ <xsl:param name="wx-dirs">
+ <get-dirs wx="{$wx}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+ <xsl:param name="sample-dirs">
+ <get-dirs samples="{$samples}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+ <xsl:param name="util-dirs">
+ <get-dirs utils="{$utils}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+ <xsl:param name="demo-dirs">
+ <get-dirs demos="{$demos}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+ <xsl:param name="contrib-dirs">
+ <get-dirs contrib="{$contrib}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+ <xsl:param name="test-dirs">
+ <get-dirs tests="{$tests}" gui="{$gui}" msw="{$msw}"/>
+ </xsl:param>
+
+ <compile-subdirs dirs="{$wx-dirs}" halt="true">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+ <compile-subdirs name="samples" dirs="{$sample-dirs}">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+ <compile-subdirs name="utils" dirs="{$util-dirs}">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+ <compile-subdirs name="demos" dirs="{$demo-dirs}">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+ <compile-subdirs name="contrib" dirs="{$contrib-dirs}">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+ <compile-subdirs name="tests" dirs="{$test-dirs}" halt="true">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+</xsl:template>
+
+<!--
+ Helper for compile-all.
+ Returns the directories that need to be built for the various components:
+ wx (the library itself), samples, utils, demos, contrib and tests.
+-->
+<xsl:template name="get-dirs">
+ <xsl:param name="contents"/>
+
+ <xsl:param name="gui"/>
+ <xsl:param name="msw"/>
+
+ <xsl:param name="wx"/>
+ <xsl:param name="samples"/>
+ <xsl:param name="utils"/>
+ <xsl:param name="demos"/>
+ <xsl:param name="contrib"/>
+ <xsl:param name="tests"/>
+
+ <xsl:if test="$wx = 'true'">
+ <xsl:choose>
+ <xsl:when test="$msw = 'true'">build/msw</xsl:when>
+ <xsl:otherwise>.</xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+
+ <xsl:if test="$samples = 'true'">
+ <xsl:choose>
+ <xsl:when test="$gui = 'true'">samples</xsl:when>
+ <xsl:otherwise>samples/console</xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+
+ <xsl:if test="$utils = 'true'">
+ <xsl:choose>
+ <xsl:when test="$gui = 'true'">utils</xsl:when>
+ <xsl:otherwise>utils/tex2rtf/src ../../HelpGen/src</xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+
+ <xsl:if test="$demos = 'true' and $gui = 'true'">demos </xsl:if>
+
+ <xsl:if test="$contrib = 'true' and $gui = 'true'">contrib </xsl:if>
+
+ <xsl:if test="$tests = 'true'">tests</xsl:if>
+</xsl:template>
+
+<!--
+ compile-subdir - build step to compile a subdirectory.
+
+ Usage: as <compile> plus the following attributes,
+ <compile-subdir dir="foobar" [ halt="true" ]/>
+
+ Compiles the named subdirectory 'foobar'. Continues with the next build
+ step on failure, unless the optional attibute 'halt="true"' is given.
+ The make command used is as described for the compile step above.
+-->
+<xsl:template name="compile-subdir">
+ <xsl:param name="content"/>
+ <xsl:param name="dir"/>
+ <xsl:param name="halt" select="'false'"/>
+ <compile-subdirs name="{$dir}" dirs="{$dir}" halt="{$halt}">
+ <xsl:copy-of select="$content"/>
+ </compile-subdirs>
+</xsl:template>
+
+<!--
+ compile-subdirs - adds a compile build step for each directory in a list.
+
+ Usage: as <compile> plus the following attributes,
+ <compile-subdir dirs="foobar1 foobar2"
+ [ name="foobars" ]
+ [ sep=" " ]
+ [ halt="true" ]/>
+
+ Compiles the named subdirectories. Continues with the next build
+ step on failure, unless the optional attibute 'halt="true"' is given.
+ The make command used is as described for the compile step above.
+ The 'name' attribute can be used to give a collective name for the
+ subdirectories, and the 'sep' attibute can be used to specify the
+ separator in the 'dirs' list (defaults to space).
+-->
+<xsl:template name="compile-subdirs">
+ <xsl:param name="content"/>
+ <xsl:param name="name"/>
+ <xsl:param name="dirs"/>
+ <xsl:param name="sep" select="' '"/>
+ <xsl:param name="halt" select="'false'"/>
+ <xsl:if test="translate($dirs, $sep, '')">
+ <compile>
+ <defaults content="{$content}">
+ <name>
+ <xsl:value-of select="normalize-space(concat('compile ', $name))"/>
+ </name>
+ <description>
+ <xsl:value-of select="normalize-space(concat('compiling ', $name))"/>
+ </description>
+ <descriptionDone>
+ <xsl:value-of select="normalize-space(concat('compile ', $name))"/>
+ </descriptionDone>
+ <haltOnFailure>
+ <xsl:value-of select="$halt"/>
+ </haltOnFailure>
+ <warnOnFailure/>
+ </defaults>
+ <copy-with-defaults content="{$content}">
+ <command>
+ <compile-subdirs-cmd dirs="{$dirs}" sep="{$sep}"/>
+ </command>
+ </copy-with-defaults>
+ </compile>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="compile-subdirs-cmd">
+ <xsl:param name="content"/>
+ <xsl:param name="dirs"/>
+ <xsl:param name="sep"/>
+ <xsl:choose>
+ <xsl:when test="contains($dirs, $sep)">
+ <xsl:variable name="before" select="substring-before($dirs, $sep)"/>
+ <xsl:variable name="after" select="substring-after($dirs, $sep)"/>
+
+ <xsl:call-template name="compile-subdirs-cmd">
+ <xsl:with-param name="dirs" select="$before"/>
+ <xsl:with-param name="sep" select="$sep"/>
+ </xsl:call-template>
+
+ <xsl:if test="$after and substring($after, 1, 1) != ' '">
+ <xsl:text> && </xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="compile-subdirs-cmd">
+ <xsl:with-param name="dirs" select="$after"/>
+ <xsl:with-param name="sep" select="$sep"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="string($dirs)">
+ <xsl:if test="$dirs != '.'">cd <xsl:value-of select="$dirs"/> && </xsl:if>
+ <get name="make" default="make"/>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+ run-tests - build step to run the test suites.
+
+ Usage: as <test>
+
+ Typically just:
+ <run-tests/>
+-->
+<xsl:template name="run-tests">
+ <xsl:param name="content"/>
+ <xsl:param name="msw"><is-msw/></xsl:param>
+ <test>
+ <defaults content="{$content}">
+ <description>running tests</description>
+ <descriptionDone>run tests</descriptionDone>
+ <warnOnFailure/>
+ </defaults>
+ <copy-with-defaults content="{$content}">
+ <command>
+ <xsl:choose>
+ <xsl:when test="$msw = 'true'">
+ <run-tests-win/>
+ </xsl:when>
+ <xsl:otherwise>
+ <run-tests-unix/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </command>
+ </copy-with-defaults>
+ </test>
+</xsl:template>
+
+<!--
+ We need to add something to the wxWidgets sources to run the tests with a
+ simple command so that these aren't necessary.
+-->
+<xsl:template name="run-tests-win">
+<normalize-space>
+cd tests &&
+(for /d %x in (..\lib\*_dll) do @PATH=%x;%PATH%) &&
+(for /d %x in (*) do @if exist %x\test.exe %x\test) &&
+(for /d %x in (*) do @if exist %x\test_gui.exe %x\test_gui)
+</normalize-space>
+</xsl:template>
+
+<xsl:template name="run-tests-unix">
+<normalize-space>
+cd tests &&
+./test &&
+if [ -x test_gui ]; then ./test_gui; fi
+</normalize-space>
+</xsl:template>
+
+<!--
+ defaults - supply default content for an element.
+
+ Usage: <defaults content="{$content}">
+ <foo>foo</foo>
+ <bar>bar</bar>
+ </defaults>
+
+ Copies those child elements that do not already exist in $content.
+-->
+<xsl:template name="defaults">
+ <xsl:param name="defaults"/>
+ <xsl:param name="content"/>
+
+ <xsl:variable name="def-nodes" select="exsl:node-set($defaults)"/>
+ <xsl:variable name="cont-nodes" select="exsl:node-set($content)"/>
+
+ <xsl:for-each select="$def-nodes/*">
+ <xsl:if test="not($cont-nodes/*[name() = name(current())])">
+ <xsl:copy-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<!--
+ copy-with-defaults - copy elements supplying defaults for any that are
+ missing or empty.
+
+ Usage: <copy-with-defaults content="{$content}">
+ <foo>foo</foo>
+ <bar>bar</bar>
+ </copy-with-defaults>
+
+ Copies $content plus any child elements that do not exist in $content,
+ substituting empty elements in $content with any child elements of the
+ same name.
+-->
+<xsl:template name="copy-with-defaults">
+ <xsl:param name="defaults"/>
+ <xsl:param name="content"/>
+
+ <xsl:variable name="def-nodes" select="exsl:node-set($defaults)"/>
+ <xsl:variable name="cont-nodes" select="exsl:node-set($content)"/>
+
+ <xsl:for-each select="$def-nodes/*">
+ <xsl:if test="not($cont-nodes/*[name() = name(current())])">
+ <xsl:copy-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:for-each select="$cont-nodes/*">
+ <xsl:choose>
+ <xsl:when test="not(node())">
+ <xsl:copy-of select="$def-nodes/*[name() = name(current())]"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+</xsl:template>
+
+<!--
+ get - gets the text from a child element of the current build.
+
+ Usage: <get name="foobar" [ default="value" ]/>
+
+ Gets the text from the <foobar> element of the current build, or returns
+ $default if there is not such element.
+-->
+<xsl:template name="get">
+ <xsl:param name="content"/>
+ <xsl:param name="build" select="get:build()"/>
+ <xsl:param name="name"/>
+ <xsl:param name="default"/>
+ <xsl:variable name="property" select="get:property($name, $build)"/>
+ <strip>
+ <xsl:choose>
+ <xsl:when test="$property">
+ <xsl:apply-templates select="$property/node()"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$default"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </strip>
+</xsl:template>
+
+<!--
+ Accessors to get builds and their fields. XSLT code should use these
+ instead of traversing the input tree directly.
+-->
+<func:function name="get:build">
+ <func:result select="ancestor-or-self::build[last()]"/>
+</func:function>
+
+<func:function name="get:all-builds">
+ <func:result select="//build[not(ancestor::*[name() != name(/*)])]"/>
+</func:function>
+
+<func:function name="get:preceding-builds">
+ <func:result select="get:build()/preceding-sibling::build"/>
+</func:function>
+
+<func:function name="get:property">
+ <xsl:param name="name"/>
+ <xsl:param name="build" select="get:build()"/>
+ <func:result select="$build/*[name() = $name]"/>
+</func:function>
+
+<func:function name="get:step">
+ <xsl:param name="name"/>
+ <xsl:param name="build" select="get:build()"/>
+ <func:result select="get:property('steps', $build)/*[name() = $name]"/>
+</func:function>
+
+<!--
+ Returns true if this is an msw build.
+-->
+<xsl:template name="is-msw">
+ <xsl:param name="content"/>
+ <xsl:param name="build" select="get:build()"/>
+ <xsl:value-of select="not(get:step('configure', $build))"/>
+</xsl:template>
+
+<!--
+ Returns true if this a gui build.
+-->
+<xsl:template name="is-gui">
+ <xsl:param name="content"/>
+ <xsl:param name="build" select="get:build()"/>
+ <xsl:variable name="make"><get name="make" build="{$build}"/></xsl:variable>
+ <xsl:variable name="configure"><xsl:apply-templates select="get:step('configure', $build)"/></xsl:variable>
+ <xsl:value-of select="not(contains($make, 'USE_GUI=0') or contains($configure, '--disable-gui'))"/>
+</xsl:template>
+
+<!--
+ Returns true if the branch we're building has a contrib subdirectory.
+-->
+<xsl:template name="has-contrib">
+ <xsl:param name="content"/>
+ <xsl:param name="build" select="get:build()"/>
+ <xsl:variable name="checkout"><xsl:apply-templates select="get:step('checkout', $build)"/></xsl:variable>
+ <xsl:value-of select="contains($checkout, 'WX_2_') and not(contains($checkout, 'WX_2_9_'))"/>
+</xsl:template>
+
+<!--
+ Returns true if the build should build the test suite.
+-->
+<xsl:template name="has-tests">
+ <xsl:param name="content"/>
+ <xsl:param name="build" select="get:build()"/>
+ <xsl:variable name="configure"><xsl:apply-templates select="get:step('configure', $build)"/></xsl:variable>
+ <xsl:value-of select="get:step('run-tests', $build) or contains($configure, '--host=')"/>
+</xsl:template>
+
+<!--
+ strip - strips leading and trailing whitespace
+
+ Usage: <strip>
+ foobar
+ </strip>
+
+ Converts to text and strips leading and trailing whitespace.
+-->
+<xsl:template name="strip">
+ <xsl:param name="content"/>
+ <xsl:variable name="len" select="string-length($content)"/>
+ <xsl:variable name="norm" select="normalize-space($content)"/>
+ <xsl:variable name="normlen" select="string-length($norm)"/>
+ <xsl:choose>
+ <xsl:when test="substring($content, 1, 1) != substring($norm, 1, 1)">
+ <xsl:call-template name="strip">
+ <xsl:with-param name="content" select="substring($content, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="substring($content, $len, 1) != substring($norm, $normlen, 1)">
+ <xsl:call-template name="strip">
+ <xsl:with-param name="content" select="substring($content, 1, $len - 1)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$content"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+ normalize-space - normalises whitespace.
+
+ Usage: <normalize-space>
+ foobar
+ </normalize-space>
+
+ Converts to text, strips leading and trailing whitespace and replaces
+ sequences of whitespace characters by a single space.
+-->
+<xsl:template name="normalize-space">
+ <xsl:param name="content"/>
+ <xsl:value-of select="normalize-space($content)"/>
+</xsl:template>
+
+<!--
+ lower-case - converts to lower case.
+
+ Usage: <lower-case>FooBar</lower-case>
+-->
+<xsl:template name="lower-case">
+ <xsl:param name="content"/>
+ <xsl:variable name="lower">abcdefghijklmnopqrstuvwxyz</xsl:variable>
+ <xsl:variable name="upper">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
+ <xsl:value-of select="translate($content, $upper, $lower)"/>
+</xsl:template>
+
+<!--
+ Helpers to convert between day numbers and names.
+-->
+<xsl:template name="day-number">
+ <xsl:param name="content"/>
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="$name = 'sunday'">0</xsl:when>
+ <xsl:when test="$name = 'monday'">1</xsl:when>
+ <xsl:when test="$name = 'tuesday'">2</xsl:when>
+ <xsl:when test="$name = 'wednesday'">3</xsl:when>
+ <xsl:when test="$name = 'thursday'">4</xsl:when>
+ <xsl:when test="$name = 'friday'">5</xsl:when>
+ <xsl:when test="$name = 'saturday'">6</xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="day-name">
+ <xsl:param name="content"/>
+ <xsl:param name="number"/>
+ <xsl:choose>
+ <xsl:when test="$number = '0'">sunday</xsl:when>
+ <xsl:when test="$number = '1'">monday</xsl:when>
+ <xsl:when test="$number = '2'">tuesday</xsl:when>
+ <xsl:when test="$number = '3'">wednesday</xsl:when>
+ <xsl:when test="$number = '4'">thursday</xsl:when>
+ <xsl:when test="$number = '5'">friday</xsl:when>
+ <xsl:when test="$number = '6'">saturday</xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+ Helpers to convert between time in the format 'hhmm' and an integer
+ count of the minutes since midnight.
+-->
+<xsl:template name="time-minutes">
+ <xsl:param name="content"/>
+ <xsl:param name="hhmm"/>
+ <xsl:if test="string-length($hhmm) = 4 and format-number($hhmm, '0000') = $hhmm">
+ <xsl:variable name="hour" select="substring($hhmm, 1, 2)"/>
+ <xsl:variable name="min" select="substring($hhmm, 3, 2)"/>
+ <xsl:if test="$hour >= 0 and $hour < 24 and $min >= 0 and $min < 60">
+ <xsl:value-of select="$hour * 60 + $min"/>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="time-hhmm">
+ <xsl:param name="content"/>
+ <xsl:param name="minutes"/>
+ <xsl:value-of select="format-number(floor($minutes div 60) * 100 + $minutes mod 60, '0000')"/>
+</xsl:template>
+
+<!--
+ Create schedulers.
+-->
+<xsl:template name="nightly-schedulers">
+ <xsl:param name="content"/>
+ <xsl:param name="name"/>
+ <xsl:param name="day"><day-number name="{$name}"/></xsl:param>
+ <xsl:param name="hour" select="0"/>
+ <xsl:param name="minute" select="0"/>
+ <xsl:param name="step" select="30"/>
+
+ <xsl:if test="$hour < 24">
+ <nightly>
+ <name>
+ <xsl:value-of select="concat($name, '_', format-number($hour, '00'), format-number($minute, '00'))"/>
+ </name>
+ <hour>
+ <xsl:value-of select="$hour"/>
+ </hour>
+ <minute>
+ <xsl:value-of select="$minute"/>
+ </minute>
+ <xsl:if test="$day != ''">
+ <dayOfWeek>
+ <xsl:value-of select="$day"/>
+ </dayOfWeek>
+ </xsl:if>
+ </nightly>
+ <xsl:variable name="next" select="$hour * 60 + $minute + $step"/>
+ <xsl:call-template name="nightly-schedulers">
+ <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="day" select="$day"/>
+ <xsl:with-param name="hour" select="floor($next div 60)"/>
+ <xsl:with-param name="minute" select="$next mod 60"/>
+ <xsl:with-param name="step" select="$step"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<!--
+ scheduler - provide default for the <scheduler> build element.
+-->
+<xsl:template name="scheduler">
+ <xsl:param name="content"/>
+ <xsl:param name="previous" select="get:property('scheduler', get:preceding-builds()[last()])"/>
+ <xsl:param name="step" select="60"/>
+
+ <xsl:choose>
+ <xsl:when test="exsl:node-set($content)/node()">
+ <scheduler>
+ <xsl:copy-of select="$content"/>
+ </scheduler>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="$previous">
+ <xsl:variable name="text">
+ <xsl:apply-templates select="."/>
+ </xsl:variable>
+ <scheduler>
+ <scheduler-subst text="{$text}" step="{$step}"/>
+ </scheduler>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="scheduler-subst">
+ <xsl:param name="content"/>
+ <xsl:param name="text"/>
+ <xsl:param name="step"/>
+
+ <xsl:variable name="name" select="substring-before($text, '_')"/>
+ <xsl:variable name="hhmm" select="substring-after($text, '_')"/>
+ <xsl:variable name="day"><day-number name="{$name}"/></xsl:variable>
+ <xsl:variable name="mins"><time-minutes hhmm="{$hhmm}"/></xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$mins = ''">
+ <xsl:value-of select="$text"/>
+ </xsl:when>
+ <xsl:when test="$day = ''">
+ <xsl:value-of select="$name"/>
+ <xsl:text>_</xsl:text>
+ <time-hhmm minutes="{$mins + $step}"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="day-mins" select="24 * 60"/>
+ <xsl:variable name="week-mins" select="7 * $day-mins"/>
+ <xsl:variable name="tmp" select="($day + 1) * $day-mins + $mins"/>
+ <xsl:variable name="next" select="$tmp mod $week-mins + floor($tmp div $week-mins) * $step"/>
+ <day-name number="{floor($next div $day-mins)}"/>
+ <xsl:text>_</xsl:text>
+ <time-hhmm minutes="{$next mod $day-mins}"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</bot>