Commit Jeroen Witmond's xml-to-text translator, and use it for the FAQ.
Less double maintenance, hoorah!
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4830 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/docs/Makefile.am b/docs/Makefile.am
index fee2b2a..b8307f0 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -7,7 +7,7 @@
# Comment out the next line to skip building print docs. The default
# is not to skip building print docs. Note, after changing it
# you of course need to re-run configure to make it take effect.
-BUILD_ALL_DOCS=yes
+BUILD_ALL_DOCS=no
##-------------------------------------------------------------
## END OF HACK
@@ -44,18 +44,24 @@
# stylesheet processor
XSLTPROC = xsltproc
-XSLTPROC_FLAGS = --nonet --xinclude
+XSLTPROC_FLAGS = --xinclude
# stylesheets
XSL_HTML_CHUNK_STYLE = $(mylibdir)/vg-html-chunk.xsl
XSL_HTML_SINGLE_STYLE = $(mylibdir)/vg-html-single.xsl
XSL_FO_STYLE = $(mylibdir)/vg-fo.xsl
-all-docs: html-docs print-docs
+all-docs: FAQ.txt html-docs print-docs
valid:
$(XMLLINT) $(XMLLINT_FLAGS) $(myxmldir)/index.xml
+# The text version of the FAQ.
+FAQ.txt: $(myxmldir)/FAQ.xml $(myxmldir)/vg-entities.xml $(mylibdir)/*.xslt
+ $(XSLTPROC) $(XSLTPROC_FLAGS) $(mylibdir)/untag-inline.xslt $(myxmldir)/FAQ.xml | \
+ $(XSLTPROC) $(XSLTPROC_FLAGS) $(mylibdir)/docbook2text.xslt - > FAQ.txt
+
+
# chunked html
html-docs:
@echo "Generating html files..."
@@ -113,14 +119,17 @@
# This is done at 'make dist' time. It builds the html and print docs
# and copies them into the docs/ directory in the tarball.
ifeq ($(BUILD_ALL_DOCS),yes)
-dist-hook: html-docs print-docs
+dist-hook: FAQ.txt html-docs print-docs
cp -r html $(distdir)
+ cp FAQ.txt $(distdir)/..
cp print/index.pdf $(distdir)
cp print/index.ps $(distdir)
else
-dist-hook: html-docs
+dist-hook: FAQ.txt html-docs
+ cp FAQ.txt $(distdir)/..
cp -r html $(distdir)
endif
distclean-local:
rm -rf html print
+ rm -f $(top_builddir)/FAQ.txt
diff --git a/docs/README b/docs/README
index af8fa16..6f6b5e3 100644
--- a/docs/README
+++ b/docs/README
@@ -178,12 +178,6 @@
- http://cvs.sourceforge.net/viewcvs.py/perl-xml/perl-xml-faq/
-TODO CRUCIAL:
--------------
-- Need to generate text FAQ from the valgrind/docs/xml/FAQ.xml (done at 'make
- dist' time along with the HTML docs using the "dist-hook"), and remove the
- old text FAQ which is in valgrind/.
-
TODO LESS CRUCIAL:
------------------
- add the HOWTO doc?
diff --git a/docs/lib/Makefile.am b/docs/lib/Makefile.am
index 627e39d..c589900 100644
--- a/docs/lib/Makefile.am
+++ b/docs/lib/Makefile.am
@@ -1,6 +1,16 @@
EXTRA_DIST = \
+ README_XML2TXT.txt \
+ copy.xslt \
+ text.justify.xslt \
+ docbook2text.xslt \
+ text.wrap.xslt \
+ str.dup.xslt \
+ untag-inline.xslt \
+ str.find-last.xslt \
vg-common.xsl \
vg-fo.xsl \
vg-html-chunk.xsl \
vg-html-single.xsl \
vg_basic.css
+
+
diff --git a/docs/lib/README_XML2TXT.txt b/docs/lib/README_XML2TXT.txt
new file mode 100644
index 0000000..3d70bec
--- /dev/null
+++ b/docs/lib/README_XML2TXT.txt
@@ -0,0 +1,59 @@
+README.txt file for the FAQ.xml to FAQ.txt transformer.
+=======================================================
+
+In valgrind-3.1.SVN, file docs/README contains, under the heading
+"TODO CRUCIAL", the item "Need to generate text FAQ from the
+valgrind/docs/xml/FAQ.xml (done at 'make dist' time along with the
+HTML docs using the 'dist-hook'), and remove the old text FAQ which is
+in valgrind/." This is an attempt to resolve this item using xsltproc
+and a number of xml style sheets. It is a hack in the sense that it
+does not support all of docbook, but only the subset currently used by
+file docs/xml/FAQ.xml.
+
+The transformation is done in two stages:
+
+1. Inline elements (literal, computeroutput and ulink) are replaced
+ with the corresponding text by stylesheet untag-inline.xslt. This
+ stylesheet uses copy.xslt to handle the non-inline elements.
+
+2. The actual formatting is done by stylesheet docbook2text.xslt. It
+ uses stylesheets str.dup.xslt, str.find-last.xslt,
+ text.justify.xslt and text.wrap.xslt to handle the formatting of
+ the text into a column with the approproate width and indentation.
+
+Stylesheets untag-inline.xslt and docbook2text.xslt are original
+work. Stylesheets copy.xslt, str.dup.xslt, str.find-last.xslt,
+text.justify.xslt and text.wrap.xslt are copied with some adaptations
+from the examples supplied with the XSLT Cookbook by Sal Mangano, (C)
+2003 O'Reilly & Associates, ISBN 0-596-00372-2. The O'Reilly Policy on
+Re-Use of Code Examples from Books
+<http://www.oreilly.com/pub/a/oreilly/ask_tim/2001/codepolicy.html>
+allows the use of these style sheets in valgrind for this purpose.
+
+The tarball contains:
+
+- File README.txt (this file).
+
+- the stylesheets copy.xslt, docbook2text.xslt, str.dup.xslt,
+ str.find-last.xslt, text.justify.xslt, text.wrap.xslt and
+ untag-inline.xslt.
+
+- File faq.txt.patch adds the generation of FAQ.txt to file
+ docs/Makefile.am. It is based on the assumptions that
+ * file FAQ.txt will be generated in directory docs.
+ * the stylesheets will be stored in directory docs/lib.
+ If a different output width is required (e.g. 80), you can use
+ command
+ $(XSLTPROC) $(XSLTPROC_FLAGS) $(libdir)/untag-inline.xslt $(xmldir)/FAQ.xml | \
+ $(XSLTPROC) $(XSLTPROC_FLAGS) --stringparam width 80 $(libdir)/docbook2text.xslt - > FAQ.txt
+
+- File FAQ.txt as generated on my system (Debian 3.1).
+
+Software used:
+xsltproc was compiled against libxml 20616, libxslt 10112 and libexslt 810
+libxslt 10112 was compiled against libxml 20616
+libexslt 810 was compiled against libxml 20616
+
+
+Copyright 2005 Jeroen N. Witmond, jnw@xs4all.nl
+GNU GENERAL PUBLIC LICENSE Version 2, June 1991 applies.
diff --git a/docs/lib/copy.xslt b/docs/lib/copy.xslt
new file mode 100644
index 0000000..b2c565d
--- /dev/null
+++ b/docs/lib/copy.xslt
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!-- This file was copied with some adaptations from the examples
+supplied with the XSLT Cookbook by Sal Mangano, (C) 2003 O'Reilly &
+Associates, ISBN 0-596-00372-2. -->
+
+<xsl:output method="xml"/>
+
+<xsl:template match="/ | node() | @* | comment() | processing-instruction()">
+ <xsl:copy>
+ <xsl:apply-templates select="node() | @*"/>
+ </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/lib/docbook2text.xslt b/docs/lib/docbook2text.xslt
new file mode 100644
index 0000000..becc862
--- /dev/null
+++ b/docs/lib/docbook2text.xslt
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text"
+ xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings">
+
+<xsl:include href="text.wrap.xslt"/>
+
+<xsl:strip-space elements="*"/>
+<xsl:preserve-space elements="screen programlisting"/>
+<xsl:output method="text"/>
+
+<!-- Transform a subset of docbook/xml into plain text. This -->
+<!-- stylesheet assumes that all elements that are to be formatted -->
+<!-- inline already have been handled by untag-inline.xslt. -->
+
+<!-- Maximum number of characters on one line. -->
+<xsl:param name="width" select="72"/>
+
+<!-- This stylesheet uses two named templates. The template named -->
+<!-- "header" writes its input, followed by a line of '~'s of -->
+<!-- the same length. The template named "ruler" produces a line of -->
+<!-- $width '-'s. They are implemented at the bottom of this file. -->
+
+<xsl:template match="/">
+ <!-- Title 'page' stuff. -->
+ <xsl:call-template name="header">
+ <xsl:with-param name="input" select="book/title"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="header">
+ <xsl:with-param name="input" select="book/bookinfo/releaseinfo"/>
+ </xsl:call-template>
+ <xsl:text>
</xsl:text>
+
+ <!-- List of sections. -->
+ <xsl:text>Table of Contents
</xsl:text>
+ <xsl:apply-templates select="book/sect1" mode="toc"/>
+ <xsl:text>
</xsl:text>
+
+ <!-- Contents. -->
+ <xsl:apply-templates select="book/sect1"/>
+</xsl:template>
+
+<xsl:template match="sect1" mode="toc">
+ <xsl:value-of select="position()"/>
+ <xsl:text>. </xsl:text>
+ <xsl:value-of select="title"/>
+ <xsl:text>
</xsl:text>
+</xsl:template>
+
+<!-- Processing of the contents starts here. -->
+
+<xsl:template match="sect1">
+ <!-- The FAQ contains two types of sect1: those containing a
+ qandaset (actually an unspecified number), and those containing a
+ sequence of paras. To get the number of blank lines right, these
+ must be treated separately. -->
+
+ <xsl:variable name="sectno" select="position()"/>
+
+ <xsl:call-template name="ruler"/>
+ <xsl:value-of select="$sectno"/>
+ <xsl:text>. </xsl:text>
+ <xsl:value-of select="title"/>
+ <xsl:text>
</xsl:text>
+ <xsl:call-template name="ruler"/>
+ <xsl:text>
</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="qandaset">
+ <xsl:apply-templates select="qandaset|para">
+ <xsl:with-param name="sectno" select="$sectno"/>
+ </xsl:apply-templates>
+ </xsl:when>
+
+ <xsl:when test="para">
+ <xsl:for-each select="para|screen|programlisting|itemizedlist|orderedlist">
+ <xsl:apply-templates select="."/>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:when>
+
+ <!-- Oops. sect1 contains elements we do not yet handle. -->
+ <xsl:otherwise>
+ <xsl:message>template match="sect1": Encountered
+ <<xsl:value-of select="name(.)"/>>.</xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text>
</xsl:text>
+</xsl:template>
+
+<xsl:template match="qandaset">
+ <xsl:param name="sectno"/>
+
+ <xsl:apply-templates select="qandaentry">
+ <xsl:with-param name="sectno" select="$sectno"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="qandaentry">
+ <xsl:param name="sectno"/>
+
+ <xsl:variable name="questno" select="position()"/>
+
+ <xsl:variable name="prefix">
+ <xsl:value-of select="$sectno"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="$questno"/>
+ <xsl:text>. </xsl:text>
+ </xsl:variable>
+ <xsl:variable name="prefix-length" select="string-length($prefix)"/>
+
+ <xsl:if test="$questno > 1">
+ <xsl:text>
</xsl:text>
+ <xsl:call-template name="ruler"/>
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+
+ <xsl:apply-templates select="question">
+ <xsl:with-param name="prefix" select="$prefix"/>
+ <xsl:with-param name="indent" select="$prefix-length"/>
+ </xsl:apply-templates>
+
+ <xsl:text>
</xsl:text>
+
+ <xsl:apply-templates select="answer"/>
+</xsl:template>
+
+<xsl:template match="question">
+ <xsl:param name="prefix"/>
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:for-each select="para|screen|programlisting">
+ <xsl:choose>
+ <xsl:when test="position() = 1 and $prefix">
+ <xsl:value-of select="$prefix"/>
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ <xsl:with-param name="dofirst" select="0"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="answer">
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:for-each select="para|screen|programlisting|itemizedlist|orderedlist">
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:apply-templates>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="para">
+ <xsl:param name="indent" select="0"/>
+ <xsl:param name="dofirst" select="1"/>
+
+ <xsl:for-each select="node()">
+ <xsl:choose>
+ <!-- Lists and blocks as children. -->
+ <xsl:when test="self::screen|self::programlisting|
+ self::itemizedlist|self::orderedlist">
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:apply-templates>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:when>
+
+ <!-- Text. Inline elements have been flattened by
+ untag-inline.xslt. -->
+ <xsl:when test="self::text()">
+ <xsl:choose>
+ <xsl:when test="position() = 1 and $dofirst = 0">
+ <xsl:apply-templates select="." mode="text:wrap">
+ <xsl:with-param name="width" select="$width"/>
+ <xsl:with-param name="indent" select="$indent"/>
+ <xsl:with-param name="dofirst" select="0"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." mode="text:wrap">
+ <xsl:with-param name="width" select="$width"/>
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <!-- Oops. para contains elements we do not yet handle. -->
+ <xsl:otherwise>
+ <xsl:message>template match="para": Encountered
+ <<xsl:value-of select="name(.)"/>>.</xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="screen|programlisting">
+ <xsl:param name="indent" select="0"/>
+ <xsl:param name="dofirst" select="1"/><!-- ignored. -->
+
+ <xsl:variable name="myindent" select=" $indent + 2 " />
+
+ <xsl:apply-templates select="." mode="text:dump">
+ <xsl:with-param name="input" select="text()"/>
+ <xsl:with-param name="indent" select="$myindent"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="itemizedlist">
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:variable name="prefix" select=" '* ' "/>
+ <xsl:variable name="prefix-length" select="string-length($prefix)"/>
+
+ <xsl:for-each select="listitem">
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="prefix" select="$prefix"/>
+ <xsl:with-param name="indent" select="$prefix-length"/>
+ </xsl:apply-templates>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="orderedlist">
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:for-each select="listitem">
+ <xsl:variable name="prefix">
+ <xsl:value-of select="position()"/>
+ <xsl:text>. </xsl:text>
+ </xsl:variable>
+ <xsl:variable name="prefix-length" select="string-length($prefix)"/>
+
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="prefix" select="$prefix"/>
+ <xsl:with-param name="indent" select="$prefix-length"/>
+ </xsl:apply-templates>
+
+ <xsl:if test="position() != last()">
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="listitem">
+ <xsl:param name="prefix"/>
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:for-each select="para|screen|programlisting">
+ <xsl:choose>
+ <xsl:when test="position() = 1 and $prefix">
+ <xsl:value-of select="$prefix"/>
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ <xsl:with-param name="dofirst" select="0"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- Named utility templates. -->
+
+<xsl:template name="header">
+ <xsl:param name="input" select="0"/>
+ <xsl:variable name="input-length" select="string-length($input)"/>
+
+ <xsl:value-of select="$input"/>
+ <xsl:text>
</xsl:text>
+
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" '~' "/>
+ <xsl:with-param name="count" select="$input-length"/>
+ </xsl:call-template>
+ <xsl:text>
</xsl:text>
+</xsl:template>
+
+<xsl:template name="ruler">
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" '-' "/>
+ <xsl:with-param name="count" select="$width"/>
+ </xsl:call-template>
+ <xsl:text>
</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/lib/str.dup.xslt b/docs/lib/str.dup.xslt
new file mode 100644
index 0000000..564b342
--- /dev/null
+++ b/docs/lib/str.dup.xslt
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings">
+
+<!-- This file was copied with some adaptations from the examples
+supplied with the XSLT Cookbook by Sal Mangano, (C) 2003 O'Reilly &
+Associates, ISBN 0-596-00372-2. -->
+
+ <xsl:template name="str:dup">
+ <xsl:param name="input"/>
+ <xsl:param name="count" select="1"/>
+
+ <xsl:choose>
+ <xsl:when test="not($count) or not($input)"/>
+ <xsl:when test="$count = 1">
+ <xsl:value-of select="$input"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- If $count is odd append an extra copy of input -->
+ <xsl:if test="$count mod 2">
+ <xsl:value-of select="$input"/>
+ </xsl:if>
+ <!-- Recursively apply template after doubling input and
+ halving count -->
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select="concat($input,$input)"/>
+ <xsl:with-param name="count" select="floor($count div 2)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/lib/str.find-last.xslt b/docs/lib/str.find-last.xslt
new file mode 100644
index 0000000..2700fd3
--- /dev/null
+++ b/docs/lib/str.find-last.xslt
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="str.find-last"
+ xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings" extension-element-prefixes="str">
+
+<!-- This file was copied with some adaptations from the examples
+supplied with the XSLT Cookbook by Sal Mangano, (C) 2003 O'Reilly &
+Associates, ISBN 0-596-00372-2. -->
+
+<xsl:template name="str:substring-before-last">
+ <xsl:param name="input"/>
+ <xsl:param name="substr"/>
+
+ <xsl:if test="$substr and contains($input, $substr)">
+ <xsl:variable name="temp" select="substring-after($input, $substr)" />
+ <xsl:value-of select="substring-before($input, $substr)" />
+ <xsl:if test="contains($temp, $substr)">
+ <xsl:value-of select="$substr" />
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select="$temp" />
+ <xsl:with-param name="substr" select="$substr" />
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:if>
+
+</xsl:template>
+
+
+<xsl:template name="str:substring-after-last">
+ <xsl:param name="input"/>
+ <xsl:param name="substr"/>
+
+ <!-- Extract the string which comes after the first occurence -->
+ <xsl:variable name="temp" select="substring-after($input,$substr)"/>
+
+ <xsl:choose>
+ <xsl:when test="$substr and contains($temp,$substr)">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select="$temp"/>
+ <xsl:with-param name="substr" select="$substr"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$temp"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="xsl:stylesheet[@id='str.find-last'] | xsl:include[@href='str.find-last.xslt'] " >
+<tests>
+
+<!-- before -->
+ <test name="str:substring-before-last with no occurences of yes">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'No occurences' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-before-last starts with yes">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'yes occurences' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-before-last starts with yes and ends with yes">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'yes occurences yes' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-before-last 3 yes">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'yesyesyes' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+ <test name="str:substring-before-last empty input">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-before-last empty search">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'No occurences' "/>
+ </xsl:call-template>
+
+ </test>
+
+ <test name="str:substring-before-last large">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select=" 'yesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyesyes' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+
+
+ </test>
+
+<!-- after -->
+
+ <test name="str:substring-after-last with no occurences of yes">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'No occurences' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last starts with yes">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'yes occurences' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last starts with yes and ends with yes">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'yes occurences yes' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last 3 yes">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'yesyesyes' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last 3 yes then no">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'yesyesyesno' "/>
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last empty input">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="substr" select=" 'yes' "/>
+ </xsl:call-template>
+ </test>
+
+ <test name="str:substring-after-last empty search">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="input" select=" 'No occurences' "/>
+ </xsl:call-template>
+
+ </test>
+
+</tests>
+</xsl:template>
+
+ <xsl:template match="text()"/>
+
+</xsl:stylesheet>
diff --git a/docs/lib/text.justify.xslt b/docs/lib/text.justify.xslt
new file mode 100644
index 0000000..a6a8992
--- /dev/null
+++ b/docs/lib/text.justify.xslt
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings"
+ xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text" extension-element-prefixes="text">
+
+<!-- This file was copied with some adaptations from the examples
+supplied with the XSLT Cookbook by Sal Mangano, (C) 2003 O'Reilly &
+Associates, ISBN 0-596-00372-2. -->
+
+<xsl:include href="str.dup.xslt"/>
+
+<xsl:template name="text:justify">
+ <xsl:param name="value" />
+ <xsl:param name="width" select="10"/>
+ <xsl:param name="align" select=" 'left' "/>
+
+ <!-- Truncate if too long -->
+ <xsl:variable name="output" select="substring($value,1,$width)"/>
+
+ <xsl:choose>
+ <xsl:when test="$align = 'left'">
+ <xsl:value-of select="$output"/>
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="$width - string-length($output)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$align = 'right'">
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="$width - string-length($output)"/>
+ </xsl:call-template>
+ <xsl:value-of select="$output"/>
+ </xsl:when>
+ <xsl:when test="$align = 'center'">
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="floor(($width - string-length($output)) div 2)"/>
+ </xsl:call-template>
+ <xsl:value-of select="$output"/>
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="ceiling(($width - string-length($output)) div 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>INVALID ALIGN</xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/lib/text.wrap.xslt b/docs/lib/text.wrap.xslt
new file mode 100644
index 0000000..e77819e
--- /dev/null
+++ b/docs/lib/text.wrap.xslt
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="text.wrap"
+ xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings"
+ xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text" exclude-result-prefixes="text">
+
+<!-- This file was copied with some adaptations from the examples
+supplied with the XSLT Cookbook by Sal Mangano, (C) 2003 O'Reilly &
+Associates, ISBN 0-596-00372-2. -->
+
+<xsl:include href="str.find-last.xslt"/>
+<xsl:include href="text.justify.xslt"/>
+
+<xsl:template match="node() | @*" mode="text:wrap" name="text:wrap">
+ <xsl:param name="input" select="normalize-space()"/>
+ <xsl:param name="width" select="70"/>
+ <xsl:param name="indent" select="0"/>
+ <xsl:param name="dofirst" select="1"/>
+ <xsl:param name="align" select=" 'left' "/>
+
+ <xsl:variable name="effective" select="$width - $indent"/>
+
+ <xsl:if test="$input">
+ <xsl:variable name="line">
+ <xsl:choose>
+ <xsl:when test="string-length($input) > $effective">
+ <xsl:variable name="candidate-line" select="substring($input,1,$effective)"/>
+ <xsl:choose>
+ <xsl:when test="contains($candidate-line,' ')">
+ <xsl:call-template name="str:substring-before-last">
+ <xsl:with-param name="input" select="$candidate-line"/>
+ <xsl:with-param name="substr" select=" ' ' "/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$candidate-line"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$input"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:if test="$line">
+ <xsl:if test="$dofirst">
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="$indent"/>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:call-template name="text:justify">
+ <xsl:with-param name="value" select="$line"/>
+ <xsl:with-param name="width" select="$effective"/>
+ <xsl:with-param name="align" select="$align"/>
+ </xsl:call-template>
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="text:wrap">
+ <xsl:with-param name="input" select="substring($input, string-length($line) + 2)"/>
+ <xsl:with-param name="width" select="$width"/>
+ <xsl:with-param name="indent" select="$indent"/>
+ <xsl:with-param name="align" select="$align"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="node() | @*" mode="text:dump" name="text:dump">
+ <xsl:param name="input" select="text()"/>
+ <xsl:param name="indent" select="0"/>
+
+ <xsl:if test="$input">
+ <xsl:variable name="line">
+ <xsl:choose>
+ <xsl:when test="contains($input, '
')">
+ <xsl:value-of select="substring-before($input, '
')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$input"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:if test="$line">
+ <xsl:call-template name="str:dup">
+ <xsl:with-param name="input" select=" ' ' "/>
+ <xsl:with-param name="count" select="$indent"/>
+ </xsl:call-template>
+ <xsl:value-of select="$line"/>
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="text:dump">
+ <xsl:with-param name="input" select="substring-after($input, '
')"/>
+ <xsl:with-param name="indent" select="$indent"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/lib/untag-inline.xslt b/docs/lib/untag-inline.xslt
new file mode 100644
index 0000000..ea553a5
--- /dev/null
+++ b/docs/lib/untag-inline.xslt
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:include href="copy.xslt"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
+
+<!-- Preprocess a docbook/xml file, replacing elements that are to be -->
+<!-- formatted inline with the corresponding text. -->
+
+<xsl:template match="literal|computeroutput">
+ <xsl:value-of select="text()"/>
+</xsl:template>
+
+<xsl:template match="ulink">
+ <xsl:variable name="url" select="normalize-space(@url)"/>
+ <xsl:variable name="text" select="normalize-space(text())"/>
+
+ <xsl:if test="$text and $text != $url">
+ <xsl:text>'</xsl:text><xsl:value-of select="$text"/><xsl:text>' </xsl:text>
+ </xsl:if>
+ <xsl:text><</xsl:text><xsl:value-of select="$url"/><xsl:text>></xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/docs/xml/FAQ.xml b/docs/xml/FAQ.xml
index f8b8c12..25f44b0 100644
--- a/docs/xml/FAQ.xml
+++ b/docs/xml/FAQ.xml
@@ -305,21 +305,27 @@
<para>Some example sub-traces:</para>
- <para>With debug information and unstripped (best):</para>
+ <itemizedlist>
+ <listitem>
+ <para>With debug information and unstripped (best):</para>
<programlisting>
Invalid write of size 1
at 0x80483BF: really (malloc1.c:20)
by 0x8048370: main (malloc1.c:9)
</programlisting>
+ </listitem>
- <para>With no debug information, unstripped:</para>
+ <listitem>
+ <para>With no debug information, unstripped:</para>
<programlisting>
Invalid write of size 1
at 0x80483BF: really (in /auto/homes/njn25/grind/head5/a.out)
by 0x8048370: main (in /auto/homes/njn25/grind/head5/a.out)
</programlisting>
+ </listitem>
- <para>With no debug information, stripped:</para>
+ <listitem>
+ <para>With no debug information, stripped:</para>
<programlisting>
Invalid write of size 1
at 0x80483BF: (within /auto/homes/njn25/grind/head5/a.out)
@@ -327,17 +333,20 @@
by 0x42015703: __libc_start_main (in /lib/tls/libc-2.3.2.so)
by 0x80482CC: (within /auto/homes/njn25/grind/head5/a.out)
</programlisting>
+ </listitem>
- <para>With debug information and -fomit-frame-pointer:</para>
+ <listitem>
+ <para>With debug information and -fomit-frame-pointer:</para>
<programlisting>
Invalid write of size 1
at 0x80483C4: really (malloc1.c:20)
by 0x42015703: __libc_start_main (in /lib/tls/libc-2.3.2.so)
by 0x80482CC: ??? (start.S:81)
</programlisting>
+ </listitem>
- <para>A leak error message involving an unloaded shared object:</para>
-
+ <listitem>
+ <para>A leak error message involving an unloaded shared object:</para>
<programlisting>
84 bytes in 1 blocks are possibly lost in loss record 488 of 713
at 0x1B9036DA: operator new(unsigned) (vg_replace_malloc.c:132)
@@ -346,6 +355,8 @@
by 0x1D65E007: ???
by 0x8049EE6: main (main.cpp:24)
</programlisting>
+ </listitem>
+ </itemizedlist>
</answer>
</qandaentry>