First implementation of senfutil.Doxygen
g0dil [Tue, 1 Sep 2009 09:25:20 +0000 (09:25 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1362 270642c3-0616-0410-b53a-bc976706d245

14 files changed:
site_scons/lib/Doxyfile.yap [new file with mode: 0644]
site_scons/lib/DoxygenLayout.xml [new file with mode: 0644]
site_scons/lib/dot [new file with mode: 0755]
site_scons/lib/dot-munge.pl [new file with mode: 0755]
site_scons/lib/doxy.css [new file with mode: 0644]
site_scons/lib/doxyfooter.yap [new file with mode: 0644]
site_scons/lib/doxygen.sh [new file with mode: 0755]
site_scons/lib/doxyheader.yap [new file with mode: 0644]
site_scons/lib/filter.pl [new file with mode: 0755]
site_scons/lib/html-munge.xsl [new file with mode: 0644]
site_scons/lib/tag-munge.xsl [new file with mode: 0644]
site_scons/senfutil.py
site_scons/site_tools/Yaptu.py [new file with mode: 0644]
site_scons/site_tools/__init__.py [new file with mode: 0644]

diff --git a/site_scons/lib/Doxyfile.yap b/site_scons/lib/Doxyfile.yap
new file mode 100644 (file)
index 0000000..44c1bf4
--- /dev/null
@@ -0,0 +1,127 @@
+
+INPUT                  = .
+RECURSIVE              = NO
+PROJECT_NAME           = "${PROJECTNAME}"
+PROJECT_NUMBER         = "(Version ${REVISION})"
+
+###########################################################################
+# Layout customization
+
+DOXYFILE_ENCODING      = UTF-8
+INPUT_ENCODING         = UTF-8
+
+ALWAYS_DETAILED_SEC    = YES
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP         = YES
+
+ALIASES                = "fixme=\xrefitem fixme \"Fix\" \"Fixmes\"" \
+                         "idea=\xrefitem idea \"Idea\" \"Ideas\"" \
+                         "implementation=\par \"Implementation note:\"" \
+                         "doc=\xrefitem doc \"Documentation request\" \"Documentation Requests\"" \
+                         "autotoc=\htmlonly <div id=\"autotoc\"></div> \endhtmlonly" \
+                         "seechapter=<b>\htmlonly &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&rarr;&nbsp;\endhtmlonly see </b>"
+
+BUILTIN_STL_SUPPORT    = YES
+
+SUBGROUPING            = NO
+EXTRACT_ALL            = YES
+HIDE_FRIEND_COMPOUNDS  = YES
+INTERNAL_DOCS          = YES
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cci \
+                         *.ct \
+                         *.cti \
+                         *.h \
+                         *.hh \
+                         *.ih \
+                         *.mpp \
+                         *.dox
+EXCLUDE_PATTERNS       = *.test.cc \
+                         *.test.hh \
+                         .* \
+                         *~ \
+                         "#*#"
+EXCLUDE_SYMBOLS        = boost std
+IMAGE_PATH             = .
+
+SOURCE_BROWSER         = YES
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 3
+
+GENERATE_LATEX         = NO
+GENERATE_XML           = NO
+GENERATE_MAN           = NO
+
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = YES
+PREDEFINED             = DOXYGEN \
+                         "SENF_PPI_MODULE(x)=" \
+                         "SENF_PARSER()=" \
+                         "SENF_FIXED_PARSER()=" \
+                         "SENF_PARSER_INHERIT(name)=" \
+                         "SENF_PARSER_FIELD(name,type)=type name() const" \
+                         "SENF_PARSER_FIELD_RO(name,type)=type::value_type name() const" \
+                         "SENF_PARSER_BITFIELD(name, bits, type)=senf::ParseField_ ## type(bits) name() const" \
+                         "SENF_PARSER_BITFIELD_RO(name, bits, type)=senf::ParseField_ ## type(bits)::value_type name() const" \
+                         "SENF_PARSER_CUSTOM_FIELD(name, type, size, isize)=type name() const" \
+                         "SENF_PARSER_PRIVATE_FIELD(name,type)=private: type name() const; public:" \
+                         "SENF_PARSER_PRIVATE_FIELD_RO(name, type)=private: type::value_type name() const; public:" \
+                         "SENF_PARSER_PRIVATE_BITFIELD(name, bits, type)=private: senf::ParseField_ ## type(bits) name() const; public:" \
+                         "SENF_PARSER_PRIVATE_BITFIELD_RO(name, bits, type)=private: senf::ParseField_ ## type(bits)::value_type name() const; public:" \
+                         "SENF_PARSER_SKIP(x)=" \
+                         "SENF_PARSER_SKIP_BITS(x)=" \
+                         "SENF_PARSER_GOTO(x)=" \
+                         "SENF_PARSER_GOTO_OFFSET(x)=" \
+                         "SENF_PARSER_LABEL(x)=" \
+                         "SENF_PARSER_INIT()=void init()" \
+                         "SENF_PARSER_FINALIZE(name)=" \
+                         "ParseField_unsigned(b)=UIntFieldParser<?,?+b>" \
+                         "ParseField_signed(b)=IntFieldParser<?,?+b>" \
+                         "ParseField_bool(b)=FlagParser<?>" \
+                         "SENF_PARSER_ARRAY(name,elt_type,size)=senf::Parse_Array<size,elt_type> name() const" \
+                         "SENF_PARSER_LIST_B(name,elt_type,size_type)=senf::Parse_ListB<elt_type,size_type>::parser name() const" \
+                         "SENF_PARSER_LIST_N(name,elt_type,size_type)=senf::Parse_ListN<elt_type,size_type>::parser name() const" \
+                         "SENF_PARSER_VARIANT(name,chooser,types)=senf::Parse_Variant_Direct<chooser ## _t,?,types>::parser name() const" \
+                         "SENF_PARSER_PRIVATE_VARIANT(name,chooser,types)=private: senf::Parse_Variant_Direct<chooser ## _t,?,types>::parser name() const; public:" \
+                         "SENF_PARSER_VEC_N(name,elt_type,size_type)=senf::Parse_VectorN<elt_type,size_type> name() const" \
+                         "SENF_LOG_CLASS_AREA()=" \
+                         "SENF_LOG_DEFAULT_AREA(area)=" \
+                         "SENF_LOG_DEFAULT_STREAM(stream)=" \
+                         "BOOST_PP_ITERATE()=" \
+                         "BOOST_PARAMETER_KEYWORD(ns, name)=unspecified_keyword_type name;"
+EXPAND_AS_DEFINED      = prefix_ \
+                         SENF_LOG_DEF_STREAM \
+                         SENF_LOG_DEF_AREA \
+                         SENF_LOG_DEF_AREA_I
+
+EXTERNAL_GROUPS        = NO
+
+HAVE_DOT               = YES
+COLLABORATION_GRAPH    = NO
+GROUP_GRAPHS           = NO
+GRAPHICAL_HIERARCHY    = NO
+DIRECTORY_GRAPH        = NO
+DOT_GRAPH_MAX_NODES    = 10
+MAX_DOT_GRAPH_DEPTH    = 5
+DOT_MULTI_TARGETS      = YES
+DOT_CLEANUP            = NO
+
+SEARCHENGINE           = YES
+
+###########################################################################
+# The following options are MANDATORY to integrate with the build system
+
+OUTPUT_DIRECTORY       = $(output_dir)
+STRIP_FROM_INC_PATH    = $(TOPDIR)
+LAYOUT_FILE            = $(LIBDIR)/DoxygenLayout.xml
+GENERATE_HTML          = $(html)
+HTML_OUTPUT            = $(html_dir)
+HTML_HEADER            = $(TOPDIR)/$(output_dir)/doxyheader.html
+HTML_FOOTER            = $(TOPDIR)/$(output_dir)/doxyfooter.html
+INPUT_FILTER           = $(LIBDIR)/filter.pl
+TAGFILES               = $(tagfiles)
+GENERATE_TAGFILE       = $(generate_tagfile)
+DOT_PATH               = $(LIBDIR)
+
diff --git a/site_scons/lib/DoxygenLayout.xml b/site_scons/lib/DoxygenLayout.xml
new file mode 100644 (file)
index 0000000..94e2cda
--- /dev/null
@@ -0,0 +1,184 @@
+<doxygenlayout version="1.0">
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="pages" visible="yes" title=""/>
+    <tab type="modules" visible="yes" title=""/>
+    <tab type="namespaces" visible="yes" title="">
+      <tab type="namespaces" visible="yes" title=""/>
+      <tab type="namespacemembers" visible="yes" title=""/>
+    </tab>
+    <tab type="classes" visible="yes" title="">
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
+      <tab type="classes" visible="yes" title=""/>
+      <tab type="hierarchy" visible="yes" title=""/>
+      <tab type="classmembers" visible="yes" title=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="files" visible="yes" title=""/>
+      <tab type="globals" visible="yes" title=""/>
+    </tab>
+    <tab type="dirs" visible="yes" title=""/>
+    <tab type="examples" visible="yes" title=""/>  
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <allmemberslink visible="yes"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <related title="" subtitle=""/>
+      <membergroups visible="yes"/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+    </memberdecl>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="yes"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+    <sourcelink visible="yes"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="yes"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <nestedgroups visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <pagedocs/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="yes"/>
+    <directorygraph visible="yes"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+  </directory>
+</doxygenlayout>
diff --git a/site_scons/lib/dot b/site_scons/lib/dot
new file mode 100755 (executable)
index 0000000..c6bdbe4
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+topdir="`dirname "$0"`"; topdir="`cd "$topdir/.."; pwd`"
+if head -4 "$1" | grep -q nomunge; then
+    dot "$@"
+    exit $?
+fi
+sed -i -e 's/rankdir=LR/rankdir=TB/' "$1"
+"$topdir/doclib/dot-munge.pl" "$1"
+unflatten -l2 -c2 -f -o "$1".unflat "$1"
+mv "$1".unflat "$1"
+
+case "$2" in
+    -Tpng:gd)
+    first="$1"; shift; shift
+    set -- "$first" "-Tpng" "$@"
+    ;;
+    *)
+esac
+
+set -e
+
+dot "$@"
+
+case "$4" in
+    *.png)
+    if [ -r "$4" ]; then
+        size="`pngtopnm "$4" | sed -n -e '2p'`"
+        width_a="${size% *}"
+        height_a="${size#* }"
+        if [ $width_a -gt 800 ]; then
+            for file in "${1%.dot}".*; do
+                cp "$file" "$file.a"
+            done
+            sed -e 's/rankdir=LR/rankdir=TB/' -e t -e 's/rankdir=TB/rankdir=LR/' "$1.a" > "$1"
+            dot "$@"
+            size="`pngtopnm "$4" | sed -n -e '2p'`"
+            width_b="${size% *}"
+            height_b="${size#* }"
+            if [ $width_a -lt $width_b ]; then
+                for file in "${1%.dot}".*.a; do
+                mv "$file" "${file%.a}"
+                done
+            else
+                rm "${1%.dot}".*.a
+            fi
+        fi
+    fi
+    ;;
+    *)  ;;
+esac
diff --git a/site_scons/lib/dot-munge.pl b/site_scons/lib/dot-munge.pl
new file mode 100755 (executable)
index 0000000..263b44e
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/perl -i -n
+
+# Reduce fontsize and change font
+s/fontsize=10/fontsize=8/g; 
+s/fontname="FreeSans.ttf"/fontname="Verdana"/g;
+
+# Wrap long labels (templates and pathnames)
+if (/label=\"([^"]{48,})\"/) {                              #"])){ # To make emacs happy ...
+    $pre=$`; 
+    $post=$';                                               #';    # To make emacs happy ...
+    $label=$1;
+
+    # Break at each komma or /
+    $label=~s{[,/]}{$&\\r\\ \\ \\ \\ \\ \\ \\ \\ }g; 
+
+    # If more than one '<' is in the label, break after each '<'
+    if (($label=~tr/</</)>1) { 
+        $label=~s/</<\\r\\ \\ \\ \\ \\ \\ \\ \\ /g;
+    }
+
+    # If at least one break is in there ...
+    if ($label=~/\\r/) {
+    # If it's a pathname, make all but the last line flush left
+    # Otherwise only make first line flush left
+    if ($label=~m{/}) {
+        $label=~s/\\r(\\ )*/\\ \\ \\ \\ \\ \\ \\ \\ \\l/g;
+        # Re-add blanks before last line
+        $label=~s/^.*\\l/$&\\ \\ \\ \\ \\ \\ \\ \\ /;
+    } else {
+        $label=~s/\\r/\\ \\ \\ \\ \\ \\ \\ \\ \\l/;
+    }
+        # Make last line flush right
+        $label.="\\r";
+    }
+    print "${pre}label=\"${label}\"${post}";
+} else { 
+    print;
+}
diff --git a/site_scons/lib/doxy.css b/site_scons/lib/doxy.css
new file mode 100644 (file)
index 0000000..f21137e
--- /dev/null
@@ -0,0 +1,634 @@
+body {
+        padding: 0;
+        margin: 0;
+        font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 10pt;
+}
+
+/* Argh .. doxygen.css has font-size:90% for td ... */
+td {
+        font-size: 100%;
+}
+
+#head {
+        height: 62px;
+        border-top: 5px solid #DECD40;
+        border-bottom: 1px solid #AF9D00;
+        background-color: #EDE497;
+}
+
+#title { 
+        height: 39px;
+        background-color: #DECD40;
+        border-bottom: 1px solid #AF9D00;
+        margin: 0 0 0 0;
+}
+
+#title2 {
+        padding: 0 0 0 142px;
+        max-width: 62em;
+        margin: 0 10px 0 0;
+}
+
+#head h1 {
+        margin: 0;
+        padding: 6px 0 0 0;
+        font-size: 22px;
+        font-weight: bold;
+        color: white;
+        white-space: nowrap;
+        text-align: left;
+}
+
+#subtitle {
+        margin: 0 10px 0 0px;
+        padding: 4px 0 0 142px;
+        height: 18px;
+        max-width: 62em;
+        background-color: #EDE497;
+        color: #726921;
+}
+
+#head h2 {
+        margin: 0;
+        padding: 0;
+        font-size: 13px;
+        font-weight: normal;
+        white-space: nowrap;
+}
+
+#head ul { 
+        display: inline; /* fuer IE ... */
+        font-size: 13px;
+        height: 0px;
+        margin: 0;
+        padding: 0;
+}
+
+#head li { 
+        list-style-type: none;
+        margin: 0 10px 0 0;
+        padding: 0 0 0 10px;
+        float: left;
+        border-left: 1px solid #726921;
+        height: 14px;
+}
+
+#head li:first-child { 
+        border-left: none;
+        padding: 0;
+}
+
+#head a { 
+        font-weight: normal;
+        color: #726921;
+}
+
+#head a:hover { 
+        background-color: #EDE497;
+        text-decoration: underline;
+}
+
+#search {
+        float: right;
+        width: 150px;
+        height: 39px;
+        font-size: 10px;
+        color: #726921;
+}
+
+#search input { 
+        display: block;
+        height: 16px;
+        border: 1px solid #AF9D00;
+        width: 100%;
+}
+
+#search form { 
+        margin: 0;
+        padding: 0;
+}
+
+#content1 {
+        padding: 0 10px 10px 0;
+        border-bottom: 1px solid #AF9D00;
+}
+
+#content2 {
+        /* need non-zero top padding here to prevent margin propagation */
+        padding: 10px 0 0 142px;
+        max-width: 62em;
+}
+
+a {
+        font-weight: bold;
+        text-decoration: none;
+}
+
+a.literal {
+        font-weight: normal;
+}
+
+a.ext {
+        font-style: italic;
+}
+
+a.anchor { 
+        color: inherit;
+        background-color: white !important;
+}
+
+div.tabs {
+        display: inline; /* IE double margin fix */
+        float: left;
+        clear: left;
+        background-color: #FDF7C3;
+        border: 1px solid #AF9D00;
+        margin: 0 0 10px -132px;
+        width: 120px;
+        overflow: hidden;
+}
+
+* html div.tabs {
+        margin-bottom: 0; /* Grmpf .. IE6 is f**ing up ... */
+}
+
+div.tabs ul {
+        margin: 0;
+        padding: 0;
+        list-style-type: none;
+}
+
+div.tabs ul li {
+        display: inline;
+}
+
+div.tabs ul li a {
+        display: block;
+        padding: 2px 5px;
+        font-size: 13px;
+        color: #726921;
+        text-decoration: none;
+        white-space: nowrap;
+        font-weight: normal;
+}
+
+div.tabs ul li a:visited, div.tabs ul li a:active {
+        color: #726921;
+        text-decoration: none;
+}
+
+div.tabs li.current a {
+        background-position: 100% -150px;
+        border-width: 0px;
+}
+
+div.tabs li.current span {
+        background-position: 0% -150px;
+        padding-bottom: 6px;
+}
+
+div.tabs ul li a:hover, div.tabs ul li.current a, div.tabs ul.glossary li a:hover {
+        color: #726921;
+        text-decoration: none;
+        background-color: #EDE497;
+}
+
+div.tabs ul li.level1 a {
+        padding-left: 1.5em;
+        font-size: 90%;
+}
+
+div.tabs ul.glossary li a {
+        background-color: #FDF7C3;
+}
+
+div.tabs ul.glossary li.glossary a {
+        background-color: #EDE497;
+}
+
+#footer {
+        clear: both;
+        padding: 4px 10px 4px 142px;
+        color: #726921;
+        white-space: nowrap;
+        text-align: right;
+        max-width: 62em;
+}
+
+#footer span {
+        font-size: 10px;
+}
+
+#footer a, #footer a:active, #footer a:visited {
+        color: #726921;
+        text-decoration: none;
+}
+
+#footer a:hover {
+        background-color: inherit;
+        text-decoration: underline;
+}
+
+dl.attention {
+        border: 1px solid #AADD88;
+        background-color: #EEFFDD;
+        padding: 4px;
+}
+
+dl.warning {
+        border: 1px solid #DDAA88;
+        background-color: #FFEEDD;
+        padding: 4px;
+}
+
+dl.note {
+        border: 1px solid A0C2C2;
+        background-color: #F0F8F8;
+        padding: 4px;
+}
+table.packet {
+        width: 95%;
+        margin: 10pt auto;
+        border: 1px solid #AAAAAA;
+        padding: 2px;
+        border-spacing: 0;
+        white-space: nowrap;
+        text-align: center;
+        table-layout: fixed; 
+}
+
+table.packet td,th {
+        border: 2px solid white;
+        background-color: #EEEEEE;
+        padding: 6px 4px;
+}
+
+table.packet th {
+        background-color: white;
+        text-align: left;
+        font-weight: normal;
+        padding: 0px;
+}
+
+table.senf {
+        width: 95%;
+        margin: 10pt auto;
+        border: 1px solid #AAAAAA;
+        padding: 2px;
+        border-spacing: 0;
+}
+
+table.senf td,th {
+        border: 2px solid white;
+        background-color: #EEEEEE;
+        padding: 2px 4px;
+        text-align: left;
+        vertical-align: top;
+}
+
+table.senf th {
+        background-color: #DDDDDD;
+        text-align: center;
+        font-weight: bold;
+}
+
+table.fields {
+        width: 95%;
+        margin: 10pt auto;
+        border: 1px solid #AAAAAA;
+        padding: 2px;
+        border-spacing: 0;
+}
+
+table.fields td,th {
+        border: 2px solid white;
+        background-color: #EEEEEE;
+        padding: 2px 4px;
+        text-align: left;
+        vertical-align: top;
+}
+
+table.fields th {
+        background-color: #DDDDDD;
+        text-align: center;
+        font-weight: bold;
+}
+
+table.fields td:first-child {
+        width: 25%;
+        font-style: italic;
+}
+
+table.fixedcolumn td:first-child {
+        width: 35%; 
+}
+
+table.ebnf {
+        margin: 0;
+        padding: 0;
+        border-spacing: 0;
+        border: none;
+}
+
+table.ebnf td {
+        text-align: left;
+        border: none;
+        padding: 0;
+}
+
+table.ebnf td:first-child {
+        width: 1%;
+        padding-right: 1ex;
+        font-style: italic;
+}
+
+table.listing {
+        margin: 10pt 0;
+        padding: 0;
+        border-spacing: 0;
+        border: none;
+}
+
+table.listing td {
+        text-align: left;
+        vertical-align: top;
+        border: none;
+        padding: 0 0 3pt 0;
+}
+
+table.listing td:first-child {
+        width: 35%;
+}
+
+dl.xref-bug, dl.xref-fix, dl.xref-todo, dl.xref-idea {
+        border: 1px solid #CC8888;
+        padding: 2px 3px;
+        margin: 4px 8px 4px 2px;
+        background-color: #FFEEEE;
+        color: #666666;
+        font-size: 75%;
+        overflow: hidden;
+}
+
+dl.xref-bug dt, dl.xref-fix dt, dl.xref-todo dt, dl.xref-idea dt,
+dl.xref-bug dd, dl.xref-fix dd, dl.xref-todo dd, dl.xref-idea dd {
+        display: inline;
+        margin: 0;
+        padding: 0;
+}
+
+dl.xref-bug a, dl.xref-fix a, dl.xref-todo a, dl.xref-idea a {
+        color: #6666FF;
+}
+
+dl.xref-fix {
+        border-color: #CCCC88;
+        background-color: #FFFFEE;
+}
+
+dl.xref-todo {
+        border-color: #88CC88;
+        background-color: #EEFFEE;
+}
+
+dl.xref-idea {
+        border-color:  #CCCCCC;
+        background-color: #F8F8F8;
+}
+
+div.bug, div.fixme, div.todo, div.idea { 
+        padding-left: 10px;
+}
+
+div.bug { 
+        border-left: 10px solid red;
+}
+
+div.fixme { 
+        border-left: 10px solid yellow;
+}
+
+div.todo { 
+        border-left: 10px solid green;
+}
+
+div.idea { 
+        border-left: 10px solid #AAAAAA;
+}
+
+dl.implementation {
+        color: #666666;
+        font-size: 75%;
+}
+
+p.memtitle {
+        color: #1a41a8;
+        font-weight: bold;
+        margin-right: 14px;
+        border-bottom: 1px solid #84b0c7;
+}
+
+p.sourceline, p.references, p.referencedby, p.reimplementedfrom, p.reimplementedin, 
+p.implementedin {
+        color: #666666;
+        font-size: 75%;
+        margin-bottom: .2em;
+        margin-top: .2em;
+}
+
+div.memdoc p.sourceline, p.references, p.referencedby, p.reimplementedfrom, p.reimplementedin, 
+p.implementedin {
+        margin-left: 10em;
+        text-indent: -4em;
+}
+
+div.memproto {
+        margin-bottom: .5em;
+}
+
+table {
+        width: 100%;
+}
+
+div.ah {
+        margin-right: 10px;
+}
+
+div.nav, div.navpath {
+        width: auto;
+        background-color: white;
+        border: none;
+        border-bottom: 1px solid #AF9D00;
+        padding: 5px 0;
+        margin: 0;
+}
+
+div.qindex {
+        width: auto;
+        background-color: #e8eef2;
+        border: 1px solid #84b0c7;
+        text-align: center;
+        margin: 2px 0;
+        padding: 2px;
+        line-height: 140%;
+}
+
+table.qindextable {
+        font-size: 90%;
+}
+
+table.qindextable td {
+        width: 33%;
+}
+
+dl.parameters dd table {
+        width: auto;
+}
+
+table.glossary {
+        border: none;
+        border-spacing: 0;
+        margin: 10px 0;
+}
+
+table.glossary tr td {
+        border: none;
+        border-bottom: 4px solid white;
+        vertical-align: top;
+        padding: 2px 4px;
+        background-color: #F0F0F0;
+}
+
+table.glossary tr td:first-child {
+        font-weight: bold;
+        white-space: nowrap;
+        padding-right: 10px;
+}
+
+table.members td:first-child {
+        width: 35%;
+}
+
+div.toc {
+        width: 25%;
+        margin: 10px 0px;
+}
+
+div.toc ol {
+        padding: 0px;
+        margin: 0pt 0pt 0pt 40px;
+        list-style-type: decimal;
+}
+
+div.toc li {
+        padding: none;
+}
+
+div.toc div {
+        margin: 10px 0px;
+        font-weight: bold;
+        font-size: 120%;
+}
+
+p.commalist {
+        white-space: nowrap;
+        margin-left: 4em;
+        text-indent: -4em;
+}
+
+#autotoc {
+        width: 30em;
+        background-color: #F5F5F5;
+        border: 1px solid #CCC;
+        padding: 0 1em;
+        margin: 1em 0;
+}
+
+#autotoc h1 {
+        font-size: 120%;
+        text-align: left;
+}
+
+#autotoc ul {
+        list-style-type: none;
+        padding: 0;
+        margin: 1em 0 1em 1em;
+}
+
+#autotoc li {
+        padding: 0 0 0 3em;
+        text-indent: -3em;
+}
+
+#autotoc ul li.level_h2 {
+        margin: .5em 0 .2em 0;
+}
+
+#autotoc ul li.level_h3 {
+        margin-left: 1.5em;
+}
+
+#autotoc ul li.level_h4 {
+        margin-left: 3em;
+}
+
+h4 {
+        font-size: 100%;
+        margin-bottom: .4em;
+}
+
+table.memname {
+        width: 100%; 
+        font-weight: normal; 
+        white-space: normal;
+}
+
+table.memname td {
+        vertical-align: top;
+}
+
+table.memname td.memtype {
+        width: 100%;
+}
+
+table.memname td.memname {
+        width: 35%; 
+        text-align: right; 
+        font-weight: bold;
+}
+
+table.memname td.memparen {
+        width: 1%;
+}
+
+table.memname td.paramtype {
+        width: 30%; 
+        text-align: right;
+}
+
+table.memname td.paramname {
+        width: 33%;
+}
+
+table.memname td.memattrs {
+        text-align: right;
+}
+
+table.memname.macro td.paramtype {
+        text-align: left;
+       color: #602020;
+        font-style: italic;
+}
+
+table.memname.macro td.memattrs {
+        display: none;
+}
+
+/* \f
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * ispell-local-dictionary: "american"
+ * End:
+ */
diff --git a/site_scons/lib/doxyfooter.yap b/site_scons/lib/doxyfooter.yap
new file mode 100644 (file)
index 0000000..f714e10
--- /dev/null
@@ -0,0 +1,10 @@
+<hr style="width:0px;border:none;clear:both;margin:0;padding:0" />
+  </div>
+</div>
+<div id="footer">
+  <span>
+    <a href="mailto:${PROJECTEMAIL}">Contact: ${PROJECTEMAIL}</a> |
+    Copyright &copy; ${COPYRIGHT}
+  </span>
+</div>
+</body></html>
diff --git a/site_scons/lib/doxygen.sh b/site_scons/lib/doxygen.sh
new file mode 100755 (executable)
index 0000000..958a87b
--- /dev/null
@@ -0,0 +1,206 @@
+#!/bin/bash -e
+
+do_html_cleanup()
+{
+    sed -e 's/id="current"/class="current"/' \
+       | tidy -ascii -q --wrap 0 --show-warnings no --fix-uri no \
+       | sed -e 's/name="\([^"]*\)"\([^>]*\) id="\1"/name="\1"\2/g' \
+       | xsltproc --novalid --nonet --html --stringparam topdir "$reltopdir" \
+             "$base/html-munge.xsl" -
+}
+
+###########################################################################
+
+# Build absolute, normalized pathname
+abspath()
+{
+    case "$1" in
+       /*) echo "$1" ;;
+       *) echo "`pwd`/$1" ;;
+    esac | sed \
+       -e 's/\/\/*/\//g' \
+       -e:a \
+       -e 's/\/\.\(\/\|$\)/\1/g' \
+       -eta \
+       -e:b \
+       -e 's/\/[^\/]*\/..\(\/\|$\)/\1/' \
+       -etb \
+        -e 's/^\(\/..\)*\(\/\|$\)/\2/' \
+       -e 's/^$/\//'
+}
+
+# Create relative path from absolute directory $1 to absolute path $2
+relpath()
+{
+    local src="${1#/}"
+    local dst="${2#/}"
+    while true; do
+       if [ -z "$src" -a -z "$dst" ]; then
+           echo "Internal error in relpath()" 1>&2
+           exit 1
+       fi
+       srcd="${src%%/*}"
+       dstd="${dst%%/*}"
+       if [ "$srcd" = "$dstd" ]; then
+           src="${src#$srcd}"; src="${src#/}"
+           dst="${dst#$dstd}"; dst="${dst#/}"
+       else
+           break
+       fi
+    done
+    rel="`echo "$src" | sed -e "s/[^\/]*/../g"`/$dst" # `"
+    echo "${rel%/}"
+}
+
+# Log executed commands
+cmd()
+{
+    echo "+" "$@"
+    "$@"
+}
+
+html_cleanup()
+{
+    mv "$1" "${1}.orig"
+    do_html_cleanup <"${1}.orig" >"$1"
+}
+
+###########################################################################
+
+name="`basename "$0"`"; #`"
+base="`dirname "$0"`"; base="`cd "$base"; pwd`" #`"
+LIBDIR="$base"
+
+TEMP=`getopt -n $name -o '' -l html,tagfile,tagfile-name:,tagfiles:,output-dir:,html-dir:  -- "$@"`
+if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
+eval set -- "$TEMP"
+
+tagxsl="$base/tag-munge.xsl"
+
+html="NO"; tagfile="NO"; tagfile_name=""; tagfiles=""; output_dir="doc"; html_dir="html"
+
+while true; do
+    case "$1" in
+       --html)
+           html="YES" ; shift ;;
+       --tagfile)
+           tagfile="YES" ; shift ;;
+       --tagfile-name)
+           tagfile_name="$2"; shift 2 ;;
+       --tagfiles)
+           for f in $2; do
+               f="`abspath "$f"`" #`"
+               tagfiles="$tagfiles${tagfiles:+ }$f"
+           done
+           shift 2
+           ;;
+       --output-dir)
+           output_dir="$2"; shift 2 ;;
+       --html-dir)
+           html_dir="$2"; shift 2 ;;
+       --)
+           shift; break ;;
+       *)
+           echo "Internal error: $*"; exit 1 ;;
+    esac
+done
+
+if [ -z "$1" ]; then
+    cat <<EOF
+Usage:
+    $name
+        [--html]
+        [--tagfile]
+        [--tagfile-name=<name>]
+        [--tagfiles=<files>]
+        [--output-dir=<dir>]
+        [--html-dir=<dir>]
+            <doxyfile-or-dir>
+EOF
+    exit 1
+fi
+
+if [ "$tagfile" = "YES" -a -z "$tagfile_name" ]; then
+    echo "--tagfile-name is required with --tagfile"
+    exit 1
+fi
+
+doxydir="$1"
+
+if [ -f "$doxydir" ]; then
+    doxydir="`dirname "$doxydir"`" #`"
+fi
+
+doxydir="`abspath "$doxydir"`" #`"
+
+###########################################################################
+
+## Find $TOPDIR
+
+cd "$doxydir"
+while [ ! -r "SConstruct" -a "`pwd`" != "/" ]; do cd ..; done
+if [ ! -r "SConstruct" ]; then
+    echo "topdir not found"
+    exit 1;
+fi
+TOPDIR="`pwd`";
+reltopdir="`relpath "$doxydir/$output_dir/$html_dir" "$TOPDIR"`" #`"
+cd "$doxydir"
+
+
+## Remove tagfile_name from list of tagfiles
+
+if [ -n "$tagfile_name" ]; then
+    tagfile_name="`abspath "$output_dir/$tagfile_name"`" #`"
+    x="$tagfiles"; tagfiles=""
+    for f in $x; do
+       if [ "$f" != "$tagfile_name" ]; then
+           tagfiles="$tagfiles${tagfiles:+ }$f"
+       fi
+    done
+fi
+
+## Call doxygen proper
+
+generate_tagfile=""
+if [ "$tagfile" = "YES" ]; then
+    generate_tagfile="$tagfile_name"
+fi
+export TOPDIR LIBDIR html tagfile tagfile_name tagfiles output_dir html_dir generate_tagfile
+
+cmd ${DOXYGEN:-doxygen}
+
+
+## Clean up tagfile, if generated
+
+if [ "$tagfile" = "YES" ]; then
+    mv "$tagfile_name" "${tagfile_name}.orig"
+    cmd xsltproc --novalid --nonet -o "$tagfile_name" "$tagxsl" "${tagfile_name}.orig"
+fi
+
+
+## Call installdox
+
+if [ -n "$tagfiles" ]; then
+    args=""
+    for f in $tagfiles; do
+       n="`basename "$f"`" #`"
+       d="`dirname "$f"`" #`"
+       url="`relpath "$doxydir/$output_dir/$html_dir" "$d/$html_dir"`" #`"
+       args="$args${args:+ }-l $n@$url"
+    done
+
+    (
+       cd "./$output_dir/$html_dir"
+       cmd "./installdox" $args
+    )
+fi
+
+
+## Postprocess html files, if generated
+
+if [ "$html" = "YES" ]; then
+    for h in "$doxydir/$output_dir/$html_dir"/*.html; do
+       cmd html_cleanup "$h"
+    done
+fi
diff --git a/site_scons/lib/doxyheader.yap b/site_scons/lib/doxyheader.yap
new file mode 100644 (file)
index 0000000..22ed25a
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>$title</title>
+<link href="@TOPDIR@/doc/html/doxygen.css" rel="stylesheet" type="text/css">
+<link href="@TOPDIR@/doc/doxy.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+<div id="head">
+  <div id="title">
+    <div id="title2">
+      <h1>${PROJECTNAME}</h1>
+    </div>
+  </div>
+  <div id="subtitle">
+    <ul>
+      <li><a href="index.html">Home</a></li>
+{{    for name, target in DOCLINKS:
+        <li><a href="${target}">${name}</a></li>
+}}
+    </ul>
+  </div>
+</div>
+
+<div id="content1">
+  <div id="content2">
diff --git a/site_scons/lib/filter.pl b/site_scons/lib/filter.pl
new file mode 100755 (executable)
index 0000000..14ad930
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/perl -n
+
+BEGIN {
+    ($topdir=$0) =~ s{doclib/.*$}{};
+    print $topdir,"\n";
+}
+
+s/\s*$//;
+while (s/\t/' 'x(8-length($`)%8)/e) {}
+
+if (/^\s*\\code$/ .. /\\endcode/ && !/^$/) {
+    $i=length($1) if /^(\s*)\\code$/;
+    print substr($_,$i),"\n";
+} 
+elsif (s/^(\s*)<pre>$/$1<pre class="fragment">/ .. /<\/pre>/ && !/^$/) {
+    $i=length($1) if /^(\s*)<pre class="fragment">$/;
+    print substr($_,$i),"\n";
+} 
+else {
+    print $_,"\n";
+}
diff --git a/site_scons/lib/html-munge.xsl b/site_scons/lib/html-munge.xsl
new file mode 100644 (file)
index 0000000..5b35045
--- /dev/null
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<xsl:stylesheet version="1.0"\r
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+  xmlns:str="http://exslt.org/strings"\r
+  xmlns:set="http://exslt.org/sets"\r
+  xmlns:exslt="http://exslt.org/common"\r
+  extension-element-prefixes="str">\r
+\r
+  <xsl:output \r
+    method="html" \r
+    encoding="html" \r
+    doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"\r
+    doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>\r
+\r
+  <xsl:param name="topdir" select="''"/>\r
+  \r
+  <xsl:template match="*" name="copy">\r
+    <xsl:copy>\r
+      <xsl:call-template name="copy-attributes"/>\r
+      <xsl:apply-templates/>\r
+    </xsl:copy>\r
+  </xsl:template>\r
+\r
+  <xsl:template name="copy-attributes">\r
+    <xsl:for-each select="@*">\r
+      <xsl:attribute name="{name(current())}">\r
+        <xsl:choose>\r
+          <xsl:when test="contains(current(),'@TOPDIR@')">\r
+            <xsl:value-of select="substring-before(current(),'@TOPDIR@')"/>\r
+            <xsl:value-of select="$topdir"/>\r
+            <xsl:value-of select="substring-after(current(),'@TOPDIR@')"/>\r
+          </xsl:when>\r
+          <xsl:otherwise>\r
+            <xsl:value-of select="current()"/>\r
+          </xsl:otherwise>\r
+        </xsl:choose>\r
+      </xsl:attribute>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+\r
+  <!-- Replace @TOPDIR@ with relative top directory path -->\r
+\r
+  <xsl:template match="@*[contains(current(),'@TOPDIR@')]">\r
+    <xsl:value-of select="substring-before(current(),'@TOPDIR@')"/>\r
+    <xsl:value-of select="$topdir"/>\r
+    <xsl:value-of select="substring-after(current(),'@TOPDIR@')"/>\r
+  </xsl:template>\r
+  \r
+  <!-- Add 'class' attribute  -->\r
+  \r
+  <xsl:template name="add-class">\r
+    <xsl:param name="class"/>\r
+    <xsl:copy>\r
+      <xsl:call-template name="copy-attributes"/>\r
+      <xsl:attribute name="class"><xsl:value-of select="$class"/></xsl:attribute>\r
+      <xsl:apply-templates/>\r
+    </xsl:copy>\r
+  </xsl:template>\r
+\r
+  <!-- Add '<br/>' tag after every ', ' -->\r
+  <!-- This code is not very robust, it works with the doxygen output though -->\r
+\r
+  <xsl:template name="break-comma">\r
+    <xsl:copy>\r
+      <xsl:call-template name="copy-attributes"/>\r
+      <xsl:attribute name="class">commalist</xsl:attribute>\r
+      <xsl:apply-templates mode="break-comma"/>\r
+    </xsl:copy>\r
+  </xsl:template>\r
\r
+  <xsl:template match="text()[1]" mode="break-comma">\r
+    <xsl:value-of select="current()"/><br/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="*" mode="break-comma">\r
+    <xsl:call-template name="copy"/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="text()[contains(current(),' and') or contains(current(),'and ')]" mode="break-comma" priority="1">\r
+    <xsl:value-of select="substring-before(current(),'and')"/>\r
+    <br/>\r
+    <xsl:value-of select="substring-after(current(),'and')"/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="text()[contains(current(),',')]" mode="break-comma">\r
+    <xsl:value-of select="substring-before(current(),',')"/>\r
+    <xsl:text>,</xsl:text><br/>\r
+    <xsl:value-of select="substring-after(current(),',')"/>\r
+  </xsl:template>\r
+\r
+  <!-- ====================================================================== -->\r
+\r
+  <!-- Hack Glossary menu highlight -->\r
+\r
+  <xsl:template match="div[@class='tabs menu']/ul[1]">\r
+    <xsl:choose>\r
+      <xsl:when test="//h1[.//text()='Glossary']">\r
+        <xsl:call-template name="add-class">\r
+          <xsl:with-param name="class">glossary</xsl:with-param>\r
+        </xsl:call-template>\r
+      </xsl:when>\r
+      <xsl:otherwise>\r
+        <xsl:copy>\r
+          <xsl:call-template name="copy-attributes"/>\r
+          <xsl:apply-templates/>\r
+        </xsl:copy>\r
+      </xsl:otherwise>\r
+    </xsl:choose>\r
+  </xsl:template>\r
+\r
+  <!-- Autogenerate table-of-contents for a page -->\r
+\r
+  <xsl:template match="div[@id='autotoc']">\r
+    <xsl:copy>\r
+      <xsl:call-template name="copy-attributes"/>\r
+      <h1>Contents</h1>\r
+      <ul>\r
+        <xsl:for-each select="following::h2|following::h3|following::h4">\r
+          <xsl:element name="li">\r
+            <xsl:attribute name="class">\r
+              <xsl:value-of select="concat('level_',local-name())"/>\r
+            </xsl:attribute>\r
+            <b><xsl:call-template name="section-number"/><xsl:text> </xsl:text></b>\r
+            <xsl:element name="a">\r
+              <xsl:choose>\r
+                <xsl:when test="a/@name">\r
+                  <xsl:attribute name="href">\r
+                    <xsl:value-of select="concat('#',a/@name)"/>\r
+                  </xsl:attribute>\r
+                </xsl:when>\r
+                <xsl:otherwise>\r
+                  <xsl:attribute name="href">\r
+                    <xsl:text>#autotoc-</xsl:text>\r
+                    <xsl:call-template name="section-number"/>\r
+                  </xsl:attribute>\r
+                </xsl:otherwise>\r
+              </xsl:choose>\r
+              <xsl:value-of select="string(current())"/>\r
+            </xsl:element>\r
+          </xsl:element>\r
+        </xsl:for-each>\r
+      </ul>\r
+    </xsl:copy>\r
+  </xsl:template>\r
+\r
+  <xsl:template name="section-number">\r
+    <xsl:number level="any" from="div[@id='autotoc']" count="h2"/>\r
+    <xsl:text>.</xsl:text>\r
+    <xsl:if test="self::h3|self::h4">\r
+      <xsl:number level="any" from="h2" count="h3"/>\r
+      <xsl:text>.</xsl:text>\r
+    </xsl:if>\r
+    <xsl:if test="self::h4">\r
+      <xsl:number level="any" from="h3" count="h4"/>\r
+      <xsl:text>.</xsl:text>\r
+    </xsl:if>\r
+  </xsl:template>\r
+  \r
+  <xsl:template match="h2|h3|h4">\r
+    <xsl:copy>\r
+      <xsl:call-template name="copy-attributes"/>\r
+      <xsl:choose>\r
+        <xsl:when test="preceding::div[@id='autotoc']">\r
+          <xsl:call-template name="section-number"/>\r
+          <xsl:text> </xsl:text>\r
+          <xsl:choose>\r
+            <xsl:when test="a">\r
+              <xsl:apply-templates/>\r
+            </xsl:when>\r
+            <xsl:otherwise>\r
+              <xsl:element name="a">\r
+                <xsl:attribute name="class"><xsl:text>anchor</xsl:text></xsl:attribute>\r
+                <xsl:attribute name="name">\r
+                  <xsl:text>autotoc-</xsl:text>\r
+                  <xsl:call-template name="section-number"/>\r
+                </xsl:attribute>\r
+                <xsl:apply-templates/>\r
+              </xsl:element>\r
+            </xsl:otherwise>\r
+          </xsl:choose>\r
+        </xsl:when>\r
+        <xsl:otherwise>\r
+          <xsl:apply-templates/>\r
+        </xsl:otherwise>\r
+      </xsl:choose>\r
+    </xsl:copy>\r
+  </xsl:template>\r
+\r
+  <!-- Build dia image-map from special div/span elements -->\r
+  <xsl:template match="div[@class='diamap']">\r
+    <xsl:element name="map">\r
+      <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>\r
+      <xsl:for-each select="span">\r
+        <xsl:if test="a">\r
+          <xsl:variable name="name" select="string(a[1])"/>\r
+          <xsl:element name="area">\r
+            <xsl:attribute name="shape">rect</xsl:attribute>\r
+            <xsl:attribute name="alt"><xsl:value-of select="$name"/></xsl:attribute>\r
+            <xsl:attribute name="title"><xsl:value-of select="$name"/></xsl:attribute>\r
+            <xsl:attribute name="href"><xsl:value-of select="a[1]/@href"/></xsl:attribute>\r
+            <xsl:attribute name="coords"><xsl:value-of select="@coords"/></xsl:attribute>\r
+          </xsl:element>\r
+        </xsl:if>\r
+      </xsl:for-each>\r
+    </xsl:element>\r
+  </xsl:template>\r
+\r
+  <!-- Reformat detailed member documentation -->\r
+\r
+  <xsl:template match="table[@class='memname']">\r
+    <xsl:variable name="name1"><xsl:value-of select="str:split(tr/td[@class='memname'],'::')[position()=last()]"/></xsl:variable>\r
+    <xsl:variable name="name2"><xsl:value-of select="str:split(tr/td[@class='memname'],' ')[position()=last()]"/></xsl:variable>\r
+    <xsl:variable name="name"><xsl:value-of select="substring($name1,string-length($name1)-string-length($name2))"/></xsl:variable>\r
+    <xsl:element name="table">\r
+      <xsl:attribute name="class">\r
+        <xsl:text>memname</xsl:text>\r
+        <xsl:if test="contains(tr/td[@class='memname'],'#define')"><xsl:text> macro</xsl:text></xsl:if>\r
+      </xsl:attribute>\r
+      <tr>\r
+        <td class="memtype" colspan="5">\r
+          <xsl:for-each select="tr/td[@class='memname']/*|tr/td[@class='memname']/text()">\r
+            <xsl:choose>\r
+              <xsl:when test="position()=last()">\r
+                <xsl:value-of select="substring(.,1,string-length(.)-string-length($name))"/>\r
+              </xsl:when>\r
+              <xsl:otherwise>\r
+                <xsl:copy-of select="."/>\r
+              </xsl:otherwise>\r
+            </xsl:choose>\r
+          </xsl:for-each>\r
+        </td>\r
+      </tr>\r
+\r
+      <xsl:choose>\r
+        <xsl:when test="tr/td[@class='paramtype']">\r
+          <tr>\r
+            <td class="memname"><xsl:copy-of select="$name"/></td>\r
+            <td class="memparen">(</td>\r
+            <xsl:copy-of select="tr[1]/td[@class='paramtype']"/>\r
+            <xsl:copy-of select="tr[1]/td[@class='paramname']"/>\r
+            <td class="memparen"><xsl:if test="not(tr[td[@class='paramkey']])">)</xsl:if></td>\r
+          </tr>\r
+\r
+          <xsl:for-each select="tr[td[@class='paramkey']]">\r
+            <tr>\r
+              <td class="memname"></td>\r
+              <td class="memparen"></td>\r
+              <xsl:copy-of select="td[@class='paramtype']"/>\r
+              <xsl:copy-of select="td[@class='paramname']"/>\r
+              <td class="memparen"><xsl:if test="position()=last()">)</xsl:if></td>\r
+            </tr>\r
+          </xsl:for-each>\r
+        </xsl:when>\r
+        <xsl:otherwise>\r
+          <tr>\r
+            <td class="memname"><xsl:copy-of select="$name"/></td>\r
+            <td class="memparen"><xsl:if test="tr/td[.='(']">()</xsl:if></td>\r
+            <td class="paramtype"></td>\r
+            <td class="paramname"></td>\r
+            <td class="memparen"></td>\r
+          </tr>\r
+        </xsl:otherwise>\r
+      </xsl:choose>\r
+      <tr>\r
+        <td colspan="5" class="memattrs"><xsl:copy-of select="tr/td[@width='100%']/*|tr/td[@width='100%']/text()"/></td>\r
+      </tr>\r
+    </xsl:element>\r
+  </xsl:template>\r
+\r
+  <!-- no idea, where these &nbsp;'s come frome ... -->\r
+  <xsl:template match="div[@class='memproto']/text()[.='&#160;&#x0a;']">\r
+  </xsl:template>\r
+\r
+  <!-- Add grouping to all-members page -->\r
+\r
+  <xsl:template match="table[preceding-sibling::h1[1][contains(text(),'Member List')]]">\r
+    <table class="allmembers">\r
+\r
+      <!-- We need to filter the table rows by looking for indications on the object type       -->\r
+      <!-- The table has 3 acolumns:                                                            -->\r
+      <!--    td[1] is the name of the object,                                                  -->\r
+      <!--    td[2] is the name of the class the object is defined in                           -->\r
+      <!--    td[3] contains additional flags                                                   -->\r
+      <!--                                                                                      -->\r
+      <!-- The conditions we have are:                                                          -->\r
+      <!--                                                                                      -->\r
+      <!--    contains(td[3],'static')        static member (variable or function)              -->\r
+      <!--    contains(td[3],'protected')     protected member of arbitrary type                -->\r
+      <!--    contains(td[3],'private')       private member of arbitrary type                  -->\r
+      <!--    contains(td{3],'friend')        friend declaration (function or class)            -->\r
+      <!--    contains(td[3],'pure virtual')  entry is a pure-virtual member function           -->\r
+      <!--    starts-with(td[1]/text(),'(')   function entry (member, static or friend)         -->\r
+      <!--    contains(td[1], 'typedef')      entry is a typdef                                 -->\r
+      <!--    contains(td[1], 'enum ')        entry is enum type or enumerator                  -->\r
+      <!--    contains(td[1], 'enum name')    entry is the name of an enum type                 -->\r
+      <!--    contains(td[1], 'enum value')   entry is an enumerator value                      -->\r
+      <!--    str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]==string(td[1]/a) -->\r
+      <!--                                    entry is a constructor                            -->\r
+      <!--    not(starts-with(td[1]/a,'~'))   entry is a destructor                             -->\r
+\r
+      <xsl:variable name="public-static-memfn">\r
+        <xsl:apply-templates select="tr[contains(td[3],'static')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))][starts-with(td[1]/text(),'(')]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-static-memfn)">\r
+        <tr><td colspan="3"><h2>Static Public Member Functions</h2></td></tr>\r
+        <xsl:copy-of select="$public-static-memfn"/>\r
+      </xsl:if>\r
+\r
+      <xsl:variable name="public-static-var">\r
+        <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][contains(td[3],'static')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(starts-with(td[1]/text(),'('))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-static-var)">\r
+        <tr><td colspan="3"><h2>Static Public Attributes</h2></td></tr>\r
+        <xsl:copy-of select="$public-static-var"/>\r
+      </xsl:if>\r
+      \r
+      <xsl:variable name="public-memfn">\r
+        <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][not(contains(td[3],'static'))][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))][starts-with(td[1]/text(),'(')][str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]!=string(td[1]/a)][not(starts-with(td[1]/a,'~'))][not(contains(td[3],'pure virtual'))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-memfn)">\r
+        <tr><td colspan="3"><h2>Public Member Functions</h2></td></tr>\r
+        <xsl:copy-of select="set:distinct(exslt:node-set($public-memfn)/tr)"/>\r
+      </xsl:if>\r
+\r
+      <xsl:variable name="public-var">\r
+        <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][not(contains(td[1],'enum '))][not(contains(td[3],'static'))][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(starts-with(td[1]/text(),'('))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-var)">\r
+        <tr><td colspan="3"><h2>Public Attributes</h2></td></tr>\r
+        <xsl:copy-of select="$public-var"/>\r
+      </xsl:if>\r
+      \r
+      <xsl:variable name="public-enum">\r
+        <xsl:apply-templates select="tr[contains(td[1],'enum value')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-enum)">\r
+        <tr><td colspan="3"><h2>Public Enumerators</h2></td></tr>\r
+        <xsl:copy-of select="$public-enum"/>\r
+      </xsl:if>\r
+      \r
+      <xsl:variable name="public-type">\r
+        <xsl:apply-templates select="tr[contains(td[1],'typedef') or contains(td[1],'enum name')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($public-type)">\r
+        <tr><td colspan="r"><h2>Public Types</h2></td></tr>\r
+        <xsl:copy-of select="$public-type"/>\r
+      </xsl:if>\r
+      \r
+      <xsl:variable name="non-public">\r
+        <xsl:apply-templates select="tr[contains(td[3],'protected') or contains(td[3],'private') or contains(td[3],'friend')][str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]!=string(td[1]/a)][not(starts-with(td[1]/a,'~'))][not(contains(td[3],'pure virtual'))]"/>\r
+      </xsl:variable>\r
+      <xsl:if test="string($non-public)">\r
+        <tr><td colspan="3"><h2>Non-Public Members</h2></td></tr>\r
+        <xsl:copy-of select="$non-public"/>\r
+      </xsl:if>\r
+\r
+    </table>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="table[preceding-sibling::h1[1][contains(text(),'Member List')]]/tr/td[2]/a/text()[contains(.,'&lt;')]">\r
+    <!-- this removes the template args form the second column to make the table more compact -->\r
+    <xsl:value-of select="substring-before(.,'&lt;')"/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="table[preceding-sibling::h1[1][contains(text(),'Member List')]]/tr/td[1]/a/text()[contains(.,'::')]">\r
+    <!-- for some weird reason, some members have a fully qualified name in the first column -->\r
+    <!-- remove the qualification here -->\r
+    <xsl:value-of select="str:split(.,'::')[position()=last()]"/>\r
+  </xsl:template>\r
+\r
+  <!-- Remove the automatically inserted search form (we build our own) -->\r
+  <xsl:template match="li[form]"> \r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to alphabetical class index table -->\r
+  <xsl:template match="table[preceding-sibling::*[1][self::div][@class='qindex']]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">qindextable</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to special paragraphs -->\r
+\r
+  <xsl:template match="dl[dt/b/a/text()='Bug:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">xref-bug</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="dl[dt/b/a/text()='Fix:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">xref-fix</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="dl[dt/b/a/text()='Todo:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">xref-todo</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="dl[dt/b/a/text()='Idea:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">xref-idea</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="dl[dt/b/text()='Parameters:']|dl[dt/b/text()='Template Parameters:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">parameters</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="dl[dt/b/text()='Implementation note:']">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">implementation</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="p[starts-with(text(),'Definition at line ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">sourceline</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'References ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">references</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Referenced by ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">referencedby</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Reimplemented from ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">reimplementedfrom</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Reimplemented in ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">reimplementedin</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Implemented in ')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">implementedin</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Break the following lists after each komma -->\r
+\r
+  <xsl:template match="p[starts-with(text(),'Inherited by ')]">\r
+    <xsl:call-template name="break-comma"/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="p[starts-with(text(),'Inherits ')]">\r
+    <xsl:call-template name="break-comma"/>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to the member overview table of a class documentation -->\r
+  <xsl:template match="table[descendant::td[@class='memItemLeft']]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">members</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to literal links (links, where link text and href attribute are the same -->\r
+  <xsl:template match="a[@href=string(current())]" priority="1">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">literal</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to external links -->\r
+  <xsl:template match="a[contains(@href,'http://')]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">ext</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to anchor-only links -->\r
+  <xsl:template match="a[not(@href)]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">anchor</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Add CSS class to the brief documentation paragraph of the member documentation -->\r
+  <xsl:template match="div[@class='memdoc']/p[1][not(contains(.,'Definition at line'))]">\r
+    <xsl:call-template name="add-class">\r
+      <xsl:with-param name="class">memtitle</xsl:with-param>\r
+    </xsl:call-template>\r
+  </xsl:template>\r
+\r
+  <!-- Remove external items from the namespace index -->\r
+  <xsl:template match="div[@id='content2']/table[contains(preceding-sibling::h1/text(),'Namespace Reference')]/tr[td[@class='memItemRight']/a[1][@class='elRef'][@doxygen]]">\r
+  </xsl:template>\r
+  \r
+  <!-- Remove [external] references from the modules page -->\r
+  <xsl:template match="div[@id='content2']/ul/li[a/@class='elRef'][a/@doxygen][code/text()='[external]'][not(ul)]">\r
+  </xsl:template>\r
+\r
+</xsl:stylesheet>\r
diff --git a/site_scons/lib/tag-munge.xsl b/site_scons/lib/tag-munge.xsl
new file mode 100644 (file)
index 0000000..67f1f3d
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+                version="1.0">\r
+  \r
+  <xsl:output method="xml"/>\r
+    \r
+  <xsl:template match="compound[@kind='namespace']">\r
+  </xsl:template>\r
+\r
+  <xsl:template match="*">\r
+    <xsl:copy>\r
+      <xsl:for-each select="@*"><xsl:copy/></xsl:for-each>\r
+      <xsl:apply-templates/>\r
+    </xsl:copy>\r
+  </xsl:template>\r
+\r
+</xsl:stylesheet>\r
index 46e33d1..55665dc 100644 (file)
@@ -1,6 +1,8 @@
-import os.path, glob
+import os.path, glob, site_tools.Yaptu
 from SCons.Script import *
 
+senfutildir = os.path.dirname(__file__)
+
 # Fix for SCons 0.97 compatibility
 try:
     Variables
@@ -60,12 +62,15 @@ Special command line parameters:
 # c) check for a local SENF, set options accordingly and update that SENF if needed
 
 def SetupForSENF(env, senf_paths = []):
-    senfutildir = os.path.dirname(__file__)
+    global senfutildir
     senf_paths.extend(('senf', '../senf', os.path.dirname(senfutildir), '/usr/local', '/usr'))
     tooldir = os.path.join(senfutildir, 'site_tools')
 
     env.Tool('Boost',       [ tooldir ])
     env.Tool('PhonyTarget', [ tooldir ])
+    env.Tool('Yaptu',       [ tooldir ])
+    env.Tool('CopyToDir',   [ tooldir ])
+    env.Tool('Doxygen',     [ tooldir ])
 
     env.Append(
         LIBS              = [ 'senf', 'rt', '$BOOSTREGEXLIB',
@@ -90,6 +95,11 @@ def SetupForSENF(env, senf_paths = []):
         LOGLEVELS_        = BuildTypeOptions('LOGLEVELS'),
         )
 
+    rev = 'unknown'
+    if os.path.isdir('.svn'):
+        rev = 'r'+os.popen('svnversion').read().strip().lower()
+    elif os.path.isdir('.git'):
+        rev = 'r'+os.popen('gitsvnversion').read().strip().lower()
     env.SetDefault( 
         CXXFLAGS_final    = [],
         CXXFLAGS_normal   = [],
@@ -106,6 +116,12 @@ def SetupForSENF(env, senf_paths = []):
         LOGLEVELS_final   = [],
         LOGLEVELS_normal  = [],
         LOGLEVELS_debug   = [],
+
+        PROJECTNAME       = "Unnamed project",
+        DOCLINKS          = [],
+        PROJECTEMAIL      = "nobody@nowhere.org",
+        COPYRIGHT         = "nobody",
+        REVISION          = rev,
         )
 
     # Interpret command line options
@@ -159,3 +175,48 @@ def Glob(env, exclude=[], subdirs=[]):
         sources += [ x for x in glob.glob(os.path.join(subdir,"*.cc"))
                      if x not in testSources and x not in exclude ]
     return (sources, testSources)
+
+def Doxygen(env, doxyheader=None, doxyfooter=None, doxycss=None, mydoxyfile=False, **kw):
+    # Additional interesting keyword arguments or environment variables:
+    #    PROJECTNAME, DOCLINKS, PROJECTEMAIL, COPYRIGHT
+
+    libdir=os.path.join(senfutildir, 'lib')
+    
+    if env.GetOption('clean'):
+        env.Clean('doc', env.Dir('doc'))
+        if not mydoxyfile:
+            env.Clean('doc', "Doxyfile")
+
+    if not mydoxyfile:
+        # Create Doxyfile NOW
+        site_tools.Yaptu.yaptuAction("Doxyfile", 
+                                     os.path.join(libdir, "Doxyfile.yap"),
+                                     env)
+
+    # The other files are created using dependencies
+    if doxyheader: 
+        doxyheader = env.CopyToDir(env.Dir("doc"), doxyheader)
+    else:
+        doxyheader = env.Yaptu("doc/doxyheader.html", os.path.join(libdir, "doxyheader.yap"), **kw)
+    if doxyfooter:
+        doxyfooter = env.CopyToDir(env.Dir("doc"), doxyfooter)
+    else:
+        doxyfooter = env.Yaptu("doc/doxyfooter.html", os.path.join(libdir, "doxyfooter.yap"), **kw)
+    if doxycss:
+        doxycss = env.CopyToDir(env.Dir("doc"), doxycss)
+    else:
+        doxycss    = env.CopyToDir(env.Dir("doc"), os.path.join(libdir, "doxy.css"))
+
+    doc = env.Doxygen("Doxyfile",
+                      DOXYOPTS   = [ '--html' ],
+                      DOXYENV    = { 'TOPDIR'     : env.Dir('#').abspath,
+                                     'LIBDIR'     : libdir,
+                                     'output_dir' : 'doc',
+                                     'html_dir'   : 'html',
+                                     'html'       : 'YES' },
+                      DOCLIBDIR  = libdir,
+                      DOXYGENCOM = "$DOCLIBDIR/doxygen.sh $DOXYOPTS $SOURCE")
+
+    env.Depends(doc, [ doxyheader, doxyfooter, doxycss ])
+
+    return doc
diff --git a/site_scons/site_tools/Yaptu.py b/site_scons/site_tools/Yaptu.py
new file mode 100644 (file)
index 0000000..030f371
--- /dev/null
@@ -0,0 +1,17 @@
+import SCons.Action, SCons.Builder, yaptu
+
+def yaptuAction(target, source, env):
+    source = env.arg2nodes(source)
+    target = env.arg2nodes(target)
+    file(target[0].get_path(),"w").write(
+        yaptu.process(file(source[0].get_path(),"r").read(), globals(), env.Dictionary()))
+
+YaptuAction = SCons.Action.Action(yaptuAction,
+                                  lambda t,s,e=None: 'Yaptu("%s", "%s")' % (t[0],s[0]))
+YaptuBuilder = SCons.Builder.Builder(action=YaptuAction, single_source=1)
+
+def generate(env):
+    env['BUILDERS']['Yaptu'] = YaptuBuilder
+
+def exists(env):
+    return True
diff --git a/site_scons/site_tools/__init__.py b/site_scons/site_tools/__init__.py
new file mode 100644 (file)
index 0000000..e69de29