]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Import kdoc snapshot 2.a35
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 21 Jun 2000 12:33:53 +0000 (12:33 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 21 Jun 2000 12:33:53 +0000 (12:33 +0000)
git-svn-id: https://svn.dealii.org/trunk@3041 0785d39b-7218-0410-832d-ea1e28bc413d

42 files changed:
deal.II/contrib/kdoc/src/Ast.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/Iter.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/Makefile.cvs [new file with mode: 0644]
deal.II/contrib/kdoc/src/Makefile.in [new file with mode: 0644]
deal.II/contrib/kdoc/src/README [new file with mode: 0644]
deal.II/contrib/kdoc/src/TODO [new file with mode: 0644]
deal.II/contrib/kdoc/src/Version [new file with mode: 0644]
deal.II/contrib/kdoc/src/config.log [new file with mode: 0644]
deal.II/contrib/kdoc/src/configure [new file with mode: 0755]
deal.II/contrib/kdoc/src/configure.in [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/changelog [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/control [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/copyright [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/postinst [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/postrm [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/preinst [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/prerm [new file with mode: 0644]
deal.II/contrib/kdoc/src/debian/rules [new file with mode: 0755]
deal.II/contrib/kdoc/src/doc/DESIGN [new file with mode: 0644]
deal.II/contrib/kdoc/src/doc/Makefile.in [new file with mode: 0644]
deal.II/contrib/kdoc/src/doc/kdoc.docbook [new file with mode: 0644]
deal.II/contrib/kdoc/src/doc/kdoc.pod [new file with mode: 0644]
deal.II/contrib/kdoc/src/findperl [new file with mode: 0755]
deal.II/contrib/kdoc/src/install-sh [new file with mode: 0755]
deal.II/contrib/kdoc/src/kdoc [new file with mode: 0755]
deal.II/contrib/kdoc/src/kdocAstUtil.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocCxxDocbook.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocCxxHTML.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocDocHelper.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocHTMLutil.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocIDLhtml.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocLib.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocParseDoc.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocTeX.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdocUtil.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/kdoctexi.pm [new file with mode: 0644]
deal.II/contrib/kdoc/src/makekdedoc [new file with mode: 0755]
deal.II/contrib/kdoc/src/qt2kdoc [new file with mode: 0755]
deal.II/contrib/kdoc/src/test/decl.h [new file with mode: 0644]
deal.II/contrib/kdoc/src/test/testrelpaths [new file with mode: 0755]
deal.II/contrib/kdoc/src/test/tweedle.h [new file with mode: 0644]

diff --git a/deal.II/contrib/kdoc/src/Ast.pm b/deal.II/contrib/kdoc/src/Ast.pm
new file mode 100644 (file)
index 0000000..0fb4bd0
--- /dev/null
@@ -0,0 +1,91 @@
+package Ast;
+use strict;
+
+use vars qw/ $this $pack @endCodes /;
+
+#-----------------------------------------------------------------------------
+# This package is used  to create a simple Abstract Syntax tree. Each node
+# in the AST is an associative array and supports two kinds of properties -
+# scalars and lists of scalars.
+# See SchemParser.pm for an example of usage.
+#                                                               ... Sriram
+#-----------------------------------------------------------------------------
+
+# Constructor 
+# e.g AST::New ("personnel")
+# Stores the argument in a property called astNodeName whose sole purpose
+# is to support Print()
+
+sub New {
+       my ($this) = {"astNodeName" => $_[0]};
+       bless ($this);
+       return $this;
+}
+
+# Add a property to this object
+# $astNode->AddProp("className", "Employee");
+
+sub AddProp {
+       my ($this) = $_[0];
+       $this->{$_[1]} = $_[2];
+}
+
+# Equivalent to AddProp, except the property name is associated
+# with a list of values
+# $classAstNode->AddProp("attrList", $attrAstNode);
+
+sub AddPropList {
+       my ($this) = $_[0];
+       if (! exists $this->{$_[1]}) {
+               $this->{$_[1]} = [];
+       }
+       push (@{$this->{$_[1]}}, $_[2]);
+}
+
+# Returns a list of all the property names of this object
+sub GetProps {
+       my ($this) = $_[0];
+       return keys %{$this};
+}
+
+sub Visit {
+    # Converts each of this AstNode's properties into global variables.
+    # The global variables are introduced into package "main"
+    # At the same time, a piece of code is  formed to undo this work above -
+    # $endCode essentially contains the values of these global variables
+    # before  they are mangled. endCode gets pushed into a stack (endCodes),
+    # which is unwound by UnVisit().
+
+    local ($this, $pack) = @_;
+
+
+    my $code = ""; 
+    my $endCode = "";
+
+
+    foreach my $k (keys %{$this}) {
+
+       my $glob = $pack."::".$k;
+
+       if ( defined $$glob ) {
+
+               if ( ${$glob} ne "" ) {
+                       $$glob =~ s/\'/\\\'/g; 
+               }
+
+           $endCode .= '$'.$pack.'::'.$k. " = '".$$glob."';";
+       } else {
+           $endCode .= '$'.$pack . "::". $k . ' = "";';
+       }
+       $code .= '$'.$pack . "::" . $k . "= \$this->{\"$k\"};";
+    }
+    push (@endCodes, $endCode);
+    eval($code) if $code;
+}
+
+sub UnVisit {
+    my $code = pop(@endCodes);
+    eval($code) if ($code);
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/Iter.pm b/deal.II/contrib/kdoc/src/Iter.pm
new file mode 100644 (file)
index 0000000..337825d
--- /dev/null
@@ -0,0 +1,500 @@
+package Iter;
+
+=head1 Iterator Module
+
+A set of iterator functions for traversing the various trees and indexes.
+Each iterator expects closures that operate on the elements in the iterated
+data structure.
+
+
+=head2 Generic
+
+       Params: $node, &$loopsub, &$skipsub, &$applysub, &$recursesub
+
+Iterate over $node's children. For each iteration:
+       
+If loopsub( $node, $kid ) returns false, the loop is terminated. 
+If skipsub( $node, $kid )  returns true, the element is skipped.
+
+Applysub( $node, $kid ) is called
+If recursesub( $node, $kid ) returns true, the function recurses into 
+the current node.
+
+=cut
+
+sub Generic
+{
+       my ( $root, $loopcond, $skipcond, $applysub, $recursecond ) = @_;
+
+       return sub {
+               foreach my $node ( @{$root->{Kids}} ) {
+
+                       if ( defined  $loopcond ) {
+                               return 0 unless $loopcond->( $root, $node );
+                       }
+
+                       if ( defined $skipcond ) {
+                               next if $skipcond->( $root, $node );
+                       }
+
+                       my $ret = $applysub->( $root, $node );
+                       return $ret if defined $ret && $ret;
+
+                       if ( defined $recursecond 
+                                       && $recursecond->( $root, $node ) ) {
+                               $ret = Generic( $node, $loopcond, $skipcond,
+                                               $applysub, $recursecond)->();
+                               if ( $ret ) {
+                                       return $ret;
+                               }
+                       }
+               }
+
+               return 0;
+       };
+}
+
+sub Class
+{
+       my ( $root, $applysub, $recurse ) = @_;
+
+       return Generic( $root, undef,
+               sub {
+                       return !( $node->{NodeType} eq "class" 
+                               || $node->{NodeType} eq "struct" );
+               }, 
+               $applysub, $recurse );
+}
+
+=head2 Tree
+
+       Params: $root, $recurse?, $commonsub, $compoundsub, $membersub,
+               $skipsub
+
+Traverse the ast tree starting at $root, skipping if skipsub returns true.
+
+Applying $commonsub( $node, $kid),
+then $compoundsub( $node, $kid ) or $membersub( $node, $kid ) depending on
+the Compound flag of the node.
+
+=cut
+
+sub Tree
+{
+       my ( $rootnode, $recurse, $commonsub, $compoundsub, $membersub, 
+                $skipsub ) = @_;
+
+       my $recsub = $recurse ? sub { return 1 if $_[1]->{Compound}; } 
+                               : undef;
+
+       Generic( $rootnode, undef, $skipsub,
+               sub {                                   # apply
+                       my ( $root, $node ) = @_;
+                       my $ret;
+
+                       if ( defined $commonsub ) {
+                               $ret = $commonsub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+
+                       if ( $node->{Compound} && defined $compoundsub ) {
+                               $ret = $compoundsub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+                       
+                       if( !$node->{Compound} && defined $membersub ) {
+                               $ret = $membersub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+                       return;
+               },
+               $recsub                                 # skip
+       )->();
+}
+
+=head2 LocalCompounds
+
+Apply $compoundsub( $node ) to all locally defined compound nodes
+(ie nodes that are not external to the library being processed).
+
+=cut
+
+sub LocalCompounds
+{
+               my ( $rootnode, $compoundsub ) = @_;
+
+               return unless defined $rootnode && defined $rootnode->{Kids};
+
+               foreach my $kid ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+                                                                @{$rootnode->{Kids}} ) {
+                               next if !defined $kid->{Compound};
+
+                               $compoundsub->( $kid ) unless defined $kid->{ExtSource};
+                               LocalCompounds( $kid, $compoundsub );
+               }
+}
+
+=head2 Hierarchy
+
+       Params: $node, $levelDownSub, $printSub, $levelUpSub
+
+This allows easy hierarchy traversal and printing.
+
+Traverses the inheritance hierarchy starting at $node, calling printsub
+for each node. When recursing downward into the tree, $levelDownSub($node) is
+called, the recursion takes place, and $levelUpSub is called when the
+recursion call is completed. 
+
+=cut
+
+sub Hierarchy
+{
+       my ( $node, $ldownsub, $printsub, $lupsub, $nokidssub ) = @_;
+
+       return if defined $node->{ExtSource}
+               && (!defined $node->{InBy} 
+                       || !kdocAstUtil::hasLocalInheritor( $node ));
+
+       $printsub->( $node );
+
+       if ( defined $node->{InBy} ) {
+               $ldownsub->( $node );
+
+               foreach my $kid ( 
+                               sort {$a->{astNodeName} cmp $b->{astNodeName}}
+                               @{ $node->{InBy} } ) {
+                       Hierarchy( $kid, $ldownsub, $printsub, $lupsub );
+               }
+
+               $lupsub->( $node );
+       }
+       elsif ( defined $nokidssub ) {
+               $nokidssub->( $node );
+       }
+
+       return;
+}
+
+
+sub Ancestors
+{
+       my ( $node, $rootnode, $noancessub, $startsub, $printsub,
+               $endsub ) = @_;
+       my @anlist = ();
+
+       return if $node eq $rootnode;
+
+       if ( !exists $node->{InList} ) {
+               $noancessub->( $node ) unless !defined $noancessub;
+               return;
+       }
+       
+       foreach my $innode ( @{ $node->{InList} } ) {
+               my $nref = $innode->{Node};     # real ancestor
+               next if defined $nref && $nref == $rootnode;
+
+               push @anlist, $innode;
+       }
+
+       if ( $#anlist < 0 ) {
+               $noancessub->( $node ) unless !defined $noancessub;
+               return;
+       }
+
+       $startsub->( $node ) unless !defined $startsub;
+
+       foreach my $innode ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+                               @anlist ) {
+
+               # print
+               $printsub->( $innode->{Node}, $innode->{astNodeName},
+                       $innode->{Type}, $innode->{TmplType} ) 
+                       unless !defined $printsub;
+       }
+
+       $endsub->( $node ) unless !defined $endsub;
+
+       return;
+
+}
+
+sub Descendants
+{
+       my ( $node, $nodescsub, $startsub, $printsub, $endsub ) = @_;
+
+       if ( !exists $node->{InBy} ) {
+               $nodescsub->( $node ) unless !defined $nodescsub;
+               return;
+       }
+
+       
+       my @desclist = ();
+       DescendantList( \@desclist, $node );
+       
+       if ( $#desclist < 0 ) {
+               $nodescsub->( $node ) unless !defined $nodescsub;
+               return;
+       }
+
+       $startsub->( $node ) unless !defined $startsub;
+
+       foreach my $innode ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+                               @desclist ) {
+
+               $printsub->( $innode) 
+                       unless !defined $printsub;
+       }
+
+       $endsub->( $node ) unless !defined $endsub;
+
+       return;
+
+}
+
+sub DescendantList
+{
+       my ( $list, $node ) = @_;
+
+       return unless exists $node->{InBy};
+
+       foreach my $kid ( @{ $node->{InBy} } ) {
+               push @$list, $kid;
+               DescendantList( $list, $kid );
+       }
+}
+
+=head2 DocTree
+
+=cut
+
+sub DocTree
+{
+       my ( $rootnode, $allowforward, $recurse, 
+               $commonsub, $compoundsub, $membersub ) = @_;
+               
+       Generic( $rootnode, undef,
+               sub {                           # skip
+                       my( $node, $kid ) = @_;
+
+                       unless (!(defined $kid->{ExtSource}) 
+                                       && ($allowforward || $kid->{NodeType} ne "Forward")
+                                       && ($main::doPrivate || !($kid->{Access} =~ /private/))
+                                       && exists $kid->{DocNode} ) {
+
+                               return 1;
+                       }
+
+                       return;
+               },
+               sub {                           # apply
+                       my ( $root, $node ) = @_;
+
+                       my $ret;
+
+                       if ( defined $commonsub ) {
+                               $ret = $commonsub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+
+                       if ( $node->{Compound} && defined $compoundsub ) {
+                               $ret = $compoundsub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+                       elsif( defined $membersub ) {
+                               $ret = $membersub->( $root, $node );
+                               return $ret if defined $ret;
+                       }
+
+                       return;
+               },
+               sub { return 1 if $recurse; return; }   # recurse
+               )->();
+
+}
+
+sub MembersByType
+{
+       my ( $node, $startgrpsub, $methodsub, $endgrpsub, $nokidssub ) = @_;
+
+# public
+       # types
+       # data
+       # methods
+       # signals
+       # slots
+       # static
+# protected
+# private (if enabled)
+
+       if ( !defined $node->{Kids} ) {
+                       $nokidssub->( $node ) if defined $nokidssub;
+                       return;
+       }
+
+       foreach my $access ( qw/public protected private/ ) {
+               next if $access eq "private" && !$main::doPrivate;
+
+               my @types = ();
+               my @data = ();
+               my @signals = ();
+               my @slots =();
+               my @methods = ();
+               my @static = ();
+               my @modules = ();
+               my @interfaces = ();
+
+               # Build lists
+               foreach my $kid ( @{$node->{Kids}} ) {
+                       next if !(($kid->{Access} =~ /$access/
+                                       && !$kid->{ExtSource})
+                               || ( $access eq "public" 
+                                       && $kid->{Access} eq "signals" ));
+
+                       my $type = $kid->{NodeType};
+
+                       if ( $type eq "method" ) {
+                               if ( $kid->{Flags} =~ "s" ) {
+                                       push @static, $kid;
+                               }
+                               elsif ( $kid->{Flags} =~ "l" ) {
+                                       push @slots, $kid;
+                               }
+                               elsif ( $kid->{Flags} =~ "n" ) {
+                                       push @signals, $kid;
+                               }
+                               else {
+                                       push @methods, $kid;
+                               }
+                       }
+                       elsif ( $kid->{Compound} ) {
+                               if ( $type eq "module" ) {
+                                       push @modules, $kid;
+                               }
+                               elsif ( $type eq "interface" ) {
+                                       push @interfaces, $kid;
+                               }
+                               else {
+                                       push @types, $kid;
+                               }
+                       }
+                       elsif ( $type eq "typedef" || $type eq "enum" ) {
+                               push @types, $kid;
+                       }
+                       else {
+                               push @data, $kid;
+                       }
+               }
+
+               # apply
+               $access = ucfirst( $access );
+               
+               doGroup( "$access Types", $node, \@types, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "Modules", $node, \@modules, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "Interfaces", $node, \@interfaces, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "$access Methods", $node, \@methods, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "$access Slots", $node, \@slots, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "Signals", $node, \@signals, $startgrpsub,
+                       $methodsub, $endgrpsub);
+               doGroup( "$access Static Methods", $node, \@static, 
+                       $startgrpsub, $methodsub, $endgrpsub);
+               doGroup( "$access Members", $node, \@data, $startgrpsub,
+                       $methodsub, $endgrpsub);
+       }
+}
+
+sub doGroup
+{
+       my ( $name, $node, $list, $startgrpsub, $methodsub, $endgrpsub ) = @_;
+
+       return if $#$list < 0;
+
+       $startgrpsub->( $name ) if defined $startgrpsub;
+       
+       if ( defined $methodsub ) {
+               foreach my $kid ( @$list ) {
+                       $methodsub->( $node, $kid );
+               }
+       }
+
+       $endgrpsub->( $name ) if defined $endgrpsub;
+}
+
+sub ByGroupLogical
+{
+       my ( $root, $startgrpsub, $itemsub, $endgrpsub ) = @_;
+
+       return 0 unless defined $root->{Groups};
+
+       foreach my $groupname ( sort keys %{$root->{Groups}} ) {
+               next if $groupname eq "astNodeName"||$groupname eq "NodeType";
+
+               my $group = $root->{Groups}->{ $group };
+               next unless $group->{Kids};
+               
+               $startgrpsub->( $group->{astNodeName}, $group->{Desc} );
+
+               foreach my $kid (sort {$a->{astNodeName} cmp $b->{astNodeName}}
+                                       @group->{Kids} ) {
+                       $itemsub->( $root, $kid );
+               }
+               $endgrpsub->( $group->{Desc} ); 
+       }
+
+       return 1;
+}
+
+sub SeeAlso
+{
+       my ( $node, $nonesub, $startsub, $printsub, $endsub ) = @_;
+
+       if( !defined $node ) {
+               $nonesub->();
+               return;
+       }
+
+       my $doc = $node;
+
+       if ( $node->{NodeType} ne "DocNode" ) {
+               $doc = $node->{DocNode};
+               if ( !defined $doc ) {
+                       $nonesub->() if defined $nonesub;
+                       return;
+               }
+       }
+
+       if ( !defined $doc->{See} ) {
+               $nonesub->() if defined $nonesub;
+               return;
+       }
+
+       my $see = $doc->{See};
+       my $ref = $doc->{SeeRef};
+
+       if ( $#$see < 1 ) {
+               $nonesub->() if defined $nonesub;
+               return;
+       }
+
+       $startsub->( $node ) if defined $startsub;
+
+       for my $i ( 0..$#$see ) {
+               my $seelabel = $see->[ $i ];
+               my $seenode = undef;
+               if ( defined $ref ) {
+                       $seenode = $ref->[ $i ]; 
+               }
+
+               $printsub->( $seelabel, $seenode ) if defined $printsub;
+       }
+
+       $endsub->( $node ) if defined $endsub;
+
+       return;
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/Makefile.cvs b/deal.II/contrib/kdoc/src/Makefile.cvs
new file mode 100644 (file)
index 0000000..3c0d806
--- /dev/null
@@ -0,0 +1,5 @@
+
+all: configure
+
+configure: configure.in
+       autoconf
diff --git a/deal.II/contrib/kdoc/src/Makefile.in b/deal.II/contrib/kdoc/src/Makefile.in
new file mode 100644 (file)
index 0000000..6b1a433
--- /dev/null
@@ -0,0 +1,67 @@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+perl = @perl@
+install = @INSTALL@
+bin = kdoc qt2kdoc makekdedoc
+pm = kdocUtil.pm kdocAstUtil.pm kdocParseDoc.pm kdocCxxHTML.pm kdocLib.pm \
+       Ast.pm kdocIDLhtml.pm kdocHTMLutil.pm kdoctexi.pm kdocCxxLaTeX.pm \
+       kdocDocHelper.pm kdocCxxDocbook.pm Iter.pm
+pmextra = 
+bindir = ${exec_prefix}/bin
+pmdir = ${prefix}/share/kdoc
+srcdocdir= doc
+VERSION=@Version@
+
+all: kdoc.local qt2kdoc.local makekdedoc.local
+       (cd doc; make)
+
+kdoc.local: @srcdir@/kdoc
+       cp @srcdir@/kdoc kdoc.local
+       perl -npi -e 's%^#\!.*$$%#!'${perl}' -I'${pmdir}'%g;' kdoc.local
+       perl -npi -e 's#\$$Version\\\$$#'"${VERSION}"'#g;' kdoc.local
+
+qt2kdoc.local: @srcdir@/qt2kdoc
+       cp @srcdir@/qt2kdoc qt2kdoc.local
+       perl -npi -e 's%^#\!.*$$%#!'${perl}' -I'${pmdir}'%g;' qt2kdoc.local
+
+makekdedoc.local: @srcdir@/makekdedoc
+       cp @srcdir@/makekdedoc makekdedoc.local
+       perl -npi -e 's%^#\!.*$$%#!'${perl}' -I'${pmdir}'%g;' makekdedoc.local
+
+install: all
+       ${install} -d $(DESTDIR)${bindir}
+       ${install} -m 755 kdoc.local $(DESTDIR)${bindir}/kdoc
+       ${install} -m 755 qt2kdoc.local $(DESTDIR)${bindir}/qt2kdoc
+       ${install} -m 755 makekdedoc.local $(DESTDIR)${bindir}/makekdedoc
+       ${install} -d $(DESTDIR)${pmdir}
+       for file in ${pm} ${pmextra}; do \
+               ${install} -m 644 @srcdir@/$$file $(DESTDIR)${pmdir}; \
+       done
+       (cd doc; make install)
+
+uninstall:
+       (cd $(DESTDIR)${bindir} && rm -f ${bin})
+       (cd $(DESTDIR)${pmdir} && rm -f ${pm})
+       (cd $(DESTDIR)${mandir} && rm -f ${man})
+       -rmdir $(DESTDIR)${bindir}
+       -rmdir $(DESTDIR)${pmdir}
+       -rmdir $(DESTDIR)${mandir}
+
+clean:
+       (cd doc; make clean)
+       rm -f kdoc.local qt2kdoc.local makekdedoc.local
+
+distclean: clean
+       rm -f Makefile config.status config.log config.cache perlbin \
+               doc/Makefile
+
+srcdoc:
+       pod2html --flush --title KDOC $(bin) $(pm) \
+                --outfile $(srcdocdir)/kdoc-doc.html
+tags:
+       perltags kdoc qt2kdoc makekdedoc *.pm
+
+check:
+       @for dir in $(bin) $(pm); do \
+               echo "** Checking: $$dir"; \
+               perl -wc $$dir; done
diff --git a/deal.II/contrib/kdoc/src/README b/deal.II/contrib/kdoc/src/README
new file mode 100644 (file)
index 0000000..af8cded
--- /dev/null
@@ -0,0 +1,58 @@
+
+KDOC -- C++ and IDL Source Documentation System
+Version 2.0 ALPHA
+
+KDOC creates cross-referenced documentation for C++ and CORBA IDL libraries
+directly from the source. Documentation can be embedded in special doc
+comments in the source.
+
+Also included:
+
+qt2kdoc:       Generates cross-reference index to link kdoc output with 
+               Qt documentation.
+
+makekdedoc:    Generates documentation for the KDE libraries.
+
+KDOC 2.0 is still under development.
+
+REQUIREMENTS
+
+You need perl 5.005 or greater to run kdoc.
+
+HOWTO
+
+If you are running this straight from CVS, you will need to run 
+
+       make -f Makefile.cvs
+
+before building.
+
+This should install kdoc:
+
+./configure; make; make install
+rehash; man kdoc
+
+The KDOC manual in docbook format is available in doc/kdoc.docbook.
+This can be converted to various other online and print formats using
+the jade and docbook packages.
+
+CREDITS
+-------
+
+Thanks to the following people for providing testing, feedback, encouragment,
+new features and patches:
+
+Bernd Gehrmann
+David Sweet
+Harald Hoyer
+Jochen Wilhelmy
+Marcin Kasperski
+Rainer Dorsch
+Stephane Matamontero
+Torben Weis
+Wolfgang Bangerth
+Andrew W. Nosenko
+
+------
+Copyright(C) 1999, Sirtaj Singh Kang <taj@kde.org>
+Distributed under the GPL.
diff --git a/deal.II/contrib/kdoc/src/TODO b/deal.II/contrib/kdoc/src/TODO
new file mode 100644 (file)
index 0000000..1f27b7d
--- /dev/null
@@ -0,0 +1,82 @@
+
+Bugs
+----
+Refs for external nodes are being double-escaped.
+
+templates
+       template functions
+variables
+       multivars cannot have values
+       array initializers don't work
+       pointers to functions
+compound typedefs
+functions
+       Constructor initializers are appearing as part of the args.
+       functions with funcptr or paren'd arguments
+       operators are not properly quoted
+       operators not always correctly parsed
+
+Source for Forward decls should not be picked up.
+Preprocessor screws up line numbers.
+
+check "@params ... */"
+check namespaces
+
+HTML: links are screwed (multiple escapes somewhere).
+
+General
+-------
+Running kdoc in-place
+Major IDL cleanup
+
+parser
+------
+documentation in source
+CODE etc
+templates
+
+IDL specific: 
+       parse "raises"
+
+Doc specific
+------------
+       pre should be allowed inline.
+       exceptions:
+               @exception <exception>  Reason
+               exception is a class
+
+Ast
+---
+Allow cross-referencing between languages. I don't know how to do this,
+other than by reading every language into the same syntax tree.
+
+postprocessor
+------------
+referenced text use namespaces
+       searchspaces:
+               upward-searching (this and parents)
+               enclosed (namespaces)
+
+DocBook
+-------
+Don't use deref, we need a textref function instead.
+       deref is for @refs etc.
+visibility and flags in member docs.
+Globals.
+group indices.
+Index.
+
+HTML
+----
+Filenames - "/" being replaced by "#" is silly.
+group indices.
+cross-referenced headers
+
+Libs
+----
+-L doesn't work properly (KDOCLIBS works ok).
+
+Other
+-----
+Man
+lxr
diff --git a/deal.II/contrib/kdoc/src/Version b/deal.II/contrib/kdoc/src/Version
new file mode 100644 (file)
index 0000000..9b3dad1
--- /dev/null
@@ -0,0 +1 @@
+2.0a35
diff --git a/deal.II/contrib/kdoc/src/config.log b/deal.II/contrib/kdoc/src/config.log
new file mode 100644 (file)
index 0000000..fb9038e
--- /dev/null
@@ -0,0 +1,3 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
diff --git a/deal.II/contrib/kdoc/src/configure b/deal.II/contrib/kdoc/src/configure
new file mode 100755 (executable)
index 0000000..69fdb8e
--- /dev/null
@@ -0,0 +1,891 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.12"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=qt2kdoc
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:557: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      for ac_prog in ginstall installbsd scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           # OSF/1 installbsd also uses dspmsg, but is usable.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for perl 5 or greater""... $ac_c" 1>&6
+echo "configure:608: checking for perl 5 or greater" >&5
+if $srcdir/findperl; then
+       perl=`cat perlbin`
+       echo $perl
+else
+       echo "Couldn't find perl 5 or later. kdoc will not run."
+       exit 1
+fi     
+
+
+
+echo $ac_n "checking kdoc version""... $ac_c" 1>&6
+echo "configure:620: checking kdoc version" >&5
+Version=`cat $srcdir/Version | sed 's#Revision##g' | tr -d '\$:'`
+echo $Version
+
+
+
+mandir='${prefix}/man/man1'
+docdir='${prefix}/doc/kdoc'
+
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[    `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile doc/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@perl@%$perl%g
+s%@Version@%$Version%g
+s%@docdir@%$docdir%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/deal.II/contrib/kdoc/src/configure.in b/deal.II/contrib/kdoc/src/configure.in
new file mode 100644 (file)
index 0000000..9c926e5
--- /dev/null
@@ -0,0 +1,35 @@
+AC_INIT(qt2kdoc)
+
+AC_DEFUN(AC_FIND_PERL,
+[
+AC_MSG_CHECKING(for perl 5 or greater)
+if $srcdir/findperl; then
+       $1=`cat perlbin`
+       echo $$1
+else
+       echo "Couldn't find perl 5 or later. kdoc will not run."
+       exit 1
+fi     
+])
+
+AC_DEFUN(AC_KDOC_VERSION,
+[
+AC_MSG_CHECKING(kdoc version)
+$1=`cat $srcdir/Version | sed 's#Revision##g' | tr -d '\$:'`
+echo $$1
+])
+
+AC_PROG_INSTALL
+AC_FIND_PERL(perl)
+AC_SUBST(perl)
+AC_KDOC_VERSION(Version)
+AC_SUBST(Version)
+
+mandir='${prefix}/man/man1'
+docdir='${prefix}/doc/kdoc'
+
+AC_SUBST(mandir)
+AC_SUBST(docdir)
+
+
+AC_OUTPUT(Makefile doc/Makefile)
diff --git a/deal.II/contrib/kdoc/src/debian/changelog b/deal.II/contrib/kdoc/src/debian/changelog
new file mode 100644 (file)
index 0000000..71a274e
--- /dev/null
@@ -0,0 +1,27 @@
+kdoc (2.0a15-1.0) unstable; urgency=low
+
+  * New upstream version
+
+ -- Ivan E. Moore II <rkrusty@debian.org>  Wed, 13 Oct 1999 23:30:06 -0400
+
+kdoc (2.0a12-1.0) unstable; urgency=low
+
+  * New upstream version
+
+ -- Ivan E. Moore II <rkrusty@debian.org>  Mon, 27 Sep 1999 23:30:06 -0400
+
+kdoc (2.0a9-2) unstable; urgency=low
+
+  * Use DESTDIR for 'make install'
+
+ -- Bernd Gehrmann <bernd@physik.hu-berlin.de>  Sat, 22 May 1999 18:30:06 +0200
+
+kdoc (2.0a9-1) experimental; urgency=low
+
+  * Initial Release.
+
+ -- Bernd Gehrmann <bernd@physik.hu-berlin.de>  Fri, 23 Apr 1999 19:30:14 +0200
+
+Local variables:
+mode: debian-changelog
+End:
diff --git a/deal.II/contrib/kdoc/src/debian/control b/deal.II/contrib/kdoc/src/debian/control
new file mode 100644 (file)
index 0000000..a430a44
--- /dev/null
@@ -0,0 +1,16 @@
+Source: kdoc
+Section: devel
+Priority: optional
+Maintainer: Bernd Gehrmann <bernd@physik.hu-berlin.de>
+Standards-Version: 3.0.1
+
+Package: kdoc
+Architecture: all
+Section: devel
+Depends: ${perl:Depends}
+Description: C++ and IDL Source Documentation System 
+ KDOC creates cross-referenced documentation for C++ 
+ and CORBA IDL libraries directly from the source. 
+ Documentation can be embedded in special doccomments 
+ in the source.
+  
diff --git a/deal.II/contrib/kdoc/src/debian/copyright b/deal.II/contrib/kdoc/src/debian/copyright
new file mode 100644 (file)
index 0000000..8af6449
--- /dev/null
@@ -0,0 +1,7 @@
+This package was debianized by Bernd Gehrmann <bernd@physik.hu-berlin.de> 
+
+Copyright:
+
+KDOC is released under the terms of the GNU GPL.
+
+See /usr/doc/copyright/GPL for the full license.
diff --git a/deal.II/contrib/kdoc/src/debian/postinst b/deal.II/contrib/kdoc/src/debian/postinst
new file mode 100644 (file)
index 0000000..df575f1
--- /dev/null
@@ -0,0 +1,30 @@
+#! /bin/sh
+# postinst script for kdoc
+#
+# see: dh_installdeb(1)
+
+set -e
+
+case "$1" in
+    configure)
+
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 0
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/deal.II/contrib/kdoc/src/debian/postrm b/deal.II/contrib/kdoc/src/debian/postrm
new file mode 100644 (file)
index 0000000..f8aa6ec
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+# postrm script for kdoc
+#
+# see: dh_installdeb(1)
+
+set -e
+
+case "$1" in
+       purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+
+                                # update the menu system
+
+        ;;
+
+    *)
+        echo "postrm called with unknown argument \`$1'" >&2
+        exit 0
+
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/deal.II/contrib/kdoc/src/debian/preinst b/deal.II/contrib/kdoc/src/debian/preinst
new file mode 100644 (file)
index 0000000..fe9d7ae
--- /dev/null
@@ -0,0 +1,28 @@
+#! /bin/sh
+# preinst script for kdoc
+#
+# see: dh_installdeb(1)
+
+set -e
+
+case "$1" in
+    install|upgrade)
+    ;;
+
+    abort-upgrade)
+    ;;
+
+    *)
+        echo "preinst called with unknown argument \`$1'" >&2
+        exit 0
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/deal.II/contrib/kdoc/src/debian/prerm b/deal.II/contrib/kdoc/src/debian/prerm
new file mode 100644 (file)
index 0000000..5ba573f
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+# prerm script for kdoc
+#
+# see: dh_installdeb(1)
+
+set -e
+
+case "$1" in
+    remove|upgrade|deconfigure)
+        ;;
+    failed-upgrade)
+        ;;
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 0
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/deal.II/contrib/kdoc/src/debian/rules b/deal.II/contrib/kdoc/src/debian/rules
new file mode 100755 (executable)
index 0000000..8e7b727
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/make -f
+# Made with the aid of dh_make, by Craig Small
+# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
+# Some lines taken from debmake, by Cristoph Lameter.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build:
+       dh_testdir
+       ./configure --prefix=/usr
+       $(MAKE) 
+       touch build
+
+clean:
+       dh_testdir
+       -rm -f build
+       -$(MAKE) distclean
+       -rm -f `find . -name "*~"`
+       dh_clean
+
+binary-indep: build
+       dh_testroot
+       dh_testdir
+
+binary-arch: build
+       dh_testroot
+       dh_testdir
+       dh_clean
+       dh_installdirs
+       $(MAKE) install DESTDIR=`pwd`/debian/tmp/
+       dh_installdocs
+       dh_installexamples
+       dh_installmanpages
+       dh_undocumented
+       dh_installchangelogs
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+       dh_suidregister
+       dh_makeshlibs
+       dh_perl
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+
+.PHONY: binary binary-arch binary-indep clean checkroot
diff --git a/deal.II/contrib/kdoc/src/doc/DESIGN b/deal.II/contrib/kdoc/src/doc/DESIGN
new file mode 100644 (file)
index 0000000..7038d3d
--- /dev/null
@@ -0,0 +1,124 @@
+
+Some of the functions are documented with perlpod, so you can create an HTML
+file with
+
+       pod2html *.pm kdoc > kdocfunc.html
+
+If only pod was as usable as javadoc. maybe kdoc could... naah, 2 languages are
+enough for now. ;)
+
+Ast
+---
+
+AST nodes used by kdoc are very flexible. You can assign as many
+properties as you like, and each property can be a scalar or list (perhaps
+other nodes).
+
+this list may not be complete, but all important properties should be here.
+
+-> properties of all nodes:
+astNodeName    string name of node, ie class, function, method name etc.
+NodeType       string describing node type.
+
+-> properties of all syntax nodes:
+Forward                Only Forward declaration yet.
+Compound       can contain other nodes (see: KidHash)
+ExtSource      came from a library
+Parent         Parent node     (root nodes have no parent)
+Access         Visibility from parent (public, private, etc.)
+DocNode                Documentation node, if it exists
+Deprecated
+Internal
+
+-> properties of compound nodes:
+Kids           List of all kids
+KidHash                hash of all kids by name
+KidAccess      Access that should be set for new children
+Ancestors      List of ancestors as parsed (See "ancestor nodes" )
+InList         list of ancestor nodes.
+InBy           list of derived nodes.
+Pure           Contains pure virtuals
+
+-> ancestor nodes
+astNodeName    Ancestor name as parsed
+Type           Type of derivation (eg "virtual protected");
+Node           A reference to the ancestor. Created by makeInherit.
+TmplType       The inherited template args, if present.
+
+-> properties of DocNode as attached to syntax nodes: (kdocDocParse.pm)
+
+These currently hold 3 kinds of documentation. See the exact property
+names in kdocParseDoc::newDocNode().
+
+TextProperties         Nodes, stored sequentially in Text
+       This is normal text, parabreaks, params, and @li (list items)
+
+doc and list Props     Nodes, stored in 1 property per type
+       This is stuff that is not regular text, ie short name, returns etc.
+
+code props             Properties of the node to which we will be attached
+       Currently this is just deprecated and internal.
+       NOTE: now all code props are lists, to allow for stuff like
+       groups.
+
+
+Parser (kdoc)
+------
+
+The parser assumes that a single declaration is a bunch of non-comment
+text uptil a ";" or "{"
+
+When identifyDecl is called with such a decl, all blank lines, comments 
+and newlines are removed. This makes the regexp matching in identifyDecl 
+much easier.
+
+If identifyDecl returns true and the decl finished with a {, the parser
+will skip all text till the matching } (ie nested {} is handled). 
+
+Of course, in the case of compound decls (structs, classes etc), this means 
+that we should return false since we want to parse everything in the class
+as well.
+
+The current node is stored in $cNode. A stack is maintained for parsed
+nodes, so everytime we enter a new compound node we push the current
+node onto the stack. the node will be popped once an compound end "};"
+is reached.
+
+Languages
+---------
+
+One root node is maintained per language. The correct node is selected
+depending on the file extension, using the getRoot sub.
+
+Libraries (kdocLib.pm)
+---------
+
+Libraries are now read directly into the parse tree and treated like syntax
+elements, except that their ExtSource property is set. The old library format
+is still supported, but the new one stores slightly more information, including
+the class hierarchy.
+
+
+AST routines (kdocAstUtil.pm)
+------------
+
+These are general routines that are used for all languages and output formats.
+They include generation of the hierarchy, finding of syntax nodes by identifier.
+Fully qualified and unqualified identifiers are supported.
+
+Output
+------
+
+Just like the old kdoc, the correct output module is loaded and called
+once all parsing is done and the tree has been post-processed as much
+as possible (hierarchy etc).
+
+Options
+-------
+
+The options have changed but are better, IMHO. Also, I now use Getopt::Long
+which makes option processing much easier and very robust.
+
+Thanks for reading this far.
+
+Sirtaj <taj@kde.org>
diff --git a/deal.II/contrib/kdoc/src/doc/Makefile.in b/deal.II/contrib/kdoc/src/doc/Makefile.in
new file mode 100644 (file)
index 0000000..955d049
--- /dev/null
@@ -0,0 +1,46 @@
+prefix=@prefix@
+Version = @Version@
+mandir=@mandir@
+docdir=@docdir@
+install=@INSTALL@
+
+MANPAGES = kdoc.1 makekdedoc.1 qt2kdoc.1
+MAINDOC = @srcdir@/kdoc.docbook @top_srcdir@/README
+
+all: ${MANPAGES}
+
+install:
+       ${install} -d $(DESTDIR)${mandir}
+       for file in ${MANPAGES}; do \
+               ${install} -m 644 $$file $(DESTDIR)${mandir}; \
+       done
+
+       ${install} -d ${DESTDIR}${docdir}
+       ${install} -m 644 ${MAINDOC} ${DESTDIR}${docdir}
+       for file in ${MAINDOC}; do \
+               ${install} -m 644 $$file $(DESTDIR)${docdir}; \
+       done
+
+
+kdoc.1: @srcdir@/kdoc.pod @top_srcdir@/Version
+       pod2man --center "KDOC Documentation System" --release "${Version}" \
+               @srcdir@/kdoc.pod > kdoc.1.local && mv kdoc.1.local kdoc.1
+
+makekdedoc.1: @top_srcdir@/makekdedoc @top_srcdir@/Version
+       pod2man --center "KDOC Documentation System" --release "${Version}" \
+               @top_srcdir@/makekdedoc > makekdedoc.1.local \
+               && mv makekdedoc.1.local makekdedoc.1
+
+qt2kdoc.1: @top_srcdir@/qt2kdoc @top_srcdir@/Version
+       pod2man --center "KDOC Documentation System" --release "${Version}" \
+               @top_srcdir@/qt2kdoc > qt2kdoc.1.local \
+               && mv qt2kdoc.1.local qt2kdoc.1
+
+clean:
+       rm -rf kdoc.1 makekdedoc.1 qt2kdoc.1
+
+
+html: kdoc.docbook
+       mkdir html; (cd html && jade -d \
+        /usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/html/docbook.dsl -t sgml \
+       ../$< )
diff --git a/deal.II/contrib/kdoc/src/doc/kdoc.docbook b/deal.II/contrib/kdoc/src/doc/kdoc.docbook
new file mode 100644 (file)
index 0000000..4ed2017
--- /dev/null
@@ -0,0 +1,444 @@
+<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
+]>
+<book lang="EN" ID="KDOC">
+
+<!-- This header contains all of the meta-information for the document such
+as Authors, publish date, the abstract, and Keywords -->
+
+<bookinfo>
+
+<title>The KDOC Handbook</title>
+<subtitle>Write developer documentation, easily and quickly</subtitle>
+
+<authorgroup>
+<author>
+<firstname>Sirtaj</firstname>
+<othername>Singh</othername>
+<surname>Kang</surname>
+</author>
+</authorGroup>
+<address>
+<email>taj@kde.org</email>
+</address>
+
+<keywordset>
+<keyword>KDOC</keyword>
+<keyword>C++</keyword>
+<keyword>C</keyword>
+<keyword>KDE Libraries</keyword>
+<keyword>Documentation</keyword>
+<keyword>API</keyword>
+<keyword>Literate Programming</keyword>
+</keywordset>
+
+<date>10/11/1999</date>
+<releaseinfo>2.0.0</releaseinfo>
+
+<revhistory>
+<revision>
+<revnumber>0.1</revnumber>
+<date>10/11/1999</date>
+<authorinitials>S.S.K</authorinitials>
+</revision>
+</revhistory>
+
+<!-- Abstract about this handbook -->
+
+<abstract>
+
+<para> <application>KDOC</application> generates documentation in a
+variety of formats, directly from C, C++ and IDL interface definitions.
+<application>KDOC</application> uses specially formatted comments in
+the source to allow customized documentation.  </para>
+
+</abstract>
+
+</bookinfo>
+
+
+<chapter ID="Introduction">
+                       <title>Introduction</title>
+
+<Sect1 id="whatiskdoc">
+                       <title>What is KDOC?</title>
+<para> <application>KDOC</application> generates documentation in a
+variety of formats, directly from C, C++ and IDL interface definitions.
+<application>KDOC</application> uses specially formatted comments in
+the source to allow customized documentation.  </para>
+
+<para>It is also very useful as a general class browser for libraries,
+since the output is quickly navigable and many index views are
+presented.</para>
+
+<para>KDOC is distributed under the GNU General Public License. In short,
+this allows you to modify and redistribute the package as much as you
+like, but all modifications will automatically also fall under the
+GNU General Public License. See the file <filename>COPYING</filename>
+that comes with the distribution for the full text version of the
+license.</para>
+</Sect1>
+
+<Sect1 id="features">
+                       <title>Features</title>
+       <ItemizedList Spacing="Normal">
+       <ListItem><para>Support for C, C++ and OMG CORBA IDL languages.
+       </para></ListItem>
+
+       <ListItem><para>Output in HTML, LaTeX, Manpage, Texinfo and
+               DocBook SGML formats. The DocBook format can in turn be
+               converted to various printable and online formats.
+       </para></ListItem>
+
+       <ListItem><para>Automatically works out many relationships
+       between objects and their properties, such as hierarchies,
+       overridden virtuals, non-instantiable (abstract) classes and more.
+       </para></ListItem>
+
+       <ListItem><para>Doc Comments are written in the javadoc style,
+               with many useful extensions for organizing, documenting
+               and presenting libraries.
+       </para></ListItem>
+
+       <ListItem><para>Supports a CPP (preprocessor) pass
+       via an external preprocessor, to expand macros and
+       <SystemItem>#ifdefs</SystemItem>.  </para></ListItem>
+
+       <ListItem><para>Support for the Qt GUI Toolkit's signal and
+       slot specifiers.</para></ListItem>
+
+       <ListItem><para>Cross-reference documentation generated for other
+       libraries. Links and class hierarchies that reference external
+       libraries are correctly shown.  </para></ListItem>
+
+       <ListItem><para>Includes <Application>makekdedoc</Application>,
+       an easy automake-like tool for generating documentation for
+       multiple libraries at once.</para></ListItem>
+
+       <ListItem><para>Includes <Application>qt2kdoc</Application>,
+       which allows you to link your documentation with the Qt GUI
+       Toolkit's HTML documentation as if it had been generated by
+               <Application>KDOC</Application> itself.
+       </para></ListItem>
+
+       <ListItem><para>An output mode that allows you to check for
+       errors or omissions in your documentation.</para></ListItem>
+       <ListItem><para>The application is written entirely in Perl, and
+       is therefore quite portable and extensible.  </para></ListItem>
+
+       </ItemizedList>
+</Sect1>
+
+<Sect1 ID="History">
+                       <title>History</title>
+<para>Torben Weis <email>weis@kde.org</email> wrote a perl script that
+proved how simple it was to parse the KDE Library headers to generate
+documentation that looked like the Qt documentation.  </para>
+
+<para>Sirtaj Singh Kang <email>taj@kde.org</email> took it upon himself to
+extend this program to turn it into a full-fledged application. He found
+out the hard way that while it takes 10% effort to parse 75% of source,
+the next 10% takes another 100%.  </para>
+
+<para>KDOC 1.0 still used some of Torben's source, but never really
+worked properly but was useful enough for a year or so.</para>
+
+<para>KDOC 2.0 is a complete rewrite of KDOC, and is much more extensible
+and robust, even though it has scores of new features that were impossible
+to put into 1.0.</para>
+
+</Sect1>
+
+
+</chapter>
+
+<chapter ID="usingkdoc">
+                       <title>Using KDOC</title>
+
+<sect1 ID="Support-and-Downloads">
+                       <title>Support and Downloads</title>
+
+<ItemizedList Spacing="Normal">
+
+<ListItem id="web">
+<epigraph><para>Web page</para></epigraph>
+<para><application>KDOC</application> has a web page at
+<ULink URL="http://www.ph.unimelb.edu.au/~ssk/kde/kdoc/">http://www.ph.unimelb.edu.au/~ssk/kde/kdoc/</ULink>. 
+It can be downloaded from there.
+</para>
+</ListItem>
+
+<ListItem id="cvs">
+<epigraph><para>Via KDE CVS or CVSUp</para></epigraph>
+<para>You can checkout KDOC from the KDE CVS server in the module 
+<userinput>kdoc</userinput>. This is the repository used for KDOC development,
+so it will always be up to date.
+</para>
+</ListItem>
+
+<ListItem id="mlist">
+<epigraph><para>Mailing List</para></epigraph>
+<para>There is a KDOC mailing list hosted by the KDE project, at 
+<email>kdoc-list@kde.org</email>. To subscribe, mail 
+<email>kdoc-list-request@kde.org</email>
+with <userinput>subscribe</userinput> in the message body (not the subject).
+</para>
+</ListItem>
+
+<ListItem id="faqref"><epigraph><para>The KDOC FAQ</para></epigraph>
+<para>
+The KDOC FAQ has answers to common questions and problems with KDOC.
+</para>
+</ListItem>
+
+<ListItem id="email">
+<epigraph><para>E-mail: The Last Resort</para></epigraph>
+<para>If all else fails, I will respond to decent questions via
+email, but I cannot promise prompt replies. Mail the KDOC "team" at
+<email>kdoc@kde.org</email>.</para>
+</ListItem>
+</ItemizedList>
+</sect1>
+
+
+<Sect1 ID="Installation">
+                       <title>Installation</title>
+<Sect2 id="sys">
+<title>Supported Environments</title>
+<para>KDOC requires <application>Perl 5.004</application> to function.
+Most environments where this is installed are supported by KDOC.
+</para>
+<para>KDOC has been reported to run to some extent on Win32 (NT/95/98),
+but you may encounter some problems with filenames. Also, you will probably
+have to hack the install scripts and file locations manually since the 
+configure script only works on UNIX.
+</para>
+</Sect2>
+<Sect2 id="build">
+               <title>Building the distribution</title>
+<para>
+The procedure for building KDOC is similar to most other GPL programs that
+come with a <application>configure</application> script.
+</para>
+<procedure>
+<step>
+<title>Unpack the distribution</title>
+<para>Unpack the distribution into a temporary directory. It will extract
+itself into its own directory. If you have downloaded the tar.bz2 version:
+<screen>
+<prompt>#</prompt> <userinput>bunzip2 &lt; kdoc-2.0a1.tar.bz2 | tar xf -</userinput>
+</screen>
+</para>
+<para>Or if you have downloaded the tar.gz version:
+<screen>
+<prompt>#</prompt> <userinput>gunzip &lt; kdoc-2.0a1.tar.gz | tar xf -</userinput>
+</screen>
+</para>
+<para>Replace the distribution file name in the above procedure with the one
+you have downloaded.</para>
+</step>
+<step>
+<title>Build the application</title>
+<para>This will configure KDOC to install itself in 
+<filename>/usr/local/</filename>:
+<screen>
+<prompt>#</prompt> <userinput>cd kdoc-2.0a1</userinput>
+<prompt>#</prompt> <userinput>./configure</userinput>
+</screen>
+</para>
+<para>To install it in a different directory, 
+say <filename>/opt/kdoc</filename>, add a prefix option to configure like this:
+<screen>
+<prompt>#</prompt> <userinput>./configure --prefix=/opt/kdoc</userinput>
+</screen>
+</para>
+</step>
+<step>
+<title>Perform the installation</title>
+<screen>
+<prompt>#</prompt> <userinput>make; make install</userinput>
+</screen>
+</step>
+<step>
+<title>Remove the temporary directory</title>
+<screen>
+<prompt>#</prompt> <userinput>cd ..</userinput>
+<prompt>#</prompt> <userinput>rm -rf kdoc-2.0a1</userinput>
+</screen>
+</step>
+</procedure>
+<para>Now kdoc should be installed on your system.</para>
+</Sect2>
+</Sect1>
+
+<Sect1 ID="cmdline">
+                       <title>KDOC at the command line</title>
+<abstract>
+<para>The most up-to-date source for command line options is always the
+man page that is distributed with the application. This section
+will provide a general overview of how to run the program.</para>
+</abstract>
+</Sect1>
+
+</chapter>
+
+
+<chapter ID="writingkdoc">
+                       <title>Writing Documentation</title>
+<Sect1 ID="Commenting-Source"><title>Commenting Source</title>
+<para>TODO: Explain doc comments. Explain tags. Examples.</para>
+</Sect1>
+<Sect1 ID="Commenting-Style">
+       <title>Tips on Style</title>
+<para>TODO: Various doc suggestions: internal/deprecated, short
+descriptions, link to Qt documentation guidelines.</para>
+</Sect1>
+</chapter>
+
+<chapter ID="faq">
+       <title>Frequently Asked Questions</title>
+<para>TODO: No questions, no answers.</para>
+</chapter>
+
+<chapter ID="AppendixA">
+       <title>Appendix A: Doc tag reference</title>
+<Sect1 id="tagsdoccmt">
+       <title>Doc Comments</title>
+       <para>TODO</para>
+</Sect1>
+<Sect1 id="tagscommon">
+       <title>Common tags</title>
+       <VariableList>
+       <VarListEntry>
+               <term>@li &lt;text&gt;</term>
+               <ListItem><para>A list item.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@internal</term>
+               <ListItem><para>Mark member as internal to the
+               library and not for external use.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@deprecated</term>
+               <ListItem><para>Marks member as obsolete.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@version &lt;string&gt;</term>
+               <ListItem><para>Provide version information about the
+               member. I normally set this to the RCS/CVS Id tag.
+               </para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@author &lt;string&gt;</term>
+               <ListItem><para>Specify the author.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@since &lt;string&gt;</term>
+               <ListItem><para>Specify the version of the API in which this
+               member was added.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@sect &lt;string&gt;</term>
+               <ListItem><para>A section heading, for grouping your doc
+               comment logically.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>&lt;pre&gt; text &lt;/pre&gt;</term>
+               <ListItem><para>A block of literal (preformatted) text,
+               useful for code examples.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@image &lt;path&gt;</term>
+               <ListItem><para>Embed an image in the output. This can be
+               set to a URL, but it is better to use a path if possible
+               since this will allow the image to be included in other
+               formats in the future.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@see &lt;ref&gt;,...</term>
+               <ListItem><para>Links to related information.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@ref &lt;ref&gt;</term>
+               <ListItem><para>Like @see, but inline, so it can be used
+               within a text paragraph. Also, only one member can be
+               referenced at a time, so you will have to include multiple
+               @ref tags for multiple members.</para></ListItem>
+       </VarListEntry>
+
+       </VariableList>
+</Sect1>
+<Sect1 id="tagslibdoc">
+       <title>Tags for Library Documentation</title>
+       <para>To provide documentation for the entire library, use the
+       @libdoc tag within a doc comment. If this appears in a doc comment,
+       the comment is associated with the library instead of with the 
+       following syntax member.
+       </para>
+       <VariableList>
+       <VarListEntry>
+               <term>@libdoc &lt;string&gt;</term>
+               <ListItem><para>Marks a doc comment as documentation for
+               the library. The string is used as the title of the
+               library.</para></ListItem>
+       </VarListEntry>
+       </VariableList>
+</Sect1>
+
+<Sect1 id="tagsclass">
+               <title>Tags for Classes</title>
+
+       <VariableList>
+       <VarListEntry>
+               <term>@short &lt;string&gt;</term>
+               <ListItem><para>Short description of the class, one
+               sentence long.</para>
+               <para>If class documentation is present but no short
+               description is specified, the first sentence (up to and
+               including the first period) is used instead.
+               </para>
+               </ListItem>
+       </VariableList>
+
+</Sect1>
+<Sect1 id="tagsfun">
+               <title>Tags for Functions</title>
+       <VariableList>
+       <VarListEntry>
+               <term>@param &lt;paramname&gt; &lt;text&gt;</term>
+               <ListItem><para>Documentation for a parameter. 
+               No check is done whether the parameter name specified
+               is actually a parameter of the function.
+               </para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@return &lt;text&gt;</term>
+               <ListItem><para>Documentation for the value returned by
+               the function.</para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@throws &lt;ref&gt;,...</term>
+               <ListItem><para>Define the exceptions that may be thrown
+               from this function. Synonyms are: @exception and @raises.
+               </para></ListItem>
+       </VarListEntry>
+       <VarListEntry>
+               <term>@param &lt;paramname&gt; &lt;text&gt;</term>
+               <ListItem><para>Documentation for a parameter. 
+               No check is done whether the parameter name specified
+               is actually a parameter of the function.
+               </para></ListItem>
+       </VarListEntry>
+       </VariableList>
+</Sect1>
+</chapter>
+
+<chapter ID="AppendixB"><title>Appendix B: Utilities</title>
+<Sect1 id="qt2kdoc"><title>qt2kdoc: Link with Qt HTML documentation</title>
+</Sect1>
+<Sect1 id="makekdedoc"><title>makekdedoc: Generate docs for KDELIBS and other groups of libraries</title>
+</Sect1>
+</chapter>
+
+<chapter ID="AppendixC"><title>Appendix B: Other useful tools</title></chapter>
+
+</book>
diff --git a/deal.II/contrib/kdoc/src/doc/kdoc.pod b/deal.II/contrib/kdoc/src/doc/kdoc.pod
new file mode 100644 (file)
index 0000000..b784557
--- /dev/null
@@ -0,0 +1,203 @@
+
+=head1 NAME
+
+KDOC -- Programmers' Documentation Extraction and Generation Tool
+
+=head1 SYNOPSIS
+
+       kdoc [-DqpieaP] [-f format] [-n libname] [-d outdir] [-u url] [-l lib]
+
+       kdoc [--help]
+
+       kdoc [--version]
+
+=head1 DESCRIPTION
+
+KDOC uses specially formatted comments in your C++ headers and CORBA IDL
+files to create cross-referenced documentation in various formats. 
+
+KDOC can also correctly handle "signal" and "slot" specifiers as used by the
+Qt GUI Toolkit.
+
+=head1 EXAMPLES
+
+       kdoc -f html -d /home/web/komdoc -n kom *.idl
+       kdoc -d /home/web/kdecore 
+               -u "http://www.mydomain/kdecore/" 
+               -n kdecore ~/kdelibs/kdecore/*.h -lqt
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--stdin>, B<-i>
+
+Read the filenames to process from standard input. Ignored if
+filenames are specified at the command line.
+
+=item B<--format> <string>, B<-f> <string>
+
+Generate output in the specific format. This can be used many times to
+generate documentation in multiple formats. The default format is "html".
+
+See the OUTPUT FORMAT OPTIONS section for a list of available formats.
+
+=item B<--outputdir> <path>, B<-d> <path>
+
+Write output in the specified path.
+
+=item B<--url> <url>, B<-u> <url>
+
+The URL which will be used for links when cross-referencing with this library.
+
+=item B<--name> <string>, B<-n> <string>
+
+Set the name of the library being processed, eg "kdecore"
+If no name is set, no index file is produced.
+
+=item B<--xref> <library>, B<-l> <library>
+
+Cross-reference with the specified library. This will allow referencing
+of classes etc that exist in the linked library. This option can be
+specified multiple times.
+
+For linking to work, you need to have generated documentation for the
+linked library with kdoc, so that the necessary index file is produced.
+
+=item B<--libdir> <path>, B<-L> <path>
+
+Set the directory that will be used to store the index files generated
+for cross-referencing. This is also used to search for index files for
+xref. The default is $HOME/.kdoc.
+
+=item B<--compress>, B<-z>
+
+Compress generated KDOC index files with gzip to save space.
+
+=item B<--private>, B<-p>
+
+Document all private members. These are not documented by default.
+
+=item B<--skip-internal>, B<-i>
+
+Do not document internal members. They are documented as internal by default.
+
+=item B<--skip-deprecated>, B<-e>
+
+Do not document deprecated members. They are documented as deprecated by 
+default.
+
+=item B<--strip-h-path>
+
+Strip the path from the filenames in the output.
+
+=back
+
+=head1 PREPROCESSOR OPTIONS
+
+=over 4
+
+=item B<--cpp>, B<-P>
+
+Pass each source file through the C preprocessor. Currently g++
+is required for this, but this requirement will change before
+2.0. Directories for inclusion in the preprocessor header search path
+can be specified via the B<-I> option.
+
+=item B<-cppcmd> <command>, B<-C> <command>
+
+Specify the preprocessor command that will be used. The default is:
+
+       g++ -Wp,-C -E
+
+All specified B<-I> paths will be appended to the command. This option
+quietly enables the B<-P> option.
+
+=item B<--includedir> <path>, B<-I> <path>
+
+Add a directory to the preprocessor's header search paths. Requires the
+B<-P> option. This option can be specified multiple times.
+
+=back
+
+=head1 OUTPUT FORMAT OPTIONS
+
+=over 4
+
+=item B<html>
+
+Output documentation in HTML format. This is the default.
+
+=item B<latex>
+
+Output documentation as a LaTeX document. (unimplemented)
+
+=item B<man>
+
+Output documentation as man pages. (unimplemented)
+
+=item B<texinfo>
+
+Output documentation in texinfo format. You must set the library name
+with the B<-n> option for the output to be generated.
+
+=item B<docbook>
+
+Output documentation in the DocBook SGML format. You must set the library
+name with the B<-n> option for the output to be generated.
+
+=item B<check>
+
+Print a report about the documentation, eg undocumented classes
+and functions.
+
+=back
+
+=head1 CROSS-REFERENCING LIBRARIES
+
+=head1 FILES
+
+=over 4
+
+=item B<*.kdoc>, B<*.kdoc.gz>
+
+These are files that contain information about a library that has been
+processed with kdoc. It is read for cross-referencing with other libraries
+when the B<-l> option is used.
+
+The B<.gz> extension signifies gzipped cross-reference files. kdoc is
+capable of reading these, and generates them when the B<-z> option is used.
+
+=back
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item B<KDOCLIBS>
+
+If this is set, it is used as the default for the directory where generated
+cross-reference index files are saved. See also the B<--libdir> option.
+
+=back
+
+=head1 SEE ALSO
+
+See L<qt2kdoc> for info on linking with the Qt docs, and L<makekdedoc> for
+info on generating documentation for the KDE libraries.
+
+=head1 BUGS
+
+Lots and Lots. Please send reports to the address B<kdoc@kde.org>.
+
+=head1 AUTHOR
+
+Sirtaj Singh Kang <taj@kde.org>. B<KDOC> has a web page at:
+       http://www.ph.unimelb.edu.au/~ssk/kde/kdoc
+
+=head1 COPYRIGHT
+
+The KDOC tool is Copyright (c) 1998 by Sirtaj Singh Kang. KDOC is free
+software under the conditions of the GNU Public License.
+
+=cut
diff --git a/deal.II/contrib/kdoc/src/findperl b/deal.II/contrib/kdoc/src/findperl
new file mode 100755 (executable)
index 0000000..451758d
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+test -f perlbin && rm perlbin
+
+for p in `echo $PATH | tr ":" " "`
+do
+       if [ -x $p/perl ]
+       then
+               if $p/perl -e 'require 5.000;' 
+               then
+                       echo $p/perl > perlbin
+                       exit 0
+               fi
+       fi
+       
+done
+exit 1
diff --git a/deal.II/contrib/kdoc/src/install-sh b/deal.II/contrib/kdoc/src/install-sh
new file mode 100755 (executable)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/deal.II/contrib/kdoc/src/kdoc b/deal.II/contrib/kdoc/src/kdoc
new file mode 100755 (executable)
index 0000000..b7c0ca2
--- /dev/null
@@ -0,0 +1,1335 @@
+#!/usr/local/bin/perl
+
+# KDOC -- C++ and CORBA IDL interface documentation tool.
+# Sirtaj Singh Kang <taj@kde.org>, Jan 1999.
+# $Id$
+
+# All files in this project are distributed under the GNU General
+# Public License. This is Free Software.
+
+require 5.000;
+
+use Carp;
+use Getopt::Long;
+use File::Basename;
+use strict;
+
+use Ast;
+
+use kdocUtil;
+use kdocAstUtil;
+use kdocParseDoc;
+
+use vars qw/ %rootNodes $declNodeType %options @formats_wanted
+        @includeclasses $includeclasses
+       $libdir $libname $outputdir @libs $striphpath $doPrivate $readstdin
+       $Version $quiet $debug $parseonly $currentfile $cSourceNode $exe
+       %formats %flagnames $rootNode @classStack $cNode 
+       $lastLine $docNode @includes $cpp $defcppcmd $cppcmd $inExtern
+       %stats /;
+     
+## globals
+
+%rootNodes = ();                       # root nodes for each file type
+$declNodeType = undef;                 # last declaration type
+
+# All options
+
+%options = ();                         # hash of options (set getopt below)
+@formats_wanted = ();
+$libdir = $ENV{KDOCLIBS};
+$libname = "";
+$outputdir = ".";
+@libs = ();                            # list of includes
+$striphpath = 0;
+
+@includeclasses = ();                     # names of classes to include
+$includeclasses = "";
+
+$doPrivate = 0;
+$Version = "$Version\$";
+
+$quiet = 0;
+$debug = 0;
+$parseonly = 0;
+
+$currentfile = "";
+
+$cpp = 0;
+$defcppcmd = "g++ -Wp,-C -E";
+$cppcmd = "";
+
+$exe = basename $0;
+
+# Supported formats
+%formats = ( "html" => "kdocCxxHTML", "latex" => "kdocCxxLaTeX",
+       "texinfo" => "kdoctexi", "docbook" => "kdocCxxDocbook",
+       "check" => "kdocDocHelper", "idlhtml" => "kdocIDLhtml" );
+
+# these are for expansion of method flags
+%flagnames = ( v => 'virtual', 's' => 'static', p => 'pure',
+       c => 'const', l => 'slot', i => 'inline', n => 'signal' );
+       
+
+=head1 KDOC -- Source documentation tool 
+
+       Sirtaj Singh Kang <taj@kde.org>, Dec 1998.
+
+=cut
+
+# read options
+
+Getopt::Long::config qw( no_ignore_case permute bundling auto_abbrev );
+
+GetOptions( \%options,
+       "format|f=s", \@formats_wanted,
+       "url|u=s",
+        "skip-internal|i",
+       "skip-deprecated|e", 
+       "document-all|a",
+       "compress|z",
+
+       # HTML options
+       "html-cols=i",
+       "html-logo=s",
+       
+       "strip-h-path", \$striphpath,
+       "outputdir|d=s", \$outputdir,
+       "stdin|i",      \$readstdin,
+       "name|n=s",     \$libname,
+       "help|h",       \&show_usage,
+       "version|v|V",  \&show_version,
+       "private|p",    \$doPrivate,
+       "libdir|L=s",   \$libdir, 
+       "xref|l=s",     \@libs,
+       "classes|c=s",    \@includeclasses,
+       
+       "cpp|P",        \$cpp,
+       "cppcmd|C",     \$cppcmd,
+       "includedir|I=s", \@includes,
+
+       "quiet|q",      \$quiet,
+       "debug|D",      \$debug,
+       "parse-only",   \$parseonly )
+               || exit 1;
+
+$| = 1 if $debug;
+
+# preprocessor settings
+
+if ( $cppcmd eq "" ) {
+       $cppcmd = $defcppcmd;
+}
+else {
+       $cpp = 1;
+}
+
+if ($#includeclasses>=0)
+{
+    $includeclasses = join (" ", @includeclasses);
+    print "Using Classes: $includeclasses\n" unless $quiet;
+}
+
+if ( $#includes >= 0 && !$cpp ) {
+       die "$exe: --includedir requires --cpp\n";
+}
+
+# Check output formats. HTML is the default
+if( $#formats_wanted < 0 ) {
+       push @formats_wanted, "html";
+}
+
+foreach my $format ( @formats_wanted ) {
+       die "$exe: unsupported format '$format'.\n" 
+               if !defined $formats{$format};
+}
+
+# Check if there any files to process.
+# We do it here to prevent the libraries being loaded up first.
+
+checkFileArgs();
+
+# work out libdir. This is created by kdocLib:writeDoc when
+# required.
+$libdir = $ENV{HOME}."/.kdoc" unless $libdir ne "";
+
+
+######
+###### main program
+######
+       readLibraries();
+       parseFiles();
+
+       if ( $parseonly ) {
+               print "\n\tParse Tree\n\t------------\n\n";
+               kdocAstUtil::dumpAst( $rootNode );
+       }
+       else {
+               writeDocumentation();
+               writeLibrary() unless $libname eq "";
+       }
+
+       kdocAstUtil::printDebugStats() if $debug;
+
+       exit 0;
+######
+
+sub checkFileArgs
+{
+       return unless $#ARGV < 0;
+
+       die "$exe: no input files.\n" unless $readstdin;
+
+       # read filenames from standard input
+       while (<STDIN>) {
+               chop;
+               $_ =~ s,\\,/,g; # back to fwd slash (for Windows)
+               foreach my $file ( split( /\s+/, $_ ) ) {
+                       push @ARGV, $file;
+               }
+       }
+}
+
+sub readLibraries
+{
+       return if $#libs < 0;
+
+       require kdocLib;
+       foreach my $lib ( @libs ) {
+               print "$exe: reading lib: $lib\n" unless $quiet;
+
+               my $relpath = exists $options{url} ? 
+                       $options{url} : $outputdir;
+               kdocLib::readLibrary( \&getRoot, $lib, $libdir, $relpath );
+       }
+}
+
+sub parseFiles
+{
+       foreach $currentfile ( @ARGV ) {
+               my $lang = "CXX";
+
+               if ( $currentfile =~ /\.idl\s*$/ ) {
+                       # IDL file
+                       $lang = "IDL";
+
+                       open( INPUT, "$currentfile" ) 
+                               || croak "Can't read from $currentfile";
+               }
+               # assume cxx file
+               elsif( $cpp ) {
+                       # pass through preprocessor
+                       my $cmd = $cppcmd;
+                       foreach my $dir ( @includes ) {
+                               $cmd .= " -I $dir ";
+                       }
+                       open( INPUT, $cmd." -DQOBJECTDEFS_H $currentfile|" )
+                               || croak "Can't preprocess $currentfile";
+               }
+               else {
+                       open( INPUT, "$currentfile" ) 
+                               || croak "Can't read from $currentfile";
+               }
+
+               print "$exe: processing $currentfile\n" unless $quiet;
+
+               # reset vars
+               $rootNode = getRoot( $lang );
+
+
+               # add to file lookup table
+               my $showname = $striphpath ? basename( $currentfile )
+                                               : $currentfile;
+
+               $cSourceNode = Ast::New( $showname );
+               $cSourceNode->AddProp( "NodeType", "source" );
+               $cSourceNode->AddProp( "Path", $currentfile );
+               $rootNode->AddPropList( "Sources", $cSourceNode );
+
+
+               # reset state
+               @classStack = ();
+               $cNode = $rootNode;
+               $inExtern = 0;
+
+               # parse
+               my $k = undef;
+               while ( defined ($k = readDecl()) ) {
+                       print "\nDecl: <$k>[$declNodeType]\n" if $debug;
+                       if( identifyDecl( $k ) && $k =~ /{/ ) {
+                               readCxxCodeBlock();
+                       } 
+               }
+               close INPUT;
+       }
+}
+
+
+sub writeDocumentation
+{
+       foreach my $node ( values %rootNodes ) {
+               # postprocess
+               kdocAstUtil::linkNamespaces( $node );
+               kdocAstUtil::makeInherit( $node, $node );
+               kdocAstUtil::linkReferences( $node, $node );
+               kdocAstUtil::calcStats( \%stats, $node, $node );
+
+               # write
+               no strict "refs";
+               foreach my $format ( @formats_wanted ) {
+                       my $pack = $formats{ $format };
+                       require $pack.".pm";
+
+                       print "Generating documentation in $format ",
+                               "format...\n" unless $quiet;
+
+                       my $f = "$pack\::writeDoc";
+                       &$f( $libname, $node, $outputdir, \%options );
+               }
+       }
+}
+
+sub writeLibrary
+{
+       if( $libname ne "" ) {
+               require kdocLib;
+               foreach my $lang ( keys %rootNodes ) {
+                       my $node = $rootNodes{ $lang };
+                       kdocLib::writeDoc( $libname, $node, $lang, $libdir,
+                                       $outputdir, $options{url},
+                                       exists $options{compress} ? 1 : 0 );
+               }
+       }
+}
+
+###### Parser routines
+
+=head2 readSourceLine
+
+       Returns a raw line read from the current input file.
+       This is used by routines outside main, since I don't know
+       how to share fds.
+
+=cut
+
+sub readSourceLine
+{
+       return <INPUT>;
+}
+
+=head2 readCxxLine
+
+       Reads a C++ source line, skipping comments, blank lines,
+       preprocessor tokens and the Q_OBJECT macro
+
+=cut
+
+sub readCxxLine
+{
+       my( $p );
+       my( $l );
+       
+       while( 1 ) {
+               return undef if !defined ($p = <INPUT>);
+
+               $p =~ s#//.*$##g;                       # C++ comment
+               $p =~ s#/\*(?!\*).*?\*/##g;             # C comment
+
+               # join all multiline comments
+               if( $p =~ m#/\*(?!\*)#s ) {
+                       # unterminated comment
+LOOP:
+                       while( defined ($l = <INPUT>) ) {
+                               $l =~ s#//.*$##g;               # C++ comment
+                               $p .= $l;
+                               $p =~ s#/\*(?!\*).*?\*/##sg;    # C comment
+                               last LOOP unless $p =~ m#(/\*(?!\*))|(\*/)#sg;
+                       }
+               }
+
+               next if ( $p =~ /^\s*$/s                # blank lines
+                       || $p =~ /^\s*Q_OBJECT/         # QObject macro
+                       );
+
+               # remove all preprocessor macros
+               if( $p =~ /^\s*#\s*(\w+)/ ) {
+                       if ($p =~ /^\s*#\s*[0-9]+\s*\".*$/ 
+                                       && not($p =~ /\"$currentfile\"/)) {
+                               # include file markers
+                               while( <INPUT> ) {
+                                       last if(/\"$currentfile\"/);
+                                               print "Overread $_" if $debug;
+                               };
+                               print "Cont: $_" if $debug;
+                       } 
+                       else {
+                               # multiline macros
+                               while ( defined $p && $p =~ m#\\\s*$# ) {
+                                       $p = <INPUT>;
+                               }
+                       }
+                       next;
+               }
+
+               $lastLine = $p;
+               return $p;
+       }
+}
+
+=head2 readCxxCodeBlock
+
+       Reads a C++ code block (recursive curlies), returning the last line
+       or undef on error.
+
+       Parameters: none
+
+=cut
+
+sub readCxxCodeBlock
+{
+# Code: begins in a {, ends in }\s*;?
+# In between: cxx source, including {}
+       my ( $count ) = 0;
+       my $l = undef;
+       
+       if ( defined $lastLine ) {
+               print "lastLine: '$lastLine'" if $debug;
+
+               my $open = kdocUtil::countReg( $lastLine, "{" );
+               my $close = kdocUtil::countReg( $lastLine, "}" );
+               $count = $open - $close;
+
+               return $lastLine if ( $open || $close) && $count == 0;
+       }
+
+       # find opening brace
+       if ( $count == 0 ) {
+               while( $count == 0 ) {
+                       $l = readCxxLine();
+                       return undef if !defined $l;
+                       $l =~ s/\\.//g;
+                       $l =~ s/'.?'//g;
+                       $l =~ s/".*?"//g;
+
+                       $count += kdocUtil::countReg( $l, "{" );
+                       print "c ", $count, " at '$l'" if $debug;
+               }
+               $count -= kdocUtil::countReg( $l, "}" );
+       }
+
+       # find associated closing brace
+       while ( $count > 0 ) {
+               $l = readCxxLine();
+               croak "Confused by unmatched braces" if !defined $l;
+               $l =~ s/\\.//g;
+               $l =~ s/'.?'//g;
+               $l =~ s/".*?"//g;
+
+               my $add = kdocUtil::countReg( $l, "{" );
+               my $sub = kdocUtil::countReg( $l, "}" );
+               $count += $add - $sub;
+
+               print "o ", $add, " c ", $sub, " at '$l'" if $debug;
+       }
+
+       undef $lastLine;
+       return $l;
+}
+
+=head2 readDecl
+
+       Returns a declaration and sets the $declNodeType variable.
+
+       A decl starts with a type or keyword and ends with [{};]
+       The entire decl is returned in a single line, sans newlines.
+
+       declNodeType values: undef for error, "a" for access specifier,
+       "c" for doc comment, "d" for other decls.
+
+       readCxxLine is used to read the declaration.
+
+=cut
+
+sub readDecl
+{
+       undef $declNodeType;
+       my $l = readCxxLine();
+       my ( $decl ) = "";
+
+       if( !defined $l ) {
+               return undef;
+       }
+       elsif ( $l =~ /^\s*(private|public|protected|signals)
+               (\s+\w+)?\s*:/x ) { # access specifier
+               $declNodeType = "a";
+
+               return $l;
+       }
+       elsif ( $l =~ m#^\s*/\*\*# ) {  # doc comment
+               $declNodeType = "c";
+               return $l;
+       }
+
+       do {
+               $decl .= $l;
+
+               if ( $l =~ /[{};]/ ) {
+                       $decl =~ s/\n/ /gs;
+                       $declNodeType = "d";
+                       return $decl;
+               }
+               return undef if !defined ($l = readCxxLine());
+
+       } while ( 1 );
+}
+
+#### AST Generator Routines
+
+=head2 getRoot
+
+       Return a root node for the given type of input file.
+
+=cut
+
+sub getRoot
+{
+       my $type = shift;
+       carp "getRoot called without type" unless defined $type;
+
+       if ( !exists $rootNodes{ $type } ) {
+               my $node = Ast::New( "Global" );        # parent of all nodes
+               $node->AddProp( "NodeType", "root" );
+               $node->AddProp( "RootType", $type );
+               $node->AddProp( "Compound", 1 );
+               $node->AddProp( "KidAccess", "public" );
+
+               $rootNodes{ $type } = $node;
+       }
+       print "getRoot: call for $type\n" if $debug;
+
+       return $rootNodes{ $type };
+}
+
+=head2 identifyDecl
+
+       Parameters: decl
+
+       Identifies a declaration returned by readDecl. If a code block
+       needs to be skipped, this subroutine returns a 1, or 0 otherwise.
+
+=cut
+
+sub identifyDecl
+{
+       my( $decl ) = @_;
+
+       my $newNode = undef;
+       my $skipBlock = 0;
+
+       # Doc comment
+       if ( $declNodeType eq "c" ) {
+               $docNode = kdocParseDoc::newDocComment( $decl );
+
+               # if it's the main doc, it is attached to the root node
+               if ( defined $docNode->{LibDoc} ) {
+                       kdocParseDoc::attachDoc( $rootNode, $docNode,
+                               $rootNode );
+                       undef $docNode;
+               }
+
+       }
+       elsif ( $declNodeType eq "a" ) {
+               newAccess( $decl );
+       }
+
+       # Typedef struct/class
+       elsif ( $decl =~ /^\s*typedef
+                       \s+(struct|union|class|enum)
+                       \s*([_\w\:]*)
+                       \s*([;{]) 
+                       /xs ) {
+               my ($type, $name, $endtag, $rest ) = ($1, $2, $3, $' );
+               $name = "--" if $name eq "";
+
+               warn "typedef '$type' n:'$name'\n" if $debug;
+
+               if ( $rest =~ /}\s*([\w_]+(?:::[\w_])*)\s*;/ ) {
+                       # TODO: Doesn't parse members yet!
+                       $endtag = ";";
+                       $name = $1;
+               }
+
+               $newNode = newTypedefComp( $type, $name, $endtag );
+       }
+
+       # Typedef
+       elsif ( $decl =~ /^\s*typedef\s+
+                       (.*?\s*[\*&]?)          # type
+                       \s*([-\w_\:]+)          # name
+                       \s*[{;]\s*$/xs  ) {
+
+               print "Typedef: <$1> <$2>\n" if $debug;
+               $newNode = newTypedef( $1, $2 );
+       }
+
+       # Enum
+       elsif ( $decl =~ /^\s*enum(\s+[-\w_:]*)?\s*\{(.*)/s  ) {
+
+               print "Enum: <$1>\n" if $debug;
+               my $enumname = defined $2 ? $1 : "";
+
+               $newNode = newEnum( $enumname );
+       }
+
+       # Class/Struct
+       elsif ( $decl =~ /^\s*((?:template\s*<.*>)?)      # 1 template
+                                       \s*(class|struct|union|namespace) # 2 struct type
+                                       \s+([\w_]+                        # 3 name
+                                                       (?:<[\w_ :,]+?>)?                 # maybe explicit template
+                                                                       #    (eat chars between <> non-hungry)
+                                                       (?:::[\w_]+)*                 #   maybe nested
+                                          )
+                                       (.*?)                             # 4 inheritance
+                                       ([;{])/xs ) {                     # 5 rest
+
+               print "Class: [$1]\n\t[$2]\n\t[$3]\n\t[$4]\n\t[$5]\n" if $debug;
+               my ( $tmpl, $ntype, $name, $rest, $endtag ) =
+                       ( $1, $2, $3, $4, $5 );
+
+               if ($includeclasses)
+               {
+                   if (! ($includeclasses =~ /$name/) )
+                   {
+                       return 1;
+                       
+                   }
+               }
+
+               my @inherits = ();
+
+               $tmpl =~ s/<(.*)>/$1/ if $tmpl ne "";
+
+               if(  $rest =~ /^\s*:\s*/ ) {
+                       # inheritance 
+                       $rest = $';
+                       @inherits = parseInheritance( $rest );
+               }
+
+               $newNode = newClass( $tmpl, $ntype, 
+                       $name, $endtag, @inherits );
+       }
+       # IDL compound node
+       elsif( $decl =~ /^\s*(module|interface|exception) # struct type
+                       \s+([-\w_]+)                    # name
+                       (.*?)                           # inheritance?
+                       ([;{])/xs ) {
+               
+               my ( $type, $name, $rest, $fwd, $complete ) 
+                       = ( $1, $2, $3, $4 eq ";" ? 1 : 0,
+                               0 );
+               my @in = ();
+               print "IDL: [$type] [$name] [$rest] [$fwd]\n" if $debug;
+
+               if( $rest =~ /^\s*:\s*/ ) {
+                       $rest = $';
+                       $rest =~ s/\s+//g;
+                       @in = split ",", $rest;
+               }
+               if( $decl =~ /}\s*;/ ) {
+                       $complete = 1;
+               }
+
+               $newNode = newIDLstruct( $type, $name, $fwd, $complete, @in );
+       }
+       # Method
+       elsif ( $decl =~ /^\s*([^=]+?(?:operator\s*(?:\(\)|.?=)\s*)?) # ret+nm
+               \( (.*?) \)             # parameters
+               \s*((?:const)?)\s*
+               \s*((?:=\s*0(?:L?))?)\s*        # Pureness. is "0L" allowed?
+               \s*[;{]+/xs ) { # rest
+
+               print "Method: R+N:[$1]\n\tP:[$2]\n\t[$3]\n" if $debug;
+
+               my $tpn = $1; # type + name
+               my $params = $2;
+
+               my $const = $3 eq "" ? 0 : 1;
+               my $pure = $4 eq "" ? 0 : 1;
+
+               if ( $tpn =~ /((?:\w+\s*::\s*)?operator.*?)\s*$/        # operator
+                                       || $tpn =~ /((?:\w*\s*::\s*~?)?[-\w:]+)\s*$/ ) { # normal
+                               my $name = $1;
+                               $tpn = $`;
+                               $newNode = newMethod( $tpn, $name, 
+                                                               $params, $const, $pure );
+               }
+
+               $skipBlock = 1; # FIXME check end token before doing this!
+       }
+       # Using: import namespace
+       elsif ( $decl =~ /^\s*using\s+namespace\s+(\w+)/ ) {
+               newNamespace( $1 );
+
+       }
+
+       # extern block
+       elsif ( $decl =~ /^\s*extern\s*"(.*)"\s*{/ ) {
+               $inExtern = 1 unless $decl =~ /}/;
+       }
+
+       # Single variable
+       elsif ( $decl =~ /^
+                       \s*( (?:[\w_:]+(?:\s+[\w_:]+)*? )# type
+                               \s*(?:<.+>)?            # template
+                               \s*(?:[\&\*])?          # ptr or ref
+                               (?:\s*(?:const|volatile))* )
+                       \s*([\w_:]+)                    # name
+                       \s*( (?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? ) # array
+                       \s*((?:=.*)?)                   # value
+                       \s*([;{])\s*$/xs ) {
+               my $type = $1;
+               my $name = $2;
+               my $arr  = $3;
+               my $val  = $4;
+               my $end  = $5;
+
+               print "Var: [$name] type: [$type$arr] val: [$val]\n" 
+                               if $debug;
+
+               $newNode = newVar( $type.$arr, $name, $val );
+
+               $skipBlock = 1 if $end eq '{';
+
+       }
+
+       # Multi variables
+       elsif ( $decl =~ m/^
+               \s*( (?:[\w_:]+(?:\s+[\w_:]+)*? )       # type
+               \s*(?:<.+>)?)                                           # template
+
+               \s*( (?:\s*(?: [\&\*][\&\*\s]*)?        # ptr or ref
+                       [\w_:]+)                                                # name
+               \s*(?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? # array
+               \s*(?:,                                                         # extra vars
+                       \s*(?: [\&\*][\&\*\s]*)?                # ptr or ref
+                       \s*(?:[\w_:]+)                                  # name
+                       \s*(?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? # array
+                       )* 
+               \s*(?:=.*)?)                                            # value
+               \s*[;]/xs ) {
+
+               my $type = $1;
+               my $names = $2;
+               my $end = $3;
+               my $doc = $docNode;
+
+               print "Multivar: type: [$type] names: [$names] \n" if $debug;
+
+               foreach my $vardecl ( split( /\s*,\s*/, $names ) ) {
+                       next unless $vardecl =~ m/
+                       \s*((?: [\&\*][\&\*\s]*)?)      # ptr or ref
+                       \s*([\w_:]+)                    # name
+                       \s*( (?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? ) # array
+                       \s*((?:=.*)?)                   # value
+                               /xs;
+                       my ($ptr, $name, $arr, $val) = ($1, $2, $3, $4);
+
+                       print "Split: type: [$type$ptr$arr] ",
+                               " name: [$name] val: [$val] \n" if $debug;
+
+                       my $node = newVar( $type.$ptr.$arr, $name, $val );
+
+                       $docNode = $doc;        # reuse docNode for each
+                       postInitNode( $node ) unless !defined $node;
+               }
+
+               $skipBlock = 1 if $end eq '{';
+       }
+       # end of an "extern" block
+       elsif ( $decl =~ /^\s*}\s*$/ ) {
+               $inExtern = 0;
+       }
+       # end of an in-block declaration
+       elsif ( $decl =~ /^\s*}\s*(.*?)\s*;\s*$/ ) {
+
+               if ( $cNode->{astNodeName} eq "--" ) {
+                       # structure typedefs should have no name preassigned.
+                       # If they do, then the name in 
+                       # "typedef struct <name> { ..." is kept instead.
+                       # TODO: Buglet. You should fix YOUR code dammit. ;)
+
+
+                       $cNode->{astNodeName} = $1;
+                       my $siblings = $cNode->{Parent}->{KidHash};
+                       undef $siblings->{"--"};
+                       $siblings->{ $1 } = $cNode;
+               }
+
+               if ( $#classStack < 0 ) {
+                       confess "close decl found, but no class in stack!" ;
+                       $cNode = $rootNode;
+               }
+               else {
+                       $cNode = pop @classStack;
+                       print "end decl: popped $cNode->{astNodeName}\n" 
+                               if $debug;
+               }
+       }
+       # unidentified block start
+       elsif ( $decl =~ /{/ ) {
+               print "Unidentified block start: $decl\n" if $debug;
+               $skipBlock = 1;
+       }
+       else {
+
+               ## decl is unidentified.
+               warn "Unidentified decl: $decl\n";
+       }
+
+       # once we get here, the last doc node is already used.
+       # postInitNode should NOT be called for forward decls
+       postInitNode( $newNode ) unless !defined $newNode;
+
+       return $skipBlock;
+}
+
+sub postInitNode
+{
+       my $newNode = shift;
+
+       carp "Cannot postinit undef node." if !defined $newNode;
+
+       # The reasoning here:
+       # Forward decls never get a source node.
+       # Once a source node is defined, don't assign another one.
+
+       if ( $newNode->{NodeType} ne "Forward" && !defined $newNode->{Source}) {
+               $newNode->AddProp( "Source", $cSourceNode );
+       }
+       elsif ($debug) {
+               print "postInit: skipping fwd: $newNode->{astNodeName}\n";
+       }
+
+       if( defined $docNode ) {
+               kdocParseDoc::attachDoc( $newNode, $docNode, $rootNode );
+               undef $docNode;
+       }
+}
+
+
+##### Node generators
+
+=head2 newEnum
+
+       Reads the parameters of an enumeration.
+
+       Returns the parameters, or undef on error.
+
+=cut
+
+sub newEnum
+{
+       my ( $enum ) = @_;
+       my $k = undef;
+       my $params = "";
+
+       $k = $lastLine if defined $lastLine;
+
+       if( defined $lastLine && $lastLine =~ /{/ ) {
+               $params = $';
+               if ( $lastLine =~ /}(.*?);/ ) {
+                       return initEnum( $enum, $1, $params );
+               }
+       }
+
+       while ( defined ( $k = readCxxLine() ) ) {
+               $params .= $k;
+
+               if ( $k =~ /}(.*?);/ ) {
+                       return initEnum( $enum, $1, $params );
+               }
+       }
+
+       return undef;
+}
+
+=head2 initEnum
+
+       Parameters: name, (ref) params
+
+       Returns an initialized enum node.
+
+=cut
+
+sub initEnum
+{
+       my( $name, $end, $params ) = @_;
+
+       ($name = $end) if $name eq "" && $end ne "";
+
+       $params =~ s#\s+# #sg; # no newlines
+       $params = $1 if $params =~ /^\s*{?(.*)}/;
+       print "$name params: [$params]\n" if $debug;
+
+
+       my ( $node ) = Ast::New( $name );
+       $node->AddProp( "NodeType", "enum" );
+       $node->AddProp( "Params", $params );
+       kdocAstUtil::attachChild( $cNode, $node );
+
+       return $node;
+}
+
+=head2 newIDLstruct
+
+       Parameters: type, name, forward, complete, inherits...
+
+       Handles an IDL structure definition (ie module, interface,
+       exception).
+
+=cut
+
+sub newIDLstruct
+{
+       my ( $type, $name, $fwd, $complete ) = @_;
+
+       my $node = exists $cNode->{KidHash} ? 
+               $cNode->{KidHash}->{ $name } : undef;
+
+       if( !defined $node ) {
+               $node = Ast::New( $name );
+               $node->AddProp( "NodeType", $fwd ? "Forward" : $type );
+               $node->AddProp( "KidAccess", "public" );
+               $node->AddProp( "Compound", 1 ) unless $fwd;
+               kdocAstUtil::attachChild( $cNode, $node );
+       }
+       elsif ( $fwd ) {
+               # If we have a node already, we ignore forwards.
+               return undef;
+       }
+       elsif ( $node->{NodeType} eq "Forward" ) {
+               # we are defining a previously forward node.
+               $node->AddProp( "NodeType", $type );
+               $node->AddProp( "Compound", 1 );
+               $node->AddProp( "Source", $cSourceNode );
+       }
+
+       # register ancestors.
+       foreach my $ances ( splice ( @_, 4 ) ) {
+               my $n = kdocAstUtil::newInherit( $node, $ances );
+       }
+
+       if( !( $fwd || $complete) ) {
+               print "newIDL: pushing $cNode->{astNodeName},",
+                       " new is $node->{astNodeName}\n"
+                               if $debug;
+               push @classStack, $cNode;
+               $cNode = $node;
+       }
+
+       return $node;
+}
+
+=head2 newClass
+
+       Parameters: tmplArgs, cNodeType, name, endTag, @inheritlist
+
+       Handles a class declaration (also fwd decls).
+
+=cut
+
+sub newClass
+{
+       my( $tmplArgs, $cNodeType, $name, $endTag ) = @_;
+
+       my $access = "private";
+       $access = "public" if $cNodeType ne "class";
+
+       # try to find an exisiting node, or create a new one
+       my $oldnode = kdocAstUtil::findRef( $cNode, $name );
+       my $node = defined $oldnode ? $oldnode : Ast::New( $name );
+
+       if ( $endTag ne "{" ) {
+               # forward
+               if ( !defined $oldnode ) {
+                       # new forward node
+                       $node->AddProp( "NodeType", "Forward" );
+                       $node->AddProp( "KidAccess", $access );
+                       kdocAstUtil::attachChild( $cNode, $node );
+               }
+               return $node;
+       }
+
+       # this is a class declaration
+
+       print "ClassName: $name\n" if $debug;
+
+       $node->AddProp( "NodeType", $cNodeType );
+       $node->AddProp( "Compound", 1 );
+       $node->AddProp( "Source", $cSourceNode );
+
+       $node->AddProp( "KidAccess", $access );
+       $node->AddProp( "Tmpl", $tmplArgs ) unless $tmplArgs eq "";
+
+       if ( !defined $oldnode ) {
+               kdocAstUtil::attachChild( $cNode, $node );
+       }
+
+       # inheritance
+
+       foreach my $ances ( splice (@_, 4) ) {
+               my $type = "";
+               my $name = $ances;
+               my $intmpl = undef;
+
+WORD:
+               foreach my $word ( split ( /([\w:]+(:?\s*<.*>)?)/, $ances ) ) {
+                       next WORD unless $word =~ /^[\w:]/;
+                       if ( $word =~ /(private|public|protected|virtual)/ ) {
+                               $type .= "$1 ";
+                       }
+                       else {
+                               
+                               if ( $word =~ /<(.*)>/ ) {
+                                       # FIXME: Handle multiple tmpl args
+                                       $name = $`;
+                                       $intmpl = $1;
+                               }
+                               else {
+                                       $name = $word;
+                               }
+
+                               last WORD;
+                       }
+               }
+
+               # set inheritance access specifier if none specified
+               if ( $type eq "" ) {
+                       $type = $cNodeType eq "class" ? "private ":"public ";
+               }
+               chop $type;
+
+               # attach inheritance information
+               my $n = kdocAstUtil::newInherit( $node, $name );
+               $n->AddProp( "Type", $type );
+
+               $n->AddProp( "TmplType", $intmpl ) if defined $intmpl;
+
+               print "In: $name type: $type, tmpl: $intmpl\n" if $debug;
+       }
+
+       # new current node
+       print "newClass: Pushing $cNode->{astNodeName}\n" if $debug;
+       push ( @classStack, $cNode );
+       $cNode = $node;
+
+       return $node;
+}
+
+
+=head3 parseInheritance
+
+       Param: inheritance decl string
+       Returns: list of superclasses (template decls included)
+
+       This will fail if < and > appear in strings in the decl.
+
+=cut
+
+sub parseInheritance
+{
+       my $instring = shift;
+       my @inherits = ();
+
+       my $accum = "";
+       foreach $instring ( split (/\s*,\s*/, $instring) ) {
+               $accum .= $instring.", ";
+               next unless  (kdocUtil::countReg( $accum, "<" )
+                       - kdocUtil::countReg( $accum, ">" ) ) == 0;
+
+               # matching no. of < and >, so assume the parent is
+               # complete
+               $accum =~ s/,\s*$//;
+               print "Inherits: '$accum'\n" if $debug;
+               push @inherits, $accum;
+               $accum = "";
+       }
+
+       return @inherits;
+}
+
+
+=head2 newNamespace
+
+       Param: namespace name.
+       Returns nothing.
+
+       Imports a namespace into the current node, for ref searches etc.
+       Triggered by "using namespace ..."
+
+=cut
+
+sub newNamespace
+{
+       $cNode->AddPropList( "ImpNames", shift );
+}
+
+
+
+=head2 newTypedef
+
+       Parameters: realtype, name
+
+       Handles a type definition.
+
+=cut
+
+sub newTypedef
+{
+       my ( $realtype, $name ) = @_;
+
+       my ( $node ) = Ast::New( $name );
+
+       $node->AddProp( "NodeType", "typedef" );
+       $node->AddProp( "Type", $realtype );
+
+       kdocAstUtil::attachChild( $cNode, $node );
+
+       return $node;
+}
+
+=head2 newTypedefComp
+
+       Params: realtype, name endtoken
+
+       Creates a new compound type definition.
+
+=cut
+
+sub newTypedefComp
+{
+       my ( $realtype, $name, $endtag ) = @_;
+
+       my ( $node ) = Ast::New( $name );
+
+       $node->AddProp( "NodeType", "typedef" );
+       $node->AddProp( "Type", $realtype );
+
+       kdocAstUtil::attachChild( $cNode, $node );
+
+       if ( $endtag eq '{' ) {
+               print "newTypedefComp: Pushing $cNode->{astNodeName}\n" 
+                       if $debug;
+               push ( @classStack, $cNode );
+               $cNode = $node;
+       }
+
+       return $node;
+}
+
+
+=head2 newMethod
+
+       Parameters: retType, name, params, const, pure?
+
+       Handles a new method declaration or definition.
+
+=cut
+
+sub newMethod
+{
+       my ( $retType, $name, $params, $const, $pure ) = @_;
+       my $parent = $cNode;
+       my $class;
+
+       print "Cracked: [$retType] [$name]\n\t[$params]\n\t[$const]\n" 
+               if $debug;
+
+    if ( $retType =~ /([\w\s_<>,]+)\s*::\s*$/ ) {
+               # check if stuff before :: got into rettype by mistake.
+               $retType = $`;
+               ($name = $1."::".$name);
+               $name =~ s/\s+/ /g;
+               print "New name = \"$name\" and type = '$retType'\n" if $debug;
+       }
+
+       if( $name =~ /^\s*(.*?)\s*::\s*(.*?)\s*$/ ) {
+               # Fully qualified method name.
+               $name = $2;
+               $class = $1;
+
+               if( $class =~ /^\s*$/ ) {
+                       $parent = $rootNode;
+               }
+               elsif ( $class eq $cNode->{astNodeName} ) {
+                       $parent = $cNode;
+               }
+               else {
+                       my $node = kdocAstUtil::findRef( $cNode, $class );
+
+                       if ( !defined $node ) {
+                               # if we couldn't find the name, try again with
+                               # all template parameters stripped off:
+                               my $strippedClass = $class;
+                               $strippedClass =~ s/<[^<>]*>//g;
+
+                               $node = kdocAstUtil::findRef( $cNode, $strippedClass );
+
+                               # if still not found: give up
+                               if ( !defined $node ) {
+                                               warn "$exe: Unidentified class: $class ".
+                                                               "in $currentfile\:$.\n";
+                                               return undef;
+                               }
+                       }
+
+                       $parent = $node;
+               }
+       }
+       else {
+               # Within current class/global
+       }
+
+
+       # flags
+
+       my $flags = "";
+
+       if( $retType =~ /static/ ) {
+               $flags .= "s";
+               $retType =~ s/static//g;
+       }
+
+       if( $const ) {
+               $flags .= "c";
+       }
+
+       if( $pure ) {
+               $flags .= "p";
+       }
+
+       if( $retType =~ /virtual/ ) {
+               $flags .= "v";
+               $retType =~ s/virtual//g;
+       }
+
+       print "\n" if $flags ne "" && $debug;
+
+       if ( !defined $parent->{KidAccess} ) {
+               warn "'", $parent->{astNodeName}, "' has no KidAccess ",
+               exists $parent->{Forward} ? "(forward)\n" :"\n";
+       }
+
+       if ( $parent->{KidAccess} =~ /slot/ ) {
+               $flags .= "l";
+       }
+       elsif ( $parent->{KidAccess} =~ /signal/ ) {
+               $flags .= "n";
+       }
+
+       # node
+       
+       my $node = Ast::New( $name );
+       $node->AddProp( "NodeType", "method" );
+       $node->AddProp( "Flags", $flags );
+       $node->AddProp( "ReturnType", $retType );
+       $node->AddProp( "Params", $params );
+
+       $parent->AddProp( "Pure", 1 ) if $pure;
+       kdocAstUtil::attachChild( $parent, $node );
+
+       return $node;
+}
+
+
+=head2 newAccess
+
+       Parameters: access
+
+       Sets the default "Access" specifier for the current class node. If
+       the access is a "slot" type, "_slots" is appended to the access
+       string.
+
+=cut
+
+sub newAccess
+{
+       my ( $access ) = @_;
+
+       return undef unless ($access =~ /^\s*(\w+)\s*(slots)?/);
+
+       print "Access: [$1] [$2]\n" if $debug;
+
+       $access = $1;
+
+       if ( defined $2 && $2 ne "" ) {
+               $access .= "_" . $2;
+       }
+
+       $cNode->AddProp( "KidAccess", $access );
+
+       return $cNode;
+}
+
+
+=head2 newVar
+
+       Parameters: type, name, value
+
+       New variable. Value is ignored if undef
+
+=cut
+
+sub newVar
+{
+       my ( $type, $name, $val ) = @_;
+
+       my $node = Ast::New( $name );
+       $node->AddProp( "NodeType", "var" );
+
+       my $static = 0;
+       if ( $type =~ /static/ ) {
+       #       $type =~ s/static//;
+               $static = 1;
+       }
+
+       $node->AddProp( "Type", $type );
+       $node->AddProp( "Flags", 's' ) if $static;
+       $node->AddProp( "Value", $val ) if defined $val;
+       kdocAstUtil::attachChild( $cNode, $node );
+
+       return $node;
+}
+
+
+
+=head2 show_usage
+
+       Display usage information and quit.
+
+=cut
+
+sub show_usage
+{
+print<<EOF;
+usage:
+       $exe [options] [-f format] [-d outdir] [-n name] files... [-llib..]
+
+See the man page kdoc[1] for more info.
+EOF
+       exit 1;
+}
+
+
+=head2 show_version
+
+       Display short version information and quit.
+
+=cut
+
+sub show_version
+{
+       die "$exe: $Version (c) Sirtaj S. Kang <taj\@kde.org>\n";
+}
+
+
diff --git a/deal.II/contrib/kdoc/src/kdocAstUtil.pm b/deal.II/contrib/kdoc/src/kdocAstUtil.pm
new file mode 100644 (file)
index 0000000..40e1238
--- /dev/null
@@ -0,0 +1,754 @@
+=head1 kdocAstUtil
+
+       Utilities for syntax trees.
+
+=cut
+
+
+package kdocAstUtil;
+
+use Ast;
+use Carp;
+use File::Basename;
+use kdocUtil;
+use Iter;
+use strict;
+
+use vars qw/ $depth $refcalls $refiters @noreflist %noref /;
+
+sub BEGIN {
+# statistics for findRef
+
+       $depth = 0;
+       $refcalls = 0;
+       $refiters = 0;
+
+# findRef will ignore these words
+
+       @noreflist = qw( const int char long double template 
+               unsigned signed float void bool true false uint 
+               uint32 uint64 extern static inline virtual operator );
+
+       foreach my $r ( @noreflist ) {
+               $noref{ $r } = 1;
+       }
+}
+
+
+=head2 findNodes
+
+       Parameters: outlist ref, full list ref, key, value
+
+       Find all nodes in full list that have property "key=value".
+       All resulting nodes are stored in outlist.
+
+=cut
+
+sub findNodes
+{
+       my( $rOutList, $rInList, $key, $value ) = @_;
+
+       my $node;
+
+       foreach $node ( @{$rInList} ) {
+               next if !exists $node->{ $key };
+               if ( $node->{ $key } eq $value ) {
+                       push @$rOutList, $node;
+               }
+       }
+}
+
+=head2 allTypes
+
+       Parameters: node list ref
+       returns: list
+
+       Returns a sorted list of all distinct "NodeType"s in the nodes 
+       in the list.
+
+=cut
+
+sub allTypes
+{
+       my ( $lref ) = @_;
+
+       my %types = ();
+       foreach my $node ( @{$lref} ) {
+               $types{ $node->{NodeType} } = 1;
+       }
+
+       return sort keys %types;
+}
+
+
+
+
+=head2 findRef
+
+       Parameters: root, ident, report-on-fail
+       Returns: node, or undef
+
+       Given a root node and a fully qualified identifier (:: separated),
+       this function will try to find a child of the root node that matches
+       the identifier.
+
+=cut
+
+sub findRef
+{
+       my( $root, $name, $r ) = @_;
+
+       confess "findRef: no name" if !defined $name || $name eq "";
+
+       $name =~ s/\s+//g;      
+       return undef if exists $noref{ $name };
+
+       $name =~ s/^#//g;
+
+       my ($iter, @tree) = split /(?:\:\:|#)/, $name;
+       my $kid;
+
+       $refcalls++;
+
+       # Upward search for the first token
+       return undef if !defined $iter;
+
+       while ( !defined findIn( $root, $iter ) ) {
+               return undef if !defined $root->{Parent};
+               $root = $root->{Parent};
+       }
+       $root = $root->{KidHash}->{$iter};
+       carp if !defined $root;
+
+       # first token found, resolve the rest of the tree downwards
+       foreach $iter ( @tree ) {
+               confess "iter in $name is undefined\n" if !defined $iter;
+               next if $iter =~ /^\s*$/;
+
+               unless ( defined findIn( $root, $iter ) ) {
+                       confess "findRef: failed on '$name' at '$iter'\n"
+                               if defined $r;
+                       return undef;
+               }
+
+               $root = $root->{KidHash}->{ $iter };    
+               carp if !defined $root;
+       }
+
+       return $root;
+}
+
+=head2 findIn
+
+       node, name: search for a child
+
+=cut
+
+sub findIn
+{
+       return undef unless defined $_[0]->{KidHash};
+
+       my $ret =  $_[0]->{KidHash}->{ $_[1] };
+
+       return $ret;
+}
+
+=head2 linkReferences
+
+       Parameters: root, node
+
+       Recursively links references in the documentation for each node
+       to real nodes if they can be found.  This should be called once
+       the entire parse tree is filled.
+
+=cut
+
+sub linkReferences
+{
+       my( $root, $node ) = @_;
+
+       if ( exists $node->{DocNode} ) {
+               linkDocRefs( $root, $node, $node->{DocNode} );
+
+               if( exists $node->{Compound} ) {
+                       linkSee( $root, $node, $node->{DocNode} );
+               }
+       }
+
+       my $kids = $node->{Kids};
+       return unless defined $kids;
+
+       foreach my $kid ( @$kids ) {
+               # only continue in a leaf node if it has documentation.
+               next if !exists $kid->{Kids} && !exists $kid->{DocNode};
+               if( !exists $kid->{Compound} ) {
+                       linkSee( $root, $node, $kid->{DocNode} );
+               }
+               linkReferences( $root, $kid );
+       }
+}
+
+sub linkNamespaces
+{
+       my ( $node ) = @_;
+
+       if ( defined $node->{ImpNames} ) {
+               foreach my $space ( @{$node->{ImpNames}} ) {
+                       my $spnode = findRef( $node, $space );
+
+                       if( defined $spnode ) {
+                               $node->AddPropList( "ExtNames", $spnode );
+                       }
+                       else {
+                               warn "namespace not found: $space\n";
+                       }
+               }
+       }
+
+       return unless defined $node->{Compound} || !defined $node->{Kids};
+
+
+       foreach my $kid ( @{$node->{Kids}} ) {
+               next unless localComp( $kid );
+
+               linkNamespaces( $kid );
+       }
+}
+
+sub calcStats
+{
+               my ( $stats, $root, $node ) = @_;
+# stats:
+# num types
+# num nested
+# num global funcs
+# num methods
+
+
+               my $type = $node->{NodeType};
+
+               if ( $node eq $root ) {
+                       # global methods
+                       if ( defined $node->{Kids} ) {
+                               foreach my $kid ( @{$node->{Kids}} ) {
+                                               $stats->{Global}++ if $kid->{NodeType} eq "method";
+                               }
+                       }
+
+                       $node->AddProp( "Stats", $stats );
+               }
+               elsif ( kdocAstUtil::localComp( $node ) 
+                                       || $type eq "enum" || $type eq "typedef" ) {
+                               $stats->{Types}++;
+                               $stats->{Nested}++ if $node->{Parent} ne $root;
+               }
+               elsif( $type eq "method" ) {
+                               $stats->{Methods}++;
+               }
+
+               return unless defined $node->{Compound} || !defined $node->{Kids};
+
+               foreach my $kid ( @{$node->{Kids}} ) {
+                               next if defined $kid->{ExtSource};
+                               calcStats( $stats, $root, $kid );
+               }
+}
+
+=head2 linkDocRefs
+
+       Parameters: root, node, docnode
+
+       Link references in the docs if they can be found.  This should
+       be called once the entire parse tree is filled.
+
+=cut
+
+sub linkDocRefs
+{
+       my ( $root, $node, $docNode ) = @_;
+       return unless exists $docNode->{Text};
+
+       my ($text, $ref, $item, $tosearch);
+
+       foreach $item ( @{$docNode->{Text}} ) {
+               next if $item->{NodeType} ne 'Ref';
+
+               $text = $item->{astNodeName};
+
+               if ( $text =~ /^(?:#|::)/ ) {
+                       $text = $';
+                       $tosearch = $node;
+               }
+               else {
+                       $tosearch = $root;
+               }
+
+               $ref = findRef( $tosearch, $text );
+               $item->AddProp( 'Ref', $ref ) if defined $ref;
+
+               confess "Ref failed for ", $item->{astNodeName},
+               "\n" unless defined $ref;
+       }
+}
+
+sub linkSee
+{
+       my ( $root, $node, $docNode ) = @_;
+       return unless exists $docNode->{See};
+
+       my ( $text, $tosearch, $ref );
+
+       foreach $text ( @{$docNode->{See}} ) {
+               if ( $text =~ /^\s*(?:#|::)/ ) {
+                       $text = $';
+                       $tosearch = $node;
+               }
+               else {
+                       $tosearch = $root;
+               }
+
+               $ref = findRef( $tosearch, $text );
+               $docNode->AddPropList( 'SeeRef', $ref )
+                       if defined $ref;
+       }
+}
+
+
+
+#
+# Inheritance utilities
+#
+
+=head2 makeInherit
+
+       Parameter: $rootnode, $parentnode
+
+       Make an inheritance graph from the parse tree that begins
+       at rootnode. parentnode is the node that is the parent of
+       all base class nodes.
+
+=cut
+
+sub makeInherit
+{
+       my( $rnode, $parent ) = @_;
+
+       foreach my $node ( @{ $rnode->{Kids} } ) {
+               next if !defined $node->{Compound};
+
+               # set parent to root if no inheritance
+
+               if ( !exists $node->{InList} ) {
+                       newInherit( $node, "Global", $parent );
+                       $parent->AddPropList( 'InBy', $node );
+
+                       makeInherit( $node, $parent );
+                       next;
+               }
+
+               # link each ancestor
+               my $acount = 0;
+ANITER:
+               foreach my $in ( @{ $node->{InList} } ) {
+                       unless ( defined $in ) {
+                               Carp::cluck "warning: $node->{astNodeName} "
+                                       ." has undef in InList.";
+                               next ANITER;
+                       }
+
+                       my $ref = kdocAstUtil::findRef( $rnode, 
+                                       $in->{astNodeName} );
+
+                       if( !defined $ref ) {
+                               # ancestor undefined
+                               warn "warning: ", $node->{astNodeName},
+                                       " inherits unknown class '",
+                                               $in->{astNodeName},"'\n";
+
+                               $parent->AddPropList( 'InBy', $node );
+                       }
+                       else {
+                               # found ancestor
+                               $in->AddProp( "Node", $ref );
+                               $ref->AddPropList( 'InBy', $node );
+                               $acount++;
+                       }
+               }
+
+               if ( $acount == 0 ) {
+                       # inherits no known class: just parent it to global
+                       newInherit( $node, "Global", $parent );
+                       $parent->AddPropList( 'InBy', $node );
+               }
+               makeInherit( $node, $parent );
+       }
+}
+
+=head2 newInherit
+
+       p: $node, $name, $lnode?
+
+       Add a new ancestor to $node with raw name = $name and
+       node = lnode.
+=cut
+
+sub newInherit
+{
+       my ( $node, $name, $link ) = @_;
+
+       my $n = Ast::New( $name );
+       $n->AddProp( "Node", $link ) unless !defined $link;
+
+       $node->AddPropList( "InList", $n );
+       return $n;
+}
+
+=head2 inheritName
+
+       pr: $inheritance node.
+
+       Returns the name of the inherited node. This checks for existence
+       of a linked node and will use the "raw" name if it is not found.
+
+=cut
+
+sub inheritName
+{
+       my ( $innode ) = @_;
+
+       return defined $innode->{Node} ? 
+               $innode->{Node}->{astNodeName}
+               : $innode->{astNodeName};
+}
+
+=head2 inheritedBy
+
+       Parameters: out listref, node
+
+       Recursively searches for nodes that inherit from this one, returning
+       a list of inheriting nodes in the list ref.
+
+=cut
+
+sub inheritedBy
+{
+       my ( $list, $node ) = @_;
+
+       return unless exists $node->{InBy};
+
+       foreach my $kid ( @{ $node->{InBy} } ) {
+               push @$list, $kid;
+               inheritedBy( $list, $kid );
+       }
+}
+
+=head2 hasLocalInheritor
+
+       Parameter: node
+       Returns: 0 on fail
+
+       Checks if the node has an inheritor that is defined within the
+       current library. This is useful for drawing the class hierarchy,
+       since you don't want to display classes that have no relationship
+       with classes within this library.
+
+       NOTE: perhaps we should cache the value to reduce recursion on 
+       subsequent calls.
+
+=cut
+
+sub hasLocalInheritor
+{
+       my $node = shift;
+
+       return 0 if !exists $node->{InBy};
+
+       my $in;
+       foreach $in ( @{$node->{InBy}} ) {
+               return 1 if !exists $in->{ExtSource}
+                       || hasLocalInheritor( $in );
+       }
+
+       return 0;
+}
+
+
+
+=head2 allMembers
+
+       Parameters: hashref outlist, node, $type
+
+       Fills the outlist hashref with all the methods of outlist,
+       recursively traversing the inheritance tree.
+
+       If type is not specified, it is assumed to be "method"
+
+=cut
+
+sub allMembers
+{
+       my ( $outlist, $n, $type ) = @_;
+       my $in;
+       $type = "method" if !defined $type;
+
+       if ( exists $n->{InList} ) {
+
+               foreach $in ( @{$n->{InList}} ) {
+                       next if !defined $in->{Node};
+                       my $i = $in->{Node};
+
+                       allMembers( $outlist, $i ) 
+                               unless $i == $main::rootNode;
+               }
+       }
+
+       return unless exists $n->{Kids};
+
+       foreach $in ( @{$n->{Kids}} ) {
+               next if $in->{NodeType} ne $type;
+
+               $outlist->{ $in->{astNodeName} } = $in;
+       }
+}
+
+=head2 findOverride
+
+       Parameters: root, node, name
+
+       Looks for nodes of the same name as the parameter, in its parent
+       and the parent's ancestors. It returns a node if it finds one.
+
+=cut
+
+sub findOverride
+{
+       my ( $root, $node, $name ) = @_;
+       return undef if !exists $node->{InList};
+
+       foreach my $in ( @{$node->{InList}} ) {
+               my $n = $in->{Node};
+               next unless defined $n && $n != $root && exists $n->{KidHash};
+
+               my $ref  = $n->{KidHash}->{ $name };
+               
+               return $n if defined $ref && $ref->{NodeType} eq "method";
+
+               if ( exists $n->{InList} ) {
+                       $ref = findOverride( $root, $n, $name );
+                       return $ref if defined $ref;
+               }
+       }
+
+       return undef;
+}
+
+=head2 attachChild
+
+       Parameters: parent, child
+
+       Attaches child to the parent, setting Access, Kids
+       and KidHash of respective nodes.
+
+=cut
+
+sub attachChild
+{
+       my ( $parent, $child ) = @_;
+       confess "Attempt to attach ".$child->{astNodeName}." to an ".
+               "undefined parent\n" if !defined $parent;
+
+       $child->AddProp( "Access", $parent->{KidAccess} );
+       $child->AddProp( "Parent", $parent );
+
+       $parent->AddPropList( "Kids", $child );
+
+       if( !exists $parent->{KidHash} ) {
+               my $kh = Ast::New( "LookupTable" );
+               $parent->AddProp( "KidHash", $kh );
+       }
+
+       $parent->{KidHash}->AddProp( $child->{astNodeName},
+               $child ); 
+}
+
+=head2 makeClassList
+
+       Parameters: node, outlist ref
+
+       fills outlist with a sorted list of all direct, non-external
+       compound children of node.
+
+=cut
+
+sub makeClassList
+{
+       my ( $rootnode, $list ) = @_;
+
+       @$list = ();
+
+       Iter::LocalCompounds( $rootnode,
+               sub { 
+                               my $node = shift;
+
+                               my $her = join ( "::", heritage( $node ) );
+                               $node->AddProp( "FullName", $her );
+
+                               push @$list, $node;
+       } );
+
+       @$list = sort { $a->{FullName} cmp $b->{FullName} } @$list;
+}
+
+#
+# Debugging utilities
+#
+
+=head2 dumpAst
+
+       Parameters: node, deep
+       Returns: none
+
+       Does a recursive dump of the node and its children.
+       If deep is set, it is used as the recursion property, otherwise
+       "Kids" is used.
+
+=cut
+
+sub dumpAst
+{
+       my ( $node, $deep ) = @_;
+
+       $deep = "Kids" if !defined $deep;
+
+       print "\t" x $depth, $node->{astNodeName}, 
+               " (", $node->{NodeType}, ")\n";
+
+       my $kid;
+
+       foreach $kid ( $node->GetProps() ) {
+               print "\t" x $depth, "  -\t", $kid, " -> ", $node->{$kid},"\n"
+                       unless $kid =~ /^(astNodeName|NodeType|$deep)$/;
+       }
+       if ( exists  $node->{Ancestors} ) {
+               print "\t" x $depth, "Ancestors:\t",
+                       join( ",", @{$node->{Ancestors}}),"\n";
+       }
+
+
+       $depth++;
+       foreach $kid ( @{$node->{ $deep }} ) {
+               dumpAst( $kid );
+       }
+
+       print "\t" x $depth, "Documentation nodes:\n" if defined 
+               @{ $node->{Doc}->{ "Text" }};
+
+       foreach $kid ( @{ $node->{Doc}->{ "Text" }} ) {
+               dumpAst( $kid );
+       }
+
+       $depth--;
+}
+
+=head2 testRef
+
+       Parameters: rootnode
+
+       Interactive testing of referencing system. Calling this
+       will use the readline library to allow interactive entering of
+       identifiers. If a matching node is found, its node name will be
+       printed.
+
+=cut
+
+sub testRef {
+       require Term::ReadLine;
+
+       my $rootNode = $_[ 0 ];
+
+       my $term = new Term::ReadLine 'Testing findRef';
+
+       my $OUT = $term->OUT || *STDOUT{IO};
+       my $prompt = "Identifier: ";
+
+       while( defined ($_ = $term->readline($prompt)) ) {
+
+               my $node = kdocAstUtil::findRef( $rootNode, $_ );
+
+               if( defined $node ) {
+                       print $OUT "Reference: '", $node->{astNodeName}, 
+                       "', Type: '", $node->{NodeType},"'\n";
+               }
+               else {
+                       print $OUT "No reference found.\n";
+               }
+
+               $term->addhistory( $_ ) if /\S/;
+       }
+}
+
+sub printDebugStats
+{
+       print "findRef: ", $refcalls, " calls, ", 
+               $refiters, " iterations.\n";
+}
+
+sub External
+{
+       return defined $_[0]->{ExtSource};
+}
+
+sub Compound
+{
+       return defined $_[0]->{Compound};
+}
+
+sub localComp
+{
+       my ( $node ) = $_[0];
+       return defined $node->{Compound} 
+               && !defined $node->{ExtSource} 
+               && $node->{NodeType} ne "Forward";
+}
+
+sub hasDoc
+{
+       return defined $_[0]->{DocNode};
+}
+
+
+sub heritage
+{
+               my $node = shift;
+               my @heritage;
+
+               while( 1 ) {
+                               push @heritage, $node->{astNodeName};
+
+                               last unless defined $node->{Parent};
+                               $node = $node->{Parent};
+                               last unless defined $node->{Parent};
+               }
+
+               return reverse @heritage;
+}
+
+sub refHeritage
+{
+               my $node = shift;
+               my @heritage;
+
+               while( 1 ) {
+                               push @heritage, $node;
+
+                               last unless defined $node->{Parent};
+                               $node = $node->{Parent};
+                               last unless defined $node->{Parent};
+               }
+
+               return reverse @heritage;
+
+}
+
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocCxxDocbook.pm b/deal.II/contrib/kdoc/src/kdocCxxDocbook.pm
new file mode 100644 (file)
index 0000000..57fea4f
--- /dev/null
@@ -0,0 +1,771 @@
+
+package kdocCxxDocbook;
+use Carp;
+use File::Path;
+use Iter;
+
+use strict;
+no strict "subs";
+
+use vars qw/ $lib $rootnode $outputdir $opt $paraOpen/;
+
+=head2 kdocCxxDocBook
+
+       TODO:
+
+       Templates
+       Fix tables, add index.
+       Global docs
+       Groups
+
+=cut
+
+sub writeDoc
+{
+       ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+       makeReferences( $rootnode );
+
+       $lib = "kdoc-out" if $lib eq "";        # if no library name set
+
+       mkpath( $outputdir) unless -f $outputdir;
+
+       open ( DOC, ">$outputdir/$lib.sgml" ) || die "Couldn't write output.";
+
+       my $time = localtime;
+
+print DOC<<EOF;
+<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
+]>
+<book id="$lib-lib">
+       <bookinfo>
+               <date>$time</date>
+               <title>$lib API Documentation</title>
+       </bookinfo>
+EOF
+
+       printLibDoc();
+       printHierarchy();
+       printClassIndex();
+       printClassDoc();
+
+print DOC<<EOF;
+</book>
+EOF
+
+}
+
+sub printLibDoc
+{
+       return unless kdocAstUtil::hasDoc( $rootnode );
+       
+       print DOC chapter( "$lib-intro", "Introduction" );
+       printDoc( $rootnode->{DocNode}, *DOC, $rootnode );
+       print DOC C( "chapter" );
+}
+
+
+sub printHierarchy
+{
+
+       print DOC chapter( "class-hierarchy", "$lib Class Hierarchy" );
+
+       Iter::Hierarchy( $rootnode,
+               sub {   # down
+                       print DOC "<ItemizedList>\n";
+               },
+               sub {   # print
+                       my $node = shift;
+                       return if $node == $rootnode;
+
+                       my $src = defined $node->{ExtSource} ? " ($node->{ExtSource})":"";
+                       print DOC "<ListItem><para>", refName($node), "$src</para>\n"
+               },
+               sub {   # up
+                       if ( $_[0] == $rootnode ) {
+                               print DOC "</ItemizedList>\n";
+                       }
+                       else {
+                               print DOC "</ItemizedList></ListItem>\n";
+                       }
+               },
+               sub { print DOC "</ListItem>"; }
+       );
+               
+       print DOC C( "chapter" ); 
+}
+
+sub printClassIndex
+{
+       my @clist = ();
+       kdocAstUtil::makeClassList( $rootnode, \@clist );
+
+       print DOC chapter( "class-index", "$lib Class Index" ),
+               O( "Table", "TocEntry", 0, "PgWide", 1, "ColSep", 0 ),
+               tblk( "title", $lib,' classes' ),
+               O( "tgroup", "Cols", 2  ), O( "TBody" );
+
+       foreach my $kid ( @clist ) {
+
+               # Internal, deprecated, abstract
+               my $name = refName( $kid );
+
+               if ( $kid->{Abstract} ) {
+                       $name = tblk( "Emphasis", $name );
+               }
+
+               my $extra = "";
+
+               if ( $kid->{Internal} ) {
+                       $extra .= " internal";
+               }
+
+               if ( $kid->{Deprecated} ) {
+                       $extra .= " ".tblk( "Emphasis", "deprecated" );
+               }
+
+               $extra = " [$extra]" unless $extra eq "";
+               
+               # print class entry
+               print DOC tblk( 'Row', tblk( 'ENTRY', $name )
+                       . tblk( 'ENTRY', deref( $kid->{DocNode}->{ClassShort},
+                               $rootnode).$extra ));
+       }
+
+       print DOC C( "TBody", "TGroup", "Table", "chapter" );
+}
+
+sub printClassDoc
+{
+       print DOC chapter( "class-doc", "$lib Class Documentation" );
+
+       Iter::LocalCompounds( $rootnode, sub { docChildren( shift ); } );
+
+       print DOC C("Chapter"), "\n";
+}
+
+sub docChildren
+{
+       my ( $node ) = @_;
+
+       return if $node == $rootnode;
+       
+       ## document self
+       printClassInfo( $node );
+       
+       if ( kdocAstUtil::hasDoc( $node ) ) {
+               printDoc( $node->{DocNode}, *DOC{IO}, $rootnode, 1 );
+       }
+
+       # First a member index by type
+       print DOC O( "BridgeHead", "Renderas", "Sect2" ),
+               "Interface Synopsis", C( "BridgeHead" );
+
+       Iter::MembersByType( $node,
+               sub {   # start
+               print DOC O( 'Table', 'PgWide', 1, "colsep", 0,
+                               "rowsep", 0, "tocentry", 0 ),
+                       tblk( 'Title', fullName($node)," ",$_[0] ),
+                       O( "TGroup", "cols", 1 ), O( "TBody" );
+               },
+               \&sumListMember, # print
+               sub {   # end
+                       print DOC C( "TBody", "TGroup", "Table" ), "\n";
+               },
+               sub {   # no kids
+                       print DOC tblk( "para", "(Empty interface)" );
+               }
+       );
+
+       print DOC O( "BridgeHead", "Renderas", "Sect2" );
+       print DOC "Member Documentation", C( "BridgeHead" );
+
+       # Then long docs for each member
+       Iter::MembersByType ( $node, undef, \&printMemberDoc, undef,
+               sub { print DOC tblk( "para", "(Empty interface)" ); }
+       );
+       
+       print DOC C( "Sect1" );
+
+       return;
+}
+
+sub printClassInfo
+{
+       my $node = shift;
+
+       print DOC O( "Sect1", "id", $node->{DbRef},
+                               "XRefLabel", fullName( $node, "::" ) ), "\n",
+               tblk( "Title", esc($node->{NodeType})," ",fullName( $node ) );
+
+
+       if ( defined $node->{DocNode} &&  $node->{DocNode}->{ClassShort} ) {
+               printClassInfoField( "Description", 
+                       deref( $node->{DocNode}->{ClassShort}, $rootnode ) );
+       }
+
+       printClassInfoField( "Header", tblk( "Literal", 
+                       $node->{Source}->{astNodeName} ));
+
+       my ($text, $comma ) = ("", "");
+
+       Iter::Ancestors( $node, $rootnode, undef, undef,
+               sub { # print
+                       my ( $node, $name, $type ) = @_;
+                       $name = refName( $node ) if defined $node;
+                       $name .= " (".$node->{ExtSource}.")" if defined $node->{ExtSource};
+                       $text .= $comma.$name;
+                       $text .= " [$type]" unless $type eq "public";
+
+                       $comma = ", ";
+               },
+               sub { # end
+                       printClassInfoField( "Inherits", $text );
+               }
+       );
+       
+       $text = $comma = "";
+
+       Iter::Descendants( $node, undef, undef,
+               sub { # print
+                       my $desc = shift;
+                       $text .= $comma.refName( $desc );
+                       $text .= " (".$desc->{ExtSource}.")" if defined $desc->{ExtSource};
+
+                       $comma = ", ";
+               },
+               sub { # end
+                       printClassInfoField( "Inherited By", $text );
+               }
+       );
+
+       if ( $node->{Internal} ) {
+               printClassInfoField( "Note", "Internal use only." );
+       }
+
+       if ( $node->{Deprecated} ) {
+               printClassInfoField( "Note", "Deprecated, to be removed." );
+       }
+
+       return;
+}
+
+sub printClassInfoField
+{
+       my ( $label, $text ) = @_;
+
+       print DOC tblk( "formalpara", tblk( "title", $label ),
+                       tblk( "para", " ".$text ) );
+}
+
+sub sumListMember
+{
+       my( $class, $m ) = @_;
+
+       print DOC O( "Row"), O( "Entry" );
+
+
+       my $type = $m->{NodeType};
+       my $name = esc( $m->{astNodeName} );
+       my $pname = tblk( "Emphasis", $name );
+
+       if( $type eq "var" ) {
+               print DOC tblk( "Literal", esc($m->{Type}) ), " $pname\n";
+       }
+       elsif( $type eq "method" ) {
+               my $flags = $m->{Flags};
+
+               if ( !defined $flags ) {
+                       warn "Method ".$m->{astNodeName}.
+                               " has no flags";
+               }
+
+               my $extra = "";
+               $extra .= "virtual " if $flags =~ "v";
+               $extra .= "static " if $flags =~ "s";
+
+               my $params = esc( $m->{Params} );
+               $params =~ s/^\s+//g;
+               $params =~ s/\s+$//g;
+               $params = " $params " unless $params eq "";
+               my $c = $flags =~ /c/ ? " const" : "";
+               my $p = $flags =~ /p/ ? " [pure]" : "";
+
+
+               print DOC esc($m->{ReturnType}), "  $pname\($params\)$c$p\n";
+       }
+       elsif( $type eq "enum" ) {
+               my $n = $name eq "" ? "" : $pname." ";
+
+               print DOC tblk("Literal","enum"),
+                       " $n\{ ",tblk("Literal",esc($m->{Params}))," }";
+       }
+       elsif( $type eq "typedef" ) { 
+               print DOC tblk( "Literal", "typedef " ), esc($m->{Type}), 
+                               tblk( "Emphasis", $name );
+       }
+       else { 
+               # unknown type
+               print DOC tblk( "Literal", esc( $type ) )," $pname\n";
+       }
+
+       print DOC C( "Entry", "Row" ),"\n";
+
+       return;
+}
+
+=head2 printMemberDoc
+
+       params: classnode, membernode
+
+       Prints title and long documentation for one class member.
+
+=cut
+
+sub printMemberDoc
+{
+       my ( $class, $mem ) = @_;
+
+       return unless kdocAstUtil::hasDoc( $mem );
+
+       print DOC O( "BridgeHead",
+                       "id",                   $mem->{DbRef},
+                       "XRefLabel",    fullName( $mem, "::" ),
+                       "Renderas",             "Sect3" );
+
+       # title
+       my $type = $mem->{NodeType};
+       my $name = esc( $mem->{astNodeName} );
+       my $pname = tblk( "Emphasis", $name );
+
+       if( $type eq "var" ) {
+               print DOC tblk( "Literal", esc($mem->{Type}) ), " $pname\n";
+       }
+       elsif( $type eq "method" ) {
+               my $flags = $mem->{Flags};
+
+               if ( !defined $flags ) {
+                       warn "Method ".$mem->{astNodeName}.
+                               " has no flags";
+               }
+
+               my $extra = "";
+               $extra .= "virtual " if $flags =~ "v";
+               $extra .= "static " if $flags =~ "s";
+
+               my $params = $mem->{Params};
+               $params =~ s/^\s+//g;
+               $params =~ s/\s+$//g;
+               $params = " $params " unless $params eq "";
+               my $c = $flags =~ /c/ ? " const" : "";
+               my $p = $flags =~ /p/ ? " [pure]" : "";
+
+               print DOC deref($mem->{ReturnType}, $rootnode), "  $pname\(".
+                       deref( $params, $rootnode )."\)$c$p\n";
+       }
+       elsif( $type eq "enum" ) {
+               my $n = $name eq "" ? "" : $pname." ";
+
+               print DOC tblk("Literal","enum"),
+                       " $n\{ ",tblk("Literal",esc($mem->{Params}))," }";
+       }
+       elsif( $type eq "typedef" ) { 
+               print DOC tblk( "Literal", "typedef" ), " ", esc($mem->{Type}), $pname;
+       }
+               # TODO nested compounds
+       else { 
+               # unknown type
+               print DOC tblk( "Literal", esc( $type ) )," $pname\n";
+       }
+
+       print DOC C( "BridgeHead" );
+
+       # documentation
+       printDoc( $mem->{DocNode}, *DOC, $rootnode );
+
+       if ( $type eq "method" ) {
+               my $ref = kdocAstUtil::findOverride( $rootnode,
+                               $class, $mem->{astNodeName} );
+               if ( defined $ref ) {
+                       print DOC tblk( "formalpara",
+                               tblk( "title", "Reimplemented from" ),
+                               tblk( "para", fullName( $ref, "::" )) ), "\n";
+               }
+       }
+}
+
+=head2 printDoc
+
+Parameters: docnode, *filehandle, rootnode, compound
+
+Print a doc node. If compound is specified and non-zero, various
+compound node properties are not printed.
+
+=cut
+
+sub printDoc
+{
+       my $docNode = shift;
+       local *CLASS = shift;
+
+        my ( $rootnode, $comp ) = @_;
+        my $node;
+        my $type;
+       my $text;
+       my $lasttype = "none";
+
+       $comp = 0 if !defined $comp;
+       
+       $text = $docNode->{Text};
+
+        if ( defined $text ) {
+               $paraOpen = 0;
+
+                foreach $node ( @$text ) {
+                        $type = $node->{NodeType};
+                       my $name = $node->{astNodeName};
+                        warn "Node '", $name, "' has no type"
+                               if !defined $type;
+
+                       if( $lasttype eq "ListItem" && $type ne $lasttype ) {
+                               print CLASS "</ItemizedList>\n";
+                       }
+
+                        if( $type eq "DocText" ) {
+                                print CLASS "", pc(), po(), 
+                                       deref( $name, $rootnode );
+                        }
+                        elsif ( $type eq "Pre" ) {
+                               print CLASS "", pc(), 
+                                       tblk( "ProgramListing", esc( $name ) );
+                        }
+                       elsif( $type eq "DocSection" ) {
+                               print CLASS "", pc(), O( "BridgeHead",
+                                                       "Renderas", "Sect4" ),
+                                       deref( $name, $rootnode ),
+                                       C( "BridgeHead" ),"\n";
+                       }
+                       elsif( $type eq "Ref" ) {
+                               my $ref = $node->{Ref};
+                               if ( defined $ref ) {
+                                       print CLASS refName( $ref );
+                               }
+                               else {
+                                       print CLASS $name;
+                               }
+                       }
+                       elsif ( $type eq "Image" ) {
+                               print CLASS pc(),"<Graphic FileRef=\"",
+                                       $node->{Path}, "\"></Graphic>";
+                       }
+                       elsif ( $type eq "ListItem" ) {
+                               if ( $lasttype ne "ListItem" ) {
+                                       print CLASS "", pc(),"<ItemizedList>\n";
+                               }
+                               print CLASS "", tblk( "ListItem",
+                                       tblk("para", deref($name,$rootnode )) );
+                       }
+                        elsif ( $type eq "ParaBreak" || $type eq "Param" ) {
+                               # ignore parabreak, they're taken
+                               # care of already.
+
+                               # ignore parameters, handled later
+                       }
+                       else {
+                               warn "Unhandled doc type $type\n";
+                       }
+
+                       $lasttype = $type;
+                }
+
+               if( $lasttype eq "ListItem" ) {
+                       print CLASS "", pc(), "</ItemizedList>";
+               }
+
+               print CLASS "", pc();
+        }
+
+       # Params
+       my @paramlist = ();
+       kdocAstUtil::findNodes( \@paramlist, $docNode->{Text},
+                       "NodeType", "Param" );
+
+       if( $#paramlist >= 0 ) {
+               my $pnode;
+               print CLASS "", O( 'Table', 'PgWide', 0, "colsep", 0,
+                       "frame", "none", "tocentry", 0 ),
+                       tblk( 'Title', 'Parameters' ),
+                       O( "TGroup", "cols", "2" ), O( "TBody" );
+
+               foreach $pnode ( @paramlist ) {
+                       print CLASS "<ROW><ENTRY>", esc($pnode->{Name}),
+                               "</ENTRY><ENTRY>",
+                               deref($pnode->{astNodeName}, $rootnode ),
+                               "</ROW>\n";
+               }
+               print CLASS "", C( "TBody", "TGroup", "Table" );
+       }
+
+       # Return
+       printTextItem( $docNode, *CLASS, "Returns" );
+
+       # Exceptions
+       $text = $docNode->{Throws};
+
+       if ( defined $text ) {
+               my $comma = "<formalpara><title>Exceptions</title><para>";
+
+               foreach my $tosee ( @$text ) {
+                       print CLASS $comma, esc( $tosee );
+                       $comma = ", ";
+               }
+               print CLASS C( "para", "formalpara" );
+       }
+
+       # See
+       my $comma = "";
+       
+       Iter::SeeAlso ( $docNode, undef,
+               sub { # start
+                       print CLASS "", O( "Tip" ),tblk( "Title", "See Also"),O( "Para" );
+               },
+               sub { # print
+                       my ( $label, $ref ) = @_;
+                       $label = defined $ref ? refName( $ref ):esc( $label );
+
+                       print CLASS $comma, $label;
+                       $comma = ", ";
+               },
+               sub { # end
+                       print CLASS "", C( "Para", "Tip" );
+               }
+       );
+       
+       printTextItem( $docNode, *CLASS, "Since" );
+       printTextItem( $docNode, *CLASS, "Version" );
+       printTextItem( $docNode, *CLASS, "Id" );
+       printTextItem( $docNode, *CLASS, "Author" );
+}
+
+sub makeReferences
+{
+       my $root = shift;
+       my $idcount = 0;
+
+       return Iter::Tree( $root, 1,
+               sub {
+                               my ( $parent, $node ) = @_;
+                               return if $node->{ExtSource};
+
+                               $idcount++;
+
+                               $node->AddProp( "DbRef", "docid-$idcount" );
+
+                               print fullName( $node ), " = ", $node->{DbRef},"\n";
+
+                               return;
+               }
+       );
+}
+
+sub printTextItem
+{
+       my $node = shift;
+       local *CLASS = shift;
+       my ( $prop, $label ) = @_;
+
+       my $text = $node->{ $prop };
+       
+       return unless defined $text;
+       $label = $prop unless defined $label;
+       
+       print CLASS "<formalpara><title>", $label, "</title><para> ", 
+               deref( $text, $rootnode  ), "</para></formalpara>\n";
+}
+
+
+# utilities
+
+
+sub refName
+{
+       my( $node ) = @_;
+
+       return fullName( $node ) if defined $node->{ExtSource}
+               || !kdocAstUtil::hasDoc( $node );
+
+       return '<xref LinkEnd="'.$node->{DbRef}.'">';
+}
+
+sub fullName
+{
+       my( $node, $sep ) = @_;
+
+       $sep = "::" unless defined $sep;
+
+       my @heritage = kdocAstUtil::heritage( $node );
+       foreach my $n ( @heritage ) { $n = esc( $n ); }
+
+       return join( $sep, @heritage );
+}
+
+=head2 deref
+
+       Parameters: text, rootnode
+       returns text
+
+       dereferences all @refs in the text and returns it.
+
+=cut
+
+sub deref
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is null" if !defined $rootnode;
+       my $out = "";
+       my $text;
+
+       foreach $text ( split (/(\@\w+\s+[\w:#]+)/, $str ) ) {
+               if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
+                       my $name = $1;
+                       $name =~ s/^\s*#//g;
+                       $out .= wordRef( $name, $rootnode );
+               }
+               elsif ( $text =~ /\@p\s+([\w:]+)/ ) {
+                       $out .= tblk( "Literal", esc($1) );
+               }
+               else {
+                       $out .= esc($text);
+               }
+       }
+
+       return $out;
+}
+
+
+
+=head3 wordRef
+
+       Parameters: word
+
+       Prints a hyperlink to the word's reference if found, otherwise
+       just prints the word. Good for @refs etc.
+
+=cut
+
+sub wordRef
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is undef" if !defined $rootnode;
+
+       return "" if $str eq "";
+
+       my $ref = kdocAstUtil::findRef( $rootnode, $str );
+       return esc($str) if !defined $ref;
+
+       return refName( $ref );
+}
+
+
+=head2 esc
+
+       Escape special SGML characters for normal text.
+
+=cut
+
+sub esc
+{
+       my $str = $_[ 0 ];
+
+       return "" if !defined $str || $str eq "";
+
+       $str =~ s/&/&amp;/g;
+       $str =~ s/</&lt;/g;
+       $str =~ s/>/&gt;/g;
+
+       return $str;
+}
+
+
+sub chapter
+{
+       my ( $id, $title ) = @_;
+
+       return "<chapter id=\"$id\"><title>$title</title>";
+}
+
+
+=head2 tblk
+
+       Params: tagname, text..
+
+       Inserts text in a block tag of type tagname (ie both
+       opening and closing tags)
+=cut
+
+sub tblk
+{
+       my $tag = shift;
+       return "<$tag>".join( "", @_ )."</$tag>";
+}
+
+
+=head2 O
+
+       Params: tagname, list of id and idtext interspersed.
+
+=cut
+
+sub O
+{
+       my $tag = shift;
+
+       carp "mismatched ids and tags" if ($#_+1) % 2 != 0;
+
+       my $out = "<$tag";
+
+       while ( $#_ >= 0 ) {
+               $out .= " ".shift( @_ ).'="'.shift( @_ ).'"';
+       }
+
+       $out .= ">";
+
+       return $out;
+}
+
+=head2 C
+
+       Params: list of tagnames
+
+       returns a list of close tags in the order specified in the
+       params.
+
+=cut
+
+sub C
+{
+       my $out = "";
+
+       foreach my $tag ( @_ ) {
+               $out .= "</$tag>";
+       }
+
+       return $out;
+}
+
+sub po
+{
+       my $text = $paraOpen ? "" : "<para>";
+       $paraOpen = 1;
+
+       return $text;
+}
+
+sub pc
+{
+       my $text = $paraOpen ? "</para>" : "";
+       $paraOpen = 0;
+
+       return $text;
+}
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocCxxHTML.pm b/deal.II/contrib/kdoc/src/kdocCxxHTML.pm
new file mode 100644 (file)
index 0000000..2b2d0b3
--- /dev/null
@@ -0,0 +1,848 @@
+package kdocCxxHTML;
+
+use File::Path;
+use File::Basename;
+
+use Carp;
+use Ast;
+use kdocAstUtil;
+use kdocHTMLutil;
+use kdocUtil; 
+use Iter;
+
+use strict;
+no strict "subs";
+
+use vars qw/ @clist $host $who $now $gentext %toclinks $docBotty
+       $lib $rootnode $outputdir $opt $debug *CLASS/;
+
+=head1 kdocCxxHTML
+
+Capabilities required from Ast bit: 
+
+1. Create an inheritance tree
+
+2. Referencing ability: convert a fully qualified class or member name
+to a node reference.
+
+=cut
+
+BEGIN
+{
+       @clist = ();
+
+       # Contents entries in HTML page header
+
+       %toclinks = (
+               'Index'          => 'index.html',
+               'Annotated List' => 'index-long.html',
+               'Hierarchy'      => 'hier.html',
+               'Globals'        => 'all-globals.html',
+               'Files'          => 'header-list.html'
+       );
+
+       # Page footer
+
+       $who = kdocUtil::userName();
+       $host = kdocUtil::hostName();
+       $now = localtime;
+       $gentext = "$who\@$host on $now, using kdoc $main::Version.";
+
+       $docBotty =<<EOF
+<HR>
+       <table>
+       <tr><td><small>Generated by: $gentext</small></td></tr>
+       </table>
+</BODY>
+</HTML>
+EOF
+
+}
+
+sub writeDoc
+{
+       ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+       $debug = $main::debug;
+
+       mkpath( $outputdir ) unless -f $outputdir;
+
+       makeSourceReferences( $rootnode );
+       makeReferences( $rootnode );
+       kdocAstUtil::makeClassList( $rootnode, \@clist );
+
+       writeGlobalDoc( $rootnode, "$outputdir/".$toclinks{Globals} );
+       writeClassList( $rootnode , "$outputdir/".$toclinks{Index} );
+       writeAnnotatedList( $rootnode, 
+               "$outputdir/".$toclinks{ "Annotated List" } );
+       writeHier( $rootnode, "$outputdir/".$toclinks{Hierarchy} );
+       writeHeaderList( "$outputdir/".$toclinks{Files} );
+
+
+       # Document all compound nodes
+       Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } );
+}
+
+=head2 writeClassList
+
+       Parameters: rootnode
+
+       Writes out a concise list of classes to index.html
+
+=cut
+
+sub writeClassList
+{
+       my ( $root, $file ) = @_;
+
+       open(CLIST, ">$file") 
+               || die "Couldn't create $file\n";
+
+       newPgHeader( *CLIST{IO}, "$lib Class Index", "", "", \%toclinks );
+
+       if ( defined $root->{DocNode} ) {
+               printDoc( $root->{DocNode}, *CLIST, $root, 1 );
+       }
+
+       if ( $#clist < 0 ) {
+               print CLIST "<h2>No classes</h2>";
+               # TODO: Perhaps display C-specific index.
+       }
+       else {
+               writeTable( *CLIST{IO}, \@clist, 
+                       exists $opt->{"html-cols"} ? $opt->{"html-cols"} : 3 );
+       }
+
+       print CLIST $docBotty;
+       close CLIST;
+}
+
+
+
+=head2 writeAnnotatedList
+
+       Parameters: rootnode
+
+       Writes out a list of classes with short descriptions to
+       index-long.html.
+
+=cut
+
+sub writeAnnotatedList
+{
+       my ( $root, $file ) = @_;
+       my $short;
+
+       open(CLIST, ">$file") 
+       || die "Couldn't create $file\n";
+
+       newPgHeader( *CLIST{IO}, "$lib Annotated List", "", "", \%toclinks );
+
+       print CLIST '<TABLE WIDTH="100%" BORDER=\"0\">';
+       
+       my $colnum = 0;
+       my $colour;
+       my $col = 0;
+
+       foreach my $node ( @clist ) {
+               print  "undef in clist\n" if !defined $node;
+
+               my $docnode = $node->{DocNode};
+               $short = "";
+
+               if( defined $docnode ) {
+                       if ( exists $docnode->{ClassShort} ) {
+                               $short = deref($docnode->{ClassShort}, 
+                                       $rootnode );
+                       }
+                       if ( defined $docnode->{Internal} ) {
+                               $short .= " <small>(internal)</small>";
+                       }
+                       if ( defined $docnode->{Deprecated} ) {
+                               $short .= " <small>(deprecated)</small>";
+                       }
+               }
+               
+               $col = $col ? 0 : 1;
+               $colour = $col ? "" : 'bgcolor="#eeeeee"';
+
+               print CLIST "<TR $colour><TD>", refNameFull( $node ), 
+                       "</TD><TD>", $short, "</TD></TR>";
+       }
+
+       print CLIST "</TABLE>", $docBotty;
+       close CLIST;
+}
+
+
+=head2 writeAllMembers
+
+       Parameters: node
+
+       Writes a list of all methods to "full-list-<class file>"
+
+=cut
+
+sub writeAllMembers
+{
+       my( $node ) = @_;
+       my $file = "$outputdir/full-list-".$node->{Ref};
+       my %allmem = ();
+
+       kdocAstUtil::allMembers( \%allmem, $node );
+
+       open( ALLMEM, ">$file" ) || die "Couldn't create $file\n";
+
+#      print ALLMEM pageHeader( \%toclinks, esc($node->{astNodeName})
+#              ." - All Methods" ), "<UL>";
+
+       newPgHeader( *ALLMEM, 
+                       $node->{NodeType}." ".esc($node->{astNodeName}).
+                       ": All methods", "", "", \%toclinks );
+
+       my $mem;
+       my $col = 0;
+       my $colour = "";
+
+       my @memlist = sort { $a->{astNodeName} cmp $b->{astNodeName} } 
+                       values %allmem;
+       writeTable( *ALLMEM{IO}, \@memlist, 3 );
+
+       print ALLMEM "$docBotty";
+
+       close ALLMEM;
+}
+
+=head2 writeHier
+
+       Parameters: rootnode
+
+       Writes out the class hierarchy index to hier.html.
+
+=cut
+
+sub writeHier
+{
+       my ( $root, $file ) = @_;
+
+       open( HIER, ">$file") 
+               || die "Couldn't create $file\n";
+
+       newPgHeader( *HIER{IO}, "$lib Class Hierarchy", "", "", \%toclinks );
+
+       Iter::Hierarchy( $root,
+               sub {   # down
+                       print HIER "<UL>";
+               },
+               sub {   # print
+                       my ( $node ) = @_;
+                       return if $node == $rootnode;
+
+                       my $src = defined $node->{ExtSource} ?
+                               " ($node->{ExtSource})" : "";
+
+                       print HIER "<LI>", refNameFull( $node )," $src\n";
+               },
+               sub {   # up
+                       if ( $_[0] == $root ) {
+                               print HIER "</UL>\n";
+                       }
+                       else {
+                               print HIER "</UL></LI>\n";
+                       }
+               },
+               sub { print HIER "</LI>\n"; }
+       );
+
+       print HIER $docBotty;
+       close HIER;
+}
+
+=head2 writeHeaderList
+
+       Generates the header-list.html file, which contains links
+       to each processed header. The $rootnode->{Sources} List is used.
+
+=cut
+
+sub writeHeaderList
+{
+       my ( $file ) = @_;
+
+       # Convert all to HTML
+
+       my @clist = sort { $a->{astNodeName} cmp $b->{astNodeName} }
+                       @{$rootnode->{Sources}};
+
+       foreach my $hdr ( @clist ) {
+               writeSrcHTML( $outputdir."/".$hdr->{Ref}, $hdr->{Path} );
+       }
+
+
+       # Write the list
+
+       open(HDRIDX, ">$file") || die "Couldn't create $file\n";
+
+
+       newPgHeader( *HDRIDX{IO}, "$lib File Index", "", "", \%toclinks );
+
+       writeTable( *HDRIDX{IO}, \@clist, 
+                       exists $opt->{"html-cols"} ? $opt->{"html-cols"} : 3 );
+
+       print HDRIDX "</UL>\n",$docBotty;
+       close HDRIDX;
+}
+
+
+
+
+=head2 writeClassDoc
+
+       Write documentation for one compound node.
+
+=cut
+
+sub writeClassDoc
+{
+       my( $node ) = @_;
+
+       print "Enter: $node->{astNodeName}\n" if $debug;
+       if( exists $node->{ExtSource} ) {
+               warn "Trying to write doc for ".$node->{AstNodeName}.
+                       " from ".$node->{ExtSource}."\n";
+               return;
+       }
+
+       my $file = "$outputdir/".join("__", kdocAstUtil::heritage($node)).".html";
+       my $docnode = $node->{DocNode};
+       my @list = ();
+       my $version = undef;
+       my $author = undef;
+
+       open( CLASS, ">$file" ) || die "Couldn't create $file\n";
+
+       # Header
+        
+       my $short = "";
+       my $extra = "";
+
+       if( kdocAstUtil::hasDoc( $node ) ) {
+               if ( exists $docnode->{ClassShort} ) {
+                       $short .= deref($docnode->{ClassShort}, 
+                               $rootnode).
+                               " <small>".
+                               hyper( "#longdesc", "More..." )."</small>";
+               }
+
+               if ( exists $docnode->{Deprecated} ) {
+                       $extra .= '<TR><TH colspan="2">'.
+                       'Deprecated! use with care</TH></TR>';
+               }
+
+               if ( exists $docnode->{Internal} ) {
+                       $extra .= '<TR><TH colspan="2">'.
+                       'Internal Use Only</TH></TR>';
+
+               }
+               $version = esc($docnode->{Version}) 
+                       if exists $docnode->{Version};
+               $author = esc($docnode->{Author}) 
+                       if exists $docnode->{Author};
+       }
+
+       # pure virtual check
+       if ( exists $node->{Pure} ) {
+               $extra .= '<TR><TH colspan="2">'
+                       .'Contains pure virtuals</TH></TR>';
+       }
+       
+       # full name, if not in global scope
+       if ( $node->{Parent} != $rootnode ) {
+               $extra .= tabRow( "Full name", 
+                       "<code>".refNameEvery( $node, $rootnode )."</code>" );
+       }
+
+       # include (not for namespaces)
+       if ( $node->{NodeType} ne "namespace" 
+               && $node->{NodeType} ne "Forward" ) {
+               $extra .= tabRow( 'Definition', '<code>#include &lt;'. 
+                       refName( $node->{Source} ).'&gt;</code>' );
+       }
+
+       # template form
+       if ( exists $node->{Tmpl} ) {
+               $extra .= tabRow( "Template form",
+                       esc($node->{astNodeName})
+                       ."&lt;".textRef($node->{Tmpl}, $rootnode )."&gt; "
+                       ."</code>" );
+       }
+
+       
+       my $comma = "";
+       my $out = "";
+
+       # ancestors
+       Iter::Ancestors( $node, $rootnode, undef, undef,
+               sub { # print
+                       my ( $ances, $name, $type, $template ) = @_;
+
+                       if( !defined $ances ) {
+                               $out .= $comma.esc($name);
+                       }
+                       else {
+                               $out .= $comma.refNameFull( $ances );
+                       }
+                       
+                       $out .= " &lt;".wordRef($template, $rootnode )."&gt;"
+                               unless !defined $template;
+
+                       if ( exists $ances->{ExtSource} ) {
+                               $out .=" <small>(".$ances->{ExtSource}
+                               .")</small>";
+                       }
+
+                       $out .= " <small>[$type]</small>" 
+                               unless $type eq "public";
+
+                       $comma = ", ";
+
+               },
+               sub { # end
+                       $extra .= tabRow( "Inherits", $out );
+               }
+       );
+
+       # descendants
+       Iter::Descendants( $node, undef,
+               sub { $comma = $out = ""; },            # start
+               sub {                                   # print
+                       my ( $in ) = @_;
+                       $out .= $comma.refName( $in );
+
+                       if ( exists $in->{ExtSource} ) {
+                               $short .= " <small>(".
+                               $in->{ExtSource}.")</small>";
+                       }
+       
+                       $comma = ", ";
+
+               },
+               sub {                                   # end
+                       $extra .= tabRow( "Inherited by", $out );
+               }
+       );
+
+       $extra .= '<TR><TH>'.
+               hyper( encodeURL("full-list-".$node->{Ref}),
+                       "List of all Methods" )."</TH></TR>";
+
+
+       #### print it
+
+       newPgHeader( *CLASS{IO}, 
+               $node->{NodeType}." ".esc($node->{astNodeName}), 
+               $short, $extra, \%toclinks );
+
+
+       if( $#{$node->{Kids}} < 0 ) {
+               print CLASS "<center><H4>No members</H4></center>\n";
+       }
+       else {
+               Iter::MembersByType ( $node, 
+                       sub { print CLASS "<h4>", $_[0], "</h4><ul>"; },
+                       sub {   my ($node, $kid ) = @_; 
+                               listMember( $node, $kid ); },
+                       sub { print CLASS "</ul>"; }
+               );
+       }
+
+       # long description
+       if ( kdocAstUtil::hasDoc( $node ) ) {
+               print CLASS "<HR><A NAME=\"longdesc\">",
+                       "<H2>Detailed Description</H2>";
+               printDoc( $docnode, *CLASS, $node, 1 );
+       }
+
+       # member doc
+       my $kid;
+       my ($numref, $ref);
+
+                       
+       Iter::DocTree( $node, 0, 0,
+               sub {                                   # common
+                       my ( $node, $kid ) = @_;
+
+                       if( !exists $kid->{NumRef} ) {
+                               warn $kid->{astNodeName}, " type ",
+                               $kid->{NodeType}, " doesn't have a numref\n";
+                       }
+
+                       ( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
+                       ( $ref = $kid->{Ref} ) =~ s/^.*?#//g;
+
+                       printMemberName( $kid, $ref, $numref );
+                       printDoc( $kid->{DocNode}, *CLASS, $node );
+
+                       return;
+               },
+               undef,                                  # compound
+               sub {                                   # other
+                       my ( $node, $kid ) = @_;
+
+                       if ( $kid->{NodeType} eq "method" ) {
+                               $ref = kdocAstUtil::findOverride( $rootnode, 
+                                               $node, $kid->{astNodeName} );
+                               if ( defined $ref ) {
+                                       print CLASS "<p>Reimplemented from ",
+                                               refName( $ref ), "</p>\n";
+                               }
+                       }
+
+                       return;
+               }
+       );
+
+       # done
+
+       if ( defined $version || defined $author ) {
+               print CLASS "<HR><UL>",
+                       defined $version ? 
+                               "<LI><i>Version</i>: $version</LI>" : "",
+                       defined $author ? 
+                               "<LI><i>Author</i>: $author</LI>" : "",
+                       "<LI><i>Generated</i>: $gentext</LI></UL>",
+                       "</BODY></HTML>\n";
+       }
+       else {
+               print CLASS $docBotty;
+       }
+
+       close CLASS;
+
+       # full member list
+
+       writeAllMembers( $node );
+}
+
+sub writeGlobalDoc
+{
+       my( $node, $file ) = @_;
+       my $docnode = $node->{DocNode};
+       my $hasdoc = exists $node->{DocNode} ? 1 : 0;
+       my $cumu = Ast::New( "nodelist" );
+
+       # make a list of nodes by file
+       foreach my $kid ( @{$node->{Kids}} ) {
+               next if exists $kid->{ExtSource} 
+                       || exists $kid->{Compound}
+                       || (!$main::doPrivate && 
+                               $kid->{Access} =~ /private/);
+
+               if ( exists $kid->{Source} ) {
+                       $kid->{Source}->AddPropList( "Glob", $kid )
+               }
+       }
+
+       open( CLASS, ">$file" ) || die "Couldn't create $file\n";
+
+       newPgHeader( *CLASS{IO}, $lib." Globals", "", "", \%toclinks );
+
+       my @list = sort { $a->{astNodeName} cmp $b->{astNodeName} } 
+               @{$node->{Sources}};
+
+       foreach my $source ( @list ) {
+               next unless defined $source->{Glob};
+
+               listMethods( $node, refName( $source ), "", $source->{Glob} );
+       }
+
+       # member doc
+       my ($numref, $ref);
+
+       foreach my $source ( @list ) {
+               next unless defined $source->{Glob};
+
+               foreach my $kid ( @{$source->{Glob}} ) {
+                       next if exists $kid->{ExtSource} 
+                       || exists $kid->{Compound}
+                       || !exists $kid->{DocNode}
+                       || (!$main::doPrivate && 
+                                       $kid->{Access} =~ /private/);
+
+                       if( !exists $kid->{NumRef} ) {
+                               warn $kid->{astNodeName}, " type ",
+                               $kid->{NodeType}, " doesn't have a numref\n";
+                       }
+
+                       ( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
+                               ( $ref = $kid->{Ref} ) =~ s/^.*?#//g;
+
+                       printMemberName( $kid, $ref, $numref );
+
+                       print CLASS "<p><small><code>#include &lt;",
+                               refName( $source ),
+                               "&gt;</code></small></p>";
+
+                       printDoc( $kid->{DocNode}, *CLASS, $node );
+               }
+       }
+
+       print CLASS $docBotty;
+       close CLASS;
+}
+
+
+sub listMember
+{
+       my( $class, $m ) = @_;
+       my $name;
+
+       if( exists $m->{Compound} ) {
+               # compound docs not printed for rootnode
+               next if $class eq $rootnode; 
+
+               $name = refName( $m );
+       }
+       elsif( exists $m->{DocNode} ) {
+               # compound nodes have their own page
+               $name = refName( $m,  'NumRef' );
+       } else {
+               $name = esc( $m->{astNodeName} );
+       }
+
+       my $type = $m->{NodeType};
+
+       print CLASS "<LI>";
+
+       if( $type eq "var" ) {
+               print CLASS esc( $m->{Type}), B( "b", $name );
+       }
+       elsif( $type eq "method" ) {
+               my $flags = $m->{Flags};
+
+               if ( !defined $flags ) {
+                       warn "Method ".$m->{astNodeName}.  " has no flags\n";
+               }
+
+               $name = B("i", $name ) if $flags =~ /p/;
+               $name = B("b", $name );
+
+               my $extra = "";
+               $extra .= "virtual " if $flags =~ "v";
+               $extra .= "static " if $flags =~ "s";
+
+               print CLASS $extra, textRef($m->{ReturnType}, $rootnode ),
+                       "\&nbsp;$name (", textRef( $m->{Params}, $rootnode ), ") ", 
+                       $flags =~ /c/ ? " const\n": "\n";
+       }
+       elsif( $type eq "enum" ) {
+               print CLASS "enum $name {", esc($m->{Params}),"}\n";
+       }
+       elsif( $type eq "typedef" ) {
+               print CLASS "typedef ", esc($m->{Type}), " $name\n";
+       }
+       else { 
+               # unknown type
+               print CLASS esc($type), " $name\n";
+       }
+
+       print CLASS "</LI>\n";
+
+}
+
+sub listMethods
+{
+       my( $class, $desc, $vis, $nodes ) = @_;
+       my $name;
+       my $type;
+       my $flags;
+       my @n=();
+       
+       if ( !defined $nodes ) { 
+               kdocAstUtil::findNodes( \@n, $class->{Kids}, 
+                       "Access", $vis );
+               $nodes = \@n;
+       }
+
+       return if ( $#{$nodes} < 0 );
+
+print CLASS<<EOF;
+<H2>$desc</H2>
+<UL>
+EOF
+       foreach my $m ( @$nodes ) {
+               next if exists $m->{ExtSource};
+               if( exists $m->{Compound} ) {
+                       # compound docs not printed for rootnode
+                       next if $class eq $rootnode; 
+
+                       $name = refName( $m );
+               }
+               elsif( exists $m->{DocNode} ) {
+                       # compound nodes have their own page
+                       $name = refName( $m,  'NumRef' );
+               } else {
+                       $name = esc( $m->{astNodeName} );
+               }
+
+               $type = $m->{NodeType};
+               $name = B( "b", $name );
+
+               print CLASS "<LI>";
+
+               if( $type eq "var" ) {
+                       print CLASS esc( $m->{Type}), " $name\n";
+               }
+               elsif( $type eq "method" ) {
+                       $flags = $m->{Flags};
+
+                       if ( !defined $flags ) {
+                               warn "Method ".$m->{astNodeName}.
+                                       " has no flags\n";
+                       }
+
+                       $name = "<i>$name</i>" if $flags =~ /p/;
+                       my $extra = "";
+                       $extra .= "virtual " if $flags =~ "v";
+                       $extra .= "static " if $flags =~ "s";
+
+                       print CLASS $extra, textRef($m->{ReturnType}, $rootnode), 
+                               "\&nbsp;$name (", textRef( $m->{Params}, $rootnode), ") ", 
+                               $flags =~ /c/ ? " const\n": "\n";
+               }
+               elsif( $type eq "enum" ) {
+                       print CLASS "enum $name {", esc($m->{Params}),"}\n";
+               }
+               elsif( $type eq "typedef" ) {
+                       print CLASS "typedef ", esc($m->{Type}), " $name";
+               }
+               else { 
+                       # unknown type
+                       print CLASS esc($type), " $name\n";
+               }
+
+               print CLASS "</LI>\n";
+       }
+
+print CLASS<<EOF;
+</UL>
+EOF
+
+}
+
+=head2 printIndexEntry
+
+       Parameters: member node
+
+       Prints an index entry for a single node.
+
+       TODO: stub
+
+=cut
+
+sub printIndexEntry
+{
+       my ( @node ) = @_;
+}
+
+=head2 printMemberName
+
+       Parameters: member node, names...
+
+       Prints the name of one member, customized to type. If names are
+       specified, a name anchor is written for each one.
+
+=cut
+
+sub printMemberName
+{
+       my $m = shift;
+
+       my $name = B( "underline", esc( $m->{astNodeName} ) );
+       my $type = $m->{NodeType};
+       my $ref;
+       my $flags = undef;
+
+       foreach $ref ( @_ ) {
+               print CLASS "<A NAME=\"", $ref, "\"></A>";
+       }
+
+       print CLASS '<table width="100%"><tr bgcolor="#eeeeee"><td><strong>';
+
+       if( $type eq "var" ) {
+               print CLASS textRef($m->{Type}, $rootnode ), " $name\n";
+       }
+       elsif( $type eq "method" ) {
+               $flags = $m->{Flags};
+               $name = "<i>$name</i>" if $flags =~ /p/;
+
+               print CLASS textRef($m->{ReturnType}, $rootnode ),
+                       "\&nbsp;$name (", textRef($m->{Params}, $rootnode ), ")\n";
+       }
+       elsif( $type eq "enum" ) {
+               print CLASS "enum $name {", esc($m->{Params}),"}\n";
+       }
+       elsif( $type eq "typedef" ) {
+               print CLASS "typedef ", 
+               textRef($m->{Type}, $rootnode ), " $name";
+       }
+       else {
+               print CLASS $name, " ", B( "small", "(", esc($type), ")" );
+       }
+
+       print CLASS "</strong></td></tr></table><p>";
+
+# extra attributes
+       my @extra = ();
+
+       if( !exists $m->{Access} ) {
+               warn "Member without access:\n";
+               kdocAstUtil::dumpAst( $m );
+       }
+
+       ($ref = $m->{Access}) =~ s/_slots//g;
+
+       push @extra, $ref
+               unless $ref =~ /public/
+               || $ref =~ /signal/;
+
+       if ( defined $flags ) {
+               foreach my $f ( split( "", $flags ) ) {
+                       my $n = $main::flagnames{ $f };
+
+                       if ( defined $n ) {
+                               push @extra, $n;
+                       }
+                       else {
+                               warn "flag $f has no long name.";
+                       }
+
+               }
+       }
+
+       if ( $#extra >= 0 ) {
+               print CLASS " <small>[", join( " ", @extra ), "]</small>";
+       }
+
+       print CLASS "</p>";
+
+       return;
+}
+
+
+
+sub writeSrcHTML
+{
+       my ( $outfile, $infile ) = @_;
+
+       open ( OUT, ">$outfile" ) || die "Couldn't open $outfile for".
+                       "writing.\n";
+
+       newPgHeader( *OUT{IO}, "Source: $infile", "", "", \%toclinks );
+       makeHeader( *OUT{IO}, $infile );
+
+       print OUT $docBotty;
+       close OUT;
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm b/deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm
new file mode 100644 (file)
index 0000000..8bbcca1
--- /dev/null
@@ -0,0 +1,1232 @@
+package kdocCxxLaTeX;
+
+use File::Path;
+use File::Basename;
+
+use Carp;
+use Ast;
+use kdocAstUtil;
+
+=head1 kdocCxxLaTex
+
+Capabilities required from Ast bit: 
+
+1. Create an inheritance tree
+
+2. Referencing ability: convert a fully qualified class or member name
+       to a node reference.
+
+=cut
+
+BEGIN
+{
+       @clist = ();
+       @docQueue = ();
+
+        eval { 
+          use Sys::Hostname;
+          $host = hostname();
+          chomp $host;
+        };
+        eval { 
+          $who = `whoami`;     
+         if($who =~ /DCL-W-IVVERB/) {
+             $who = `show process`;
+             ($who) = ( $who =~ /User: ([^\s]+)/ );
+         }
+          chomp $who; 
+        };
+        $now = localtime;      
+        chomp $now; 
+        $gentext = "$who\@$host, $now.";
+}
+
+sub writeDoc
+{
+       ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+       $debug = $main::debug;
+
+       print "Generating LaTeX documentation. \n" unless $main::quiet;
+
+       mkpath( $outputdir ) unless -f $outputdir;
+
+#      makeReferences( $rootnode );
+       makeClassList( $rootnode );
+
+        startMainDocument();
+
+# ??? Wykomentowane rzeczy jeszcze nie przerobione
+
+       writeGlobalDoc( $rootnode );
+       writeAnnotatedList( $rootnode );
+       writeHier( $rootnode );
+#      writeHeaderList();
+
+       foreach $node ( @{$rootnode->{Kids}} ) {
+               next if !defined $node->{Compound} 
+                       || defined $node->{ExtSource}
+                       || $node->{NodeType} eq "Forward";
+
+               push @docQueue, $node;
+       }
+
+        # Próbujemy posortowaæ t± kolejkê
+        @docQueue = sort { $b->{astNodeName} cmp $a->{astNodeName} } @docQueue;
+
+       while( $#docQueue >= 0 ) {
+               $node = pop @docQueue;
+               writeClassDoc( $node );
+       }
+
+       print "Generating LaTeXized headers.\n" unless $main::quiet;
+       foreach $header ( @main::ARGV ) {
+               markupCxxHeader( $header, $rootnode );
+       }
+
+        finishMainDocument();
+}
+
+=head2 writeAnnotatedList
+
+       Parameters: rootnode
+
+       Writes out a list of classes with short descriptions to
+       index-long.tex.
+
+=cut
+
+sub writeAnnotatedList
+{
+       my ( $root ) = @_;
+       my $short;
+
+       open(CLIST, ">$outputdir/index-long.tex") 
+       || die "Couldn't create $outputdir/index-long.tex\n";
+
+        print MAIN "\\input{index-long.tex}\n\n";
+
+       print CLIST sectionHeader( "Lista klas " . $lib );
+        print CLIST <<EOF;
+\\begin{longtable}{lp{8cm}}        
+EOF
+       foreach $node ( @clist ) {
+               print  "undef in clist\n" if !defined $node;
+
+               $docnode = $node->{DocNode};
+               $short = "";
+
+               if( defined $docnode && exists $docnode->{ClassShort} ) {
+                       $short = deref($docnode->{ClassShort}, $rootnode );
+                       if( !defined $short ) {
+                               print $root->{astNodeName}, "has undef short\n";
+                               next;
+                       }
+                               
+               }
+
+               print CLIST refName($node), ' & ', $short, "\\\\\n";                
+       }
+
+       print CLIST "\\end{longtable}\n";
+       close CLIST;
+}
+
+=head2 writeClassList
+
+       Parameters: rootnode
+
+       Writes out a concise list of classes to index.tex
+
+=cut
+
+=head3
+
+       Parameters: list, start index, end index
+
+       Helper for writeClassList.  Prints a table containing a
+       hyperlinked list of all nodes in the list from start index to
+       end index. A table header is also printed.
+
+=cut
+
+sub writeListPart
+{
+       my( $list, $start, $stop ) = @_;
+
+       print CLIST "<TABLE BORDER=\"0\">";
+
+       print CLIST "<TR><TH>", 
+               esc( $list->[ $start ]->{astNodeName} ),
+               " - ", esc( $list->[ $stop ]->{astNodeName} ), 
+               "</TH></TR>";
+
+       for $ctr ( $start..$stop ) {
+               print CLIST "<TR><TD>", refName( $list->[ $ctr ] ),
+                       "</TD></TR>\n";
+       }
+
+       print CLIST "</TABLE>";
+}
+
+
+=head2 writeAllMembers
+
+       Parameters: node
+
+       Writes a list of all methods to "full-list-<class file>"
+
+=cut
+
+sub writeAllMembers
+{
+       my( $node ) = @_;
+       my $file = "$outputdir/full-list-".$node->{Ref};
+       my %allmem = ();
+
+       kdocAstUtil::allMembers( \%allmem, $node );
+
+       open( ALLMEM, ">$file" ) || die "Couldn't create $file\n";
+
+        my $thisClassName = $node->{astNodeName};
+       print ALLMEM sectionHeader( "Wszystkie metody " . esc($thisClassName) ),
+               "<UL>";
+
+       my $mem;
+       foreach $mem ( sort keys %allmem ) {
+                my $parentName = $allmem{$mem}->{Parent}->{astNodeName};
+               print ALLMEM "<LI>";
+                print ALLMEM refName( $allmem{ $mem } );
+                if($parentName ne $thisClassName) {
+                  print ALLMEM " <small>[$parentName]</small>"
+                }
+                print ALLMEM "</LI>\n";
+       }
+
+       print ALLMEM "</UL>$docBotty";
+
+       close ALLMEM;
+}
+
+=head2 writeHier
+
+       Parameters: rootnode
+
+       Writes out the class hierarchy index to hier.html.
+
+=cut
+
+sub writeHier
+{
+       my ( $root ) = @_;
+
+       open( HIER, ">$outputdir/hier.tex") 
+               || die "Couldn't create $outputdir/hier.tex\n";
+
+        print MAIN "\\input{hier.tex}\n\n";
+
+       print HIER sectionHeader( $lib.": Class Hierachy" );
+
+       printNodeHier( $root, 0 );
+
+       close HIER;
+}
+
+=head3 printNodeHier
+
+       Parameters: node
+
+       Lists all classes that inherit from this node in an unordered list.
+
+=cut
+
+sub printNodeHier 
+{
+       my( $node, $level ) = @_;
+       my $kid;
+       my $src = "";
+
+       # non-derived external classes are not printed.
+       if ( defined $node->{ExtSource} ) {
+               return if !defined $node->{InBy} 
+                       || !kdocAstUtil::hasLocalInheritor( $node );
+
+               $src = "{\\small ".$node->{ExtSource}.")}";
+       }
+
+#      print HIER "\\item ", 
+        print HIER "\\verb!", '   ' x $level, "!",
+                   refName( $node )," $src\\\\\n" 
+           unless $node == $rootnode;
+
+       return if !defined $node->{InBy};
+
+#      print HIER "\\begin{itemize}\n";
+
+       foreach $kid ( sort { $a->{astNodeName} cmp $b->{astNodeName} } 
+                       @{ $node->{InBy} } ) {
+               printNodeHier( $kid, $level + 1 );
+       }
+#      print HIER "\\end{itemize}\n";
+}
+
+=head2 writeHeaderList
+
+       Generates the header-list.html file, which contains links
+       to each processed header. The ARGV list is used.
+
+=cut
+
+sub writeHeaderList
+{
+       open(HDRIDX, ">$outputdir/header-list.html") 
+       || die "Couldn't create $outputdir/header-list.html\n";
+
+       print HDRIDX sectionHeader( $lib . ": Header List" ), "<UL>\n";
+
+       foreach $header ( sort @main::ARGV ) {
+               $_ = $header;
+               $header = basename ( $_ ) if $main::striphpath;
+# convert dashes to double dash, convert path to dash
+               s/-/--g/g;
+               s/\/|\./-/g;
+
+               print HDRIDX  "\t<LI>",hyper($_.".html",$header),"</LI>\n";
+       }
+       
+       print HDRIDX "</UL>\n",$docBotty;
+
+}
+
+=head2 sectionHeader
+
+       Parameters: libname, heading
+
+       Returns a string containing an HTML section heading.
+
+=cut
+
+sub sectionHeader
+{
+       my( $heading, $desc ) = @_;
+
+       $desc = "" if !defined $desc;
+
+       my $libtext = "";
+       if( $lib ne "" ) {
+               $libtext = "<TR><TD><small>Dokumentacja $lib</small>".
+                       "</TD></TR>";
+       }
+
+       return <<EOF;
+\\section{$heading}
+
+EOF
+       
+}
+
+=head2 writeClassDoc
+
+       Write documentation for one compound node.
+
+=cut
+
+sub writeClassDoc
+{
+       my( $node ) = @_;
+       if( exists $node->{ExtSource} ) {
+               warn "Trying to write doc for ".$node->{AstNodeName}.
+                       " from ".$node->{ExtSource}."\n";
+               return;
+       }
+
+       my $file = "$outputdir/".$node->{astNodeName}.".tex";
+       my $docnode = $node->{DocNode};
+       my $hasdoc = exists $node->{DocNode} ? 1 : 0;
+       my @list = ();
+       my $version = undef;
+       my $author = undef;
+
+       open( CLASS, ">$file" ) || die "Couldn't create $file\n";
+
+        print MAIN "\\input{".$node->{astNodeName}.".tex}\n\n";
+
+       # Header
+        
+       my $source = kdocAstUtil::nodeSource( $node );
+       my $short = "";
+
+       if( $hasdoc ) {
+               if ( exists $docnode->{ClassShort} ) {
+#                      $short .= deref($docnode->{ClassShort}, $rootnode );
+                       $short .= $docnode->{ClassShort};
+               }
+
+               if ( exists $docnode->{Deprecated} ) {
+                       $short .= "\n\n\\textbf{Przestarza³e: u¿ywaæ ostro¿nie.}";
+               }
+
+               if ( exists $docnode->{Internal} ) {
+                       $short .= "\n\n\\textbf{Tylko do wewnêtrznego u¿ytku.}";
+               }
+               $version = esc($docnode->{Version}) 
+                       if exists $docnode->{Version};
+               $author = esc($docnode->{Author}) 
+                       if exists $docnode->{Author};
+       }
+
+       # pure virtual check
+       if ( exists $node->{Pure} ) {
+               $short .= 
+                       "\n\n\\textbf{Klasa abstrakcyjna}\n\n";
+       }
+       
+       # full name, if not in global scope
+       if ( $node->{Parent} != $rootnode ) {
+               $short .= "\n\n\\texttt{" . $node->{astNodeName} ."}";
+       }
+
+       # include
+        # MK --> hack (link z #include)
+       $short .= "\n\n\\verb!#include <".$source.">!\n\n";
+
+       # template form
+       if ( exists $node->{Tmpl} ) {
+               $short .= "\n\nKlasa parametryzowana (template): \\verb!<"
+                       .textRef($node->{Tmpl}, $rootnode)."> ".
+                       esc($node->{astNodeName}, 
+                       $rootnode )."!\n\n";
+       }
+
+       # inheritance
+       if ( $node != $rootnode && exists $node->{InList} ) {
+               my $comma = "Dziedziczy z: ";
+
+               foreach $in ( @{ $node->{InList} } ) {
+                       next if $in == $rootnode;
+
+                       $short .= $comma.refName( $in );
+                       if ( exists $in->{ExtSource} ) {
+                               $short .= " {\\small(".$in->{ExtSource}
+                                       .")}";
+                       }
+                       
+                       $comma = ", ";
+               }
+
+               $short .= "\n\n";
+       }
+
+       if ( $node != $rootnode && exists $node->{InBy} ) {
+               my $comma .= "Klasy dziedzicz±ce: ";
+
+               @list = ();
+               kdocAstUtil::inheritedBy( \@list, $node );
+
+               foreach $in ( @list ) {
+                       $short .= $comma.refName( $in );
+                       if ( exists $in->{ExtSource} ) {
+                               $short .= " {\\small(".
+                               $in->{ExtSource}.")}";
+                       }
+       
+                       $comma = ", ";
+               }
+               $short .= "\n\n";
+       }
+
+       # print it
+
+       print CLASS sectionHeader( 
+               $node->{NodeType}." ".esc($node->{astNodeName}), 
+               $short );
+
+       if( $#{$node->{Kids}} < 0 ) {
+               print CLASS <<EOF;
+\\begin{quote}
+Brak sk³adowych
+\\end{quote}
+EOF
+       }
+       else {
+               listMethods( $node, "Sk³adowe publiczne", "public" );
+               listMethods( $node, "Public Slots", "public_slots" );
+               listMethods( $node, "Sk³adowe chronione", "protected" );
+               listMethods( $node, "Protected Slots", "protected_slots" );
+               listMethods( $node, "Signals", "signals" );
+
+               if ( $main::doPrivate ) {
+                       listMethods( $node, "Sk³adowe prywatne", "private" );
+                       listMethods( $node, "Private Slots", "private_slots" );
+               }
+       }
+
+       # long description
+       if ( $hasdoc ) {
+               print CLASS "\n\\subsection*{Opis klasy}\n\n";
+               printDoc( $docnode, *CLASS, $rootnode, 1 );
+       }
+
+       # member doc
+       my $kid;
+       my ($numref, $ref);
+
+       foreach $kid ( @{$node->{Kids}} ) {
+                       next if defined $kid->{ExtSource} 
+                       || $node->{NodeType} eq "Forward"
+                       || (!$main::doPrivate && 
+                               $kid->{Access} =~ /private/);
+
+               if ( exists $kid->{Compound} ) {
+                       push @docQueue, $kid;
+               }
+
+               next if !defined $kid->{DocNode};
+
+# ??? Przywróciæ kiedy¶
+#              if( !exists $kid->{NumRef} ) {
+#                      warn $kid->{astNodeName}, " type ",
+#                      $kid->{NodeType}, " doesn't have a numref\n";
+#              }
+
+# ??? Przywróciæ kiedy¶ ???
+#              ( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
+#              ( $ref = $kid->{Ref} ) =~ s/^.*?#//g;
+
+               printMemberName( $kid, $ref, $numref );
+               printDoc( $kid->{DocNode}, *CLASS, $rootnode );
+
+               if ( $kid->{NodeType} eq "method" ) {
+                       $ref = kdocAstUtil::findOverride( $rootnode, $node, 
+                               $kid->{astNodeName} );
+                       if ( defined $ref ) {
+                               print CLASS "\n\nPrzykrywa metodê z klasy ",
+                                       refName( $ref ), "\n\n";
+                       }
+               }
+       }
+
+       # done
+
+#      if ( defined $version || defined $author ) {
+#              print CLASS "\\begin{itemize}\n",
+#                      defined $version ? 
+#                          "\\item Wersja: $version;\n" : "",
+#                      defined $author ? 
+#                          "\\item Autor: $author;\n" : "",
+#                          "\\item Generowane: $gentext;\n",
+#                          "\\end{itemize}\n";
+#      }
+#      else {
+#              print CLASS "Generowane: $gentext\n";
+#      }
+
+       close CLASS;
+
+       # full member list
+
+#      ??? Kiedy¶ jednak zrobiæ
+#      writeAllMembers( $node );
+}
+
+sub writeGlobalDoc
+{
+       my( $node ) = @_;
+       my $file = "$outputdir/all-globals.tex";
+       my $docnode = $node->{DocNode};
+       my $hasdoc = exists $node->{DocNode} ? 1 : 0;
+       my @list = ();
+       my $cumu = Ast::New( "nodelist" );
+       my $kid;
+
+       # make a list of nodes by file
+       foreach $kid ( @{$node->{Kids}} ) {
+               next if exists $kid->{ExtSource} 
+                       || exists $kid->{Compound}
+                       || (!$main::doPrivate && 
+                               $kid->{Access} =~ /private/);
+
+               $cumu->AddPropList( kdocAstUtil::nodeSource( $kid ), $kid )
+                       unless !exists $kid->{Source};
+       }
+
+       open( CLASS, ">$file" ) || die "Couldn't create $file\n";
+
+        print MAIN "\\input{all-globals.tex}\n\n";
+
+       print CLASS sectionHeader( "Zmienne, typy i funkcje globalne " . $lib);
+       @list = sort keys %$cumu;
+
+       foreach $file ( @list ) {
+               next if $file eq "astNodeName";
+
+               listMethods( $node, esc($file), "", $cumu->{$file} );
+       }
+
+       # member doc
+       my ($numref, $ref);
+
+       foreach $file ( @list ) {
+               next if $file eq "astNodeName";
+               
+               foreach $kid ( @{$cumu->{$file}} ) {
+                       next if exists $kid->{ExtSource} 
+                       || exists $kid->{Compound}
+                       || !exists $kid->{DocNode}
+                       || (!$main::doPrivate && 
+                                       $kid->{Access} =~ /private/);
+
+# ??? Przywróciæ kiedy¶
+#                      if( !exists $kid->{NumRef} ) {
+#                              warn $kid->{astNodeName}, " type ",
+#                              $kid->{NodeType}, " doesn't have a numref\n";
+#                      }
+
+# ??? Przywróciæ kiedy¶
+#                      ( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
+#                              ( $ref = $kid->{Ref} ) =~ s/^.*?#//g;
+
+                        printMemberName( $kid, $ref, $numref );
+                        
+                       print CLASS "\n\n{\\small\\verb!#include <",
+                               kdocAstUtil::nodeSource( $kid ), 
+                               ">!}\n\n";
+
+                       printDoc( $kid->{DocNode}, *CLASS, $rootnode );
+               }
+       }
+
+#      print CLASS $docBotty;
+       close CLASS;
+}
+
+sub listMethods
+{
+       my( $class, $desc, $vis, $nodes ) = @_;
+       my $name;
+       my $type;
+       my $flags;
+       my @n=();
+       
+       if ( !defined $nodes ) { 
+               kdocAstUtil::findNodes( \@n, $class->{Kids}, 
+                       "Access", $vis );
+               $nodes = \@n;
+       }
+
+       return if ( $#{$nodes} < 0 );
+
+print CLASS<<EOF;
+\\subsection*{$desc}
+
+\\begin{itemize}
+EOF
+       foreach $m ( @$nodes ) {
+               next if exists $m->{ExtSource};
+               if( exists $m->{Compound} ) {
+                       # compound docs not printed for rootnode
+                       next if $class eq $rootnode; 
+
+                       $name = refName( $m );
+               }
+               elsif( exists $m->{DocNode} ) {
+                       # compound nodes have their own section
+                       $name = refName( $m,  'NumRef' );
+               } else {
+                       $name = esc( $m->{astNodeName} );
+               }
+
+               $type = $m->{NodeType};
+
+               print CLASS "\\item ";
+
+               if( $type eq "var" ) {
+                       print CLASS esc( $m->{Type}), 
+                               " \\textbf{", $name,"}\n";
+               }
+               elsif( $type eq "method" ) {
+                       $flags = $m->{Flags};
+
+                       if ( !defined $flags ) {
+                               warn "Method ".$m->{astNodeName}.
+                                       " has no flags\n";
+                       }
+
+                       $name = "\\emph{$name}" if $flags =~ /p/;
+                       my $extra = "";
+                       $extra .= "virtual " if $flags =~ "v";
+                       $extra .= "static " if $flags =~ "s";
+
+                       print CLASS $extra, esc($m->{ReturnType}),
+                               " \\textbf{", $name, "} (", 
+                               esc($m->{Params}), ") ", 
+                               $flags =~ /c/ ? " const\n": "\n";
+               }
+               elsif( $type eq "enum" ) {
+                       print CLASS "enum \\textbf{", $name, "} {",
+                               esc($m->{Params}),"}\n";
+               }
+               elsif( $type eq "typedef" ) {
+                       print CLASS "typedef ", 
+                               esc($m->{Type}), " \\textbf{",
+                               $name,"}";
+               }
+               else { 
+                       # unknown type
+                       print CLASS esc($type), " \\textbf{",
+                               $name,"}\n";
+               }
+
+               print CLASS "\n";
+       }
+
+print CLASS<<EOF;
+\\end{itemize}
+EOF
+
+}
+
+=head2 printIndexEntry
+
+       Parameters: member node
+
+       Prints an index entry for a single node.
+
+       TODO: stub
+
+=cut
+
+sub printIndexEntry
+{
+       my ( @node ) = @_;
+}
+
+=head2 printMemberName
+
+       Parameters: member node, names...
+
+       Prints the name of one member, customized to type. If names are
+       specified, a name anchor is written for each one.
+
+=cut
+
+sub printMemberName
+{
+       my $m = shift;
+
+       my $name = esc( $m->{astNodeName} );
+       my $type = $m->{NodeType};
+       my $ref;
+       my $flags = undef;
+
+       foreach $ref ( @_ ) {
+# ??? Pomy¶leæ o tym
+#              print CLASS "\\label{", $ref, "}";
+       }
+
+#      print CLASS "\n\n\\textbf{";
+       print CLASS "\n\n\\subsubsection*{";
+
+       if( $type eq "var" ) {
+               print CLASS textRef($m->{Type}, $rootnode ), 
+               " \\texttt{", $name,"} ";
+       }
+       elsif( $type eq "method" ) {
+               $flags = $m->{Flags};
+               $name = "\\emph{$name}" if $flags =~ /p/;
+
+               print CLASS textRef($m->{ReturnType}, $rootnode ),
+               " \\texttt{", $name, "} (", 
+               textRef($m->{Params}, $rootnode ), ") ";
+       }
+       elsif( $type eq "enum" ) {
+               print CLASS "enum \\texttt{", $name, "} {",
+               esc($m->{Params}),"} ";
+       }
+       elsif( $type eq "typedef" ) {
+               print CLASS "typedef ", 
+               textRef($m->{Type}, $rootnode ), " \\texttt{",
+               $name,"} ";
+       }
+       else {
+               print CLASS $name, " {\\small (", 
+                       esc($type), ")} ";
+       }
+
+# extra attributes
+       my @extra = ();
+
+       if( !exists $m->{Access} ) {
+               print "Member without access:\n";
+               kdocAstUtil::dumpAst( $m );
+       }
+
+       ($ref = $m->{Access}) =~ s/_slots//g;
+
+       push @extra, $ref
+               unless $ref =~ /public/
+               || $ref =~ /signal/;
+
+       if ( defined $flags ) {
+               my $f;
+               my $n;
+               foreach $f ( split( "", $flags ) ) {
+                       $n = $main::flagnames{ $f };
+                       warn "flag $f has no long name.\n" if !defined $n;
+                       push @extra, $n;
+               }
+       }
+
+       if ( $#extra >= 0 ) {
+               print CLASS " {\\small [", join( " ", @extra ), "]}";
+       }
+
+       print CLASS "}"; # Po subsubsection
+       print CLASS "\n\n";
+       
+# finis
+}
+
+
+
+=head2 makeClassList
+
+       Parameters: node
+
+       fills global @clist with a list of all direct, non-external
+       compound children of node.
+
+=cut
+
+sub makeClassList
+{
+       my ( $rootnode ) = @_;
+
+       @clist = ();
+
+       foreach $node ( @ {$rootnode->{Kids}} ) {
+               if ( !defined $node ) {
+                       print "makeClassList: undefined child in rootnode!\n";
+                       next;
+               }
+
+               push( @clist, $node ) unless exists $node->{ExtSource}
+                               || !exists $node->{Compound};
+       }
+
+       @clist = sort { $a->{astNodeName} cmp $b->{astNodeName}  }
+                       @clist;
+}
+
+# MK --> skopiowane z 1.0
+sub markupCxxHeader
+{
+       my( $filename, $rootnode ) = @_;
+       $className = "";
+       my( $reference );
+       my( @inheritance );
+       my( $word );
+
+       open( HFILE, $filename ) || die "Couldn't open $filename to read.\n";
+
+       $_ = $filename;
+       # convert dashes to double dash, convert path to dash
+       s/-/--g/g;
+       s/\/|\./-/g;
+       $outputName = $_;
+       $outputFilename = $outputdir."/".$outputName;
+
+       open( HTMLFILE, ">$outputFilename.tex" ) 
+               || die "Couldn't open $outputFilename to write.\n";
+
+        print MAIN "\\input{$outputName.tex}\n\n";
+
+        print HTMLFILE sectionHeader( esc("$filename") );
+
+        print HTMLFILE <<EOF;
+\\selectlisting{cpp}
+\\begin{listing}
+EOF
+       while( <HFILE> )
+       {
+          print HTMLFILE;
+
+# ??? Co¶ zrobiæ
+#              if( /^\s*(template.*\s+)?(class|struct)/ ) {
+#                    if($rootnode) {
+#                      $_ = textRef($_, $rootnode);
+#                    } else {
+#                        print STDERR "$0: can not make hyperlinks in file $filename\n";
+#                    }
+#              }
+
+       }
+
+        print HTMLFILE <<EOF;
+\\end{listing}
+EOF
+}
+
+sub startMainDocument {
+
+  open(MAIN, ">$outputdir/main.tex")
+    || die "Couldn't create $outputdir/main.tex\n";
+    
+  print MAIN <<EOF;
+\\documentclass[a4paper,10pt]{article}
+
+% Geometria strony (twoside ?)
+\\usepackage[a4paper,hmargin={2cm,2cm},vmargin={2cm,2cm}]{geometry}
+
+\\usepackage[latin2]{inputenc}
+\\usepackage{polski}
+
+\\usepackage{longtable}
+
+% Specyficzne listingi
+\\usepackage{listings}
+\\keywordstyle{\\bfseries\\sffamily}
+%\\commentstyle{\\slshape}
+\\commentstyle{\\itshape}
+%\\stringstyle{\\ttfamily}
+\\blankstringtrue
+\\prelisting{\\small\\sffamily}
+
+% Przynajmniej nie bêdzie krzycza³
+% \\catcode`\\_=12
+
+% Odstêpy miêdzy akapitami itp
+\\setlength{\\parindent}{0cm}
+\\addtolength{\\parskip}{1ex}
+
+\\title{Dokumentacja referencyjna $lib}
+
+\\begin{document}
+
+\\maketitle
+\\tableofcontents
+
+\\begin{abstract}
+Dokumentacja referencyjna $lib. 
+
+Generowana: $gentext.
+\\end{abstract}
+
+EOF
+}
+
+sub finishMainDocument {
+  print MAIN <<EOF;
+
+\\end{document}
+EOF
+}
+
+sub esc
+{
+       my $str = $_[ 0 ];
+
+       return "" if !defined $str || $str eq "";
+
+        # Trzeba zrobiæ sztuczkê by nie zamieniaæ w³asnych klamerek
+        # lub backslashy
+       $str =~ s/{/\\lbrace/g;
+       $str =~ s/}/\\rbrace/g;
+        $str =~ s/\\/\\ensuremath{\\backslash}/g;
+#      $str =~ s/{/\\{/g;
+#      $str =~ s/}/\\}/g;
+
+        $str =~ s/</\\ensuremath{<}/g;
+        $str =~ s/>/\\ensuremath{>}/g;
+       $str =~ s/#/\\#/g;
+       $str =~ s/%/\\%/g;
+       $str =~ s/&/\\&/g;
+       $str =~ s/\$/\\\$/g;
+       $str =~ s/_/\\_/g;
+        $str =~ s/~/\\ensuremath{\\sim}/g;
+#        $str =~ s/\^/{\\ensuremath{^}}/g;
+
+       return $str;
+}
+
+sub refName
+{
+       my ( $node ) = @_;
+       confess "refName called with undef" if !defined $node->{astNodeName};
+
+       my $ref = defined $_[1] ? $_[1] : 'Ref';
+
+       $ref = $node->{ $ref };
+
+       my $out;
+
+#      if ( !defined $ref ) {
+        $out =  esc($node->{astNodeName});
+#      } else {
+#              $out = '<A HREF="'.encodeURL($ref).'">'.
+#                      esc($node->{astNodeName}).'</A>';
+#      }
+
+       $out = "\\emph{".$out."}" if exists $node->{Pure};
+
+#        print "DIAG: refName zwraca $out\n";
+       return $out;
+
+}
+
+sub deref
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is null" if !defined $rootnode;
+
+       my $out = "";
+       my $text;
+
+       foreach $text ( split (/(\@ref\s+[\w:#]+)/, $str ) ) {
+               if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
+                        my $x = wordRef( $1, $rootnode );
+#                        print "DIAG: w derefie $1 -> $x\n";
+                       $out .= $x;
+               }
+               else {
+                       $out .= esc($text);
+               }
+       }
+       
+#        print "DIAG: deref dla\n$str\nzwraca\n$out\n" if $str ne $out;
+       return $out;
+}
+
+=head2 printDoc
+
+       Parameters: docnode, *filehandle, rootnode, compound
+
+       Print a doc node. If compound is specified and non-zero, various
+       compound node properties are not printed.
+
+=cut
+
+sub printDoc
+{
+        local ($docNode, *CLASS, $rootnode, $comp ) = @_;
+        my $node;
+        my $type;
+       my $text;
+       my $lasttype = "none";
+
+       $comp = defined $comp? $comp : 0;
+       
+       $text = $docNode->{Text};
+
+        if ( defined $text ) {
+                print CLASS "\n\n";
+
+                foreach $node ( @$text ) {
+                        $type = $node->{NodeType};
+                       $name = $node->{astNodeName};
+                        warn "Node '", $name, "' has no type"
+                               if !defined $type;
+
+                       if( $lasttype eq "ListItem" && $type ne $lasttype ) {
+                               print CLASS "\\end{itemize}\n";
+                       }
+
+                        if( $type eq "DocText" ) {
+                                print CLASS "", deref( $name, $rootnode );
+                        }
+                        elsif ( $type eq "Pre" ) {
+# ??? verbatim'ów nie escapeujê. Ale mo¿e w ogóle u¿yæ tu listings
+                                print CLASS "\n\\begin{verbatim}\n",
+                                      $name , "\n\\end{verbatim}\n";
+                        }
+                       elsif( $type eq "Ref" ) {
+                               my $ref = $node->{Ref};
+                               if ( defined $ref ) {
+                                       print "found reference for $name\n";
+                                       print CLASS refName( $ref );
+                               }
+                               else {
+                                       print CLASS $name;
+                               }
+                       }
+                        elsif ( $type eq "ParaBreak" ) {
+                                print CLASS "\n\n";
+                        }
+                       elsif ( $type eq "ListItem" ) {
+                               if ( $lasttype ne "ListItem" ) {
+                                       print CLASS "\n\\begin{itemize}\n";
+                               }
+                               print CLASS "\\item ", 
+                                       deref( $name, $rootnode ), "\n";
+                       }
+
+                       $lasttype = $type;
+                }
+
+               if( $type eq "ListItem" ) {
+                       print CLASS "\n\\end{itemize}\n";
+               }
+
+                print CLASS "\n\n";
+
+        }
+
+
+       # Params
+       my @paramlist = ();
+       kdocAstUtil::findNodes( \@paramlist, $docNode->{Text},
+                       "NodeType", "Param" );
+
+       if( $#paramlist >= 0 ) {
+               my $pnode;
+               print CLASS "\n\n\\textbf{Parametry}:\n\n",
+                       "\\begin{longtable}{lp{8cm}}\n";
+               
+               foreach $pnode ( @paramlist ) {
+                       print CLASS 
+                          "\\emph{", esc($pnode->{Name}), '} & ',
+                          deref($pnode->{astNodeName}, $rootnode ),
+                          "\\\\\n";
+               }
+               print CLASS "\\end{longtable}\n";
+       }
+
+       # Return
+       printTextItem( $docNode, CLASS, "Returns", "Wynik" );
+
+        my @exception_list = ();
+        kdocAstUtil::findNodes( \@exception_list, $docNode->{Text},
+                                "NodeType", "Throws" );
+        if( $#exception_list >= 0 ) {
+               my $pnode;
+               print CLASS "\n\n\\textbf{Wyj±tki}:\n",
+                       "\\begin{longtable}{lp{8cm}}\n";
+               
+               foreach $pnode ( @exception_list ) {
+                       print CLASS 
+                          "\\emph{", esc($pnode->{Name}), '} & ',
+                          deref($pnode->{astNodeName}, $rootnode ),
+                          "\\\\\n";
+               }
+               print CLASS "\\end{longtable}\n";
+        }
+
+       # See
+       $text = $docNode->{See};
+       my $tref = $docNode->{SeeRef};
+       
+       if ( defined $text ) {
+               my $comma = "\n\n\\textbf{Patrz te¿}: ";
+
+               foreach $ctr ( 0..$#{$text} ) {
+                       if ( defined $tref->[ $ctr ] ) {
+                               print CLASS $comma, refName( $tref->[ $ctr ] );
+                       }
+                       else {
+                               print CLASS $comma, esc( $text->[ $ctr ] );
+                       }
+
+                       $comma = ", ";
+               }
+               print CLASS "\n\n";
+       }
+
+       return if $comp;
+
+       printTextItem( $docNode, CLASS, "Since", "Od" );
+       printTextItem( $docNode, CLASS, "Version", "Wersja" );
+       printTextItem( $docNode, CLASS, "Id" );
+       printTextItem( $docNode, CLASS, "Author", "Autor" );
+}
+
+=head3 printTextItem
+
+       Parameters: node, *filehandle, prop, label
+
+       If prop is set, it prints the label and the prop value deref()ed.
+
+=cut
+
+sub printTextItem
+{
+       local ( $node, *CLASS, $prop, $label ) = @_;
+       my $text = $node->{ $prop };
+       
+       return unless defined $text;
+       $label = $prop unless defined $label;
+       
+#      print CLASS "\n\n\\textbf{", $label, "}: ", deref( $text, $rootnode  ), "\n\n";
+#      print CLASS "\n\n\\textbf{$label}:\n\n", deref( $text, $rootnode  ), "\n\n";
+        my $txt = deref($text, $rootnode);
+       print CLASS <<EOF
+
+\\textbf{$label}:
+
+\\begin{longtable}{lp{10cm}}
+ & $txt \\\\
+\\end{longtable}
+EOF
+}
+
+sub textRef
+{
+       my ( $str, $rootnode ) = @_;
+       my $word;
+       my $out = "";
+
+       foreach $word ( split( /([^\w:]+)/, $str ) ) {
+               if ( $word =~ /^[^\w:]/ ) {
+                       $out .= esc($word);
+               }
+               else {
+                       $out .= wordRef( $word, $rootnode );
+               }
+       }
+
+       return $out;
+}
+
+=head3 wordRef
+
+       Parameters: word
+
+       Prints a hyperlink to the word's' reference if found, otherwise
+       just prints the word. Good for @refs etc.
+
+=cut
+
+sub wordRef
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is undef" if !defined $rootnode;
+
+       return "" if $str eq "";
+
+        # MK --> chcê linkowaæ Ref'y i ConstRef'y
+#      my $ref = kdocAstUtil::findRef( $rootnode, $str );
+        my $str2 = $str;
+        $str2 =~ s/(Const)?Ref$//;
+        my $ref = kdocAstUtil::findRef( $rootnode, $str2 );
+
+# ??? Powy¿sze nigdy siê nie znajdzie bo jeszcze nie robiê referencji. A
+# hashe zostaj±...
+        $str =~ s/^\#//;
+
+       return esc($str) if !defined $ref;
+
+       return hyper( $ref->{Ref}, esc($str) );
+}
+
+sub hyper
+{
+       confess "hyper: undefed parameter $_[0], $_[1]"
+#              unless defined $_[0] && defined $_[1];
+               unless defined $_[1];
+#      return "<A HREF=\"$_[0]\">".esc($_[1])."</A>";
+        my $result = esc($_[1]);
+#        print "DIAG: hyper zwraca $result\n";
+       return $result;
+}
+
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocDocHelper.pm b/deal.II/contrib/kdoc/src/kdocDocHelper.pm
new file mode 100644 (file)
index 0000000..f549a9d
--- /dev/null
@@ -0,0 +1,78 @@
+package kdocDocHelper;
+
+use Carp;
+use Ast;
+use kdocAstUtil;
+use kdocUtil;
+
+use strict;
+use vars qw/ @undoc_class @undoc_func @no_short 
+       $lib $rootnode $outputdir $opt /;
+
+=head1 kdocDocCheck
+
+       Check source files for documentation statistics.
+
+       Undocumented globals
+
+=cut
+
+BEGIN {
+       @undoc_class = ();
+       @undoc_func = ();
+       @no_short = ();
+}
+
+sub writeDoc
+{
+       ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+       foreach my $node ( @{$rootnode->{Kids}} ) {
+               next if defined $node->{ExtSource} 
+                       || defined $node->{Forward}
+                       || $node->{NodeType} eq "Forward";
+
+               if ( !defined $node->{Compound} ) {
+                       push @undoc_func, $node 
+                               unless defined $node->{DocNode};
+
+                       next;
+               }
+
+               if ( !defined $node->{DocNode} ) {
+                       push @undoc_class, $node;
+               }
+               elsif ( !defined $node->{DocNode}->{ClassShort} ) {
+                       push @no_short, $node;
+               }
+       }
+
+       listOffenders( "Undocumented classes", \@undoc_class );
+       listOffenders( "No short description", \@no_short );
+       listOffenders( "Undocumented functions", \@undoc_func );
+}
+
+sub listOffenders
+{
+       my ( $reason, $list ) = @_;
+
+       return if $#{$list} < 0;
+
+       my $source = "";
+
+       print "$reason:\n";
+       foreach my $node ( 
+                       sort { $a->{Source} cmp $b->{Source} } @{$list} ) {
+
+               my $newsource = kdocAstUtil::nodeSource( $node );
+               if ( $source ne $newsource ) {
+                       print "\t", kdocAstUtil::nodeSource( $node ),":\n";
+                       $source = $newsource;
+               }
+                       
+               print "\t\t(", $node->{NodeType}, ") ", 
+                       $node->{astNodeName}, "\n";
+       }
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocHTMLutil.pm b/deal.II/contrib/kdoc/src/kdocHTMLutil.pm
new file mode 100644 (file)
index 0000000..76f6edc
--- /dev/null
@@ -0,0 +1,703 @@
+
+=head1 kdocHTMLutil - Common HTML routines.
+
+=cut
+
+package kdocHTMLutil;
+
+use kdocAstUtil;
+use Carp;
+use Iter;
+use strict;
+no strict qw/ subs/;
+use vars qw( $VERSION @ISA @EXPORT $rcount $docNode $rootnode $comp *CLASS );
+
+BEGIN {
+       $VERSION = '$Revision$';
+       @ISA = qw( Exporter );
+       @EXPORT = qw( makeReferences refName refNameFull refNameEvery hyper 
+                       esc printDoc printTextItem wordRef textRef deref 
+                       encodeURL newPgHeader tabRow makeHeader 
+                       HeaderPathToHTML writeTable makeSourceReferences B);
+
+       $rcount = 0;
+}
+
+## generic HTML generator routines
+
+sub newPgHeader
+{
+       my ( $html, $heading, $desc, $rest, $toclist ) = @_; 
+       my $bw=0;
+       my $cspan = defined $main::options{"html-logo"} ? 2 : 1;
+
+       print $html <<EOF;
+<HTML>
+<HEAD>
+<TITLE>$heading</TITLE>
+<META NAME="Generator" CONTENT="KDOC $main::version">
+</HEAD>
+<BODY bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#000099" alink= "#ffffff">
+<TABLE WIDTH="100%" BORDER="$bw">
+<TR>
+<TD>
+       <TABLE BORDER="$bw">
+               <TR><TD valign="top" align="left" cellspacing="10">
+               <h1>$heading</h1>
+               </TD>
+               <TD valign="top" align="right" colspan="1">$desc</TD></TR>
+       </TABLE>
+       <HR>
+       <TABLE BORDER="$bw">
+               $rest
+       </TABLE>
+       </TD>
+EOF
+
+#      print $html '<TABLE BORDER="',$bw,'"><TR><TD>';
+       my @klist = keys %$toclist;
+
+       print $html '<TD align="right"><TABLE BORDER="',$bw,'">';
+
+       # image
+       print $html '<TD rowspan="', ($#klist)+2,'"><IMG SRC="',
+                       $main::options{"html-logo"},'"></TD>'
+               if defined $main::options{"html-logo"};
+
+       # TOC
+
+       foreach my $item ( sort @klist ) {
+               print $html '<TR><TD>',
+               '<small><A HREF="',$toclist->{$item},'">',
+                       $item, "</small></TD></TR>\n";
+       }
+
+       print $html "</TABLE></TD></TR></TABLE>\n";
+       
+}
+
+sub writeTable
+{
+       my ( $file, $list, $columns ) = @_;
+
+       my ( $ctr, $size ) = ( 0, int(($#$list+1)/$columns) );
+       $size = 1 if $size < 1;
+
+# spread out unallocated items across columns.
+# The old behaviour was to dump them in the last column.
+       my $s = $size * $columns;
+       $size++ if $s < ($#$list+1);
+
+       print $file '<TABLE WIDTH="100%" BORDER="0"><TR>';
+
+       while ( $ctr <= $#$list ) {
+               print $file '<TD VALIGN="top">';
+               $s = $ctr+$size-1;
+
+               if ( $s > $#$list ) {
+                       $s = $#$list;
+               }
+               elsif ( ($#$list - $s) < $columns) {
+                       $s = $#$list;
+               }
+
+               writeListPart( $file, $list, $ctr, $s );
+               print $file "</TD>";
+               $ctr = $s+1;
+       }
+
+       print $file '</TR></TABLE>';
+}
+
+=head3
+
+       Parameters: fd, list, start index, end index
+
+       Helper for writeClassList.  Prints a table containing a
+       hyperlinked list of all nodes in the list from start index to
+       end index. A table header is also printed.
+
+=cut
+
+sub writeListPart
+{
+       my( $file, $list, $start, $stop ) = @_;
+
+       print $file "<TABLE BORDER=\"0\">";
+
+       print $file '<TR bgcolor="b0b0b0"><TH>', 
+               esc( $list->[ $start ]->{astNodeName} ),
+               " - ", esc( $list->[ $stop ]->{astNodeName} ), 
+               "</TH></TR>";
+
+       my $col = 0;
+       my $colour = "";
+       
+       for my $ctr ( $start..$stop ) {
+               $col = $col ? 0 : 1;
+               $colour = $col ? "" : 'bgcolor="#eeeeee"';
+
+               print $file "<TR $colour><TD>", refNameFull( $list->[ $ctr ] ),
+                       "</TD></TR>\n";
+       }
+
+       print $file "</TABLE>";
+}
+
+
+=head2 makeReferences
+
+       Parameters: rootnode
+
+       Recursively traverses the Kids of the root node, setting
+       the "Ref" property for each. This is the HTML reference for
+       the node. 
+
+       A "NumRef" property is also set for non-compound members,
+       which is used for on-page links.
+
+=cut
+
+sub makeReferences
+{
+       my ( $rootnode ) = @_;
+
+       $rootnode->AddProp( "rcount", 0 );
+
+       return Iter::Tree ( $rootnode, 1, 
+               sub {                                   # common
+                       my ( $root, $node ) = @_;
+
+                       $root->{rcount}++; 
+                       $node->AddProp( 'NumRef', "#ref".$root->{rcount} ); 
+
+                       return;
+               },
+               sub {                                   # compound
+                       my ( $root, $node ) = @_;
+                       return if defined $node->{ExtSource};
+
+                       my @heritage = kdocAstUtil::heritage( $node );
+                       
+                       foreach my $n ( @heritage ) { $n = encodeURL( $n );     }
+                       $node->AddProp( "Ref", join( "__", @heritage ). ".html" );
+
+                       $node->AddProp( "rcount", 0 );
+
+                       return;
+               },
+               sub {                                   # member
+                       my ( $root, $node ) = @_;
+                       $node->AddProp( 'Ref', $root->{Ref}.
+                                       "#".encodeURL($node->{astNodeName}) )
+                               unless defined $node->{ExtSource};
+
+                       return;
+               }
+       );
+}
+
+sub makeSourceReferences
+{
+       my( $rootnode ) = shift;
+
+       return if !exists $rootnode->{Sources};
+
+       # Set up references
+
+       foreach my $header ( @{$rootnode->{Sources}} ) {
+               my $htmlname = HeaderPathToHTML( $header->{astNodeName} );
+               $header->AddProp( "Ref", $htmlname );
+       }
+
+
+}
+
+
+=head2 refName
+
+       Parameters: node, refprop?
+
+       Returns a hyperlinked name of the node if a reference exists,
+       or just returns the name otherwise. Useful for printing node names.
+
+       If refprop is specified, it is used as the reference property
+       instead of 'Ref'.
+
+=cut
+
+sub refName
+{
+       my ( $node ) = @_;
+       confess "refName called with undef" unless defined $node->{astNodeName};
+
+       my $ref = defined $_[1] ? $_[1] : 'Ref';
+
+       $ref = $node->{ $ref };
+
+       my $out;
+
+       if ( !defined $ref ) {
+               $out =  $node->{astNodeName};
+       } else {
+               $out = hyper( encodeURL($ref), $node->{astNodeName} );
+       }
+
+       $out = "<i>".$out."</i>" if exists $node->{Pure};
+
+       return $out;
+
+}
+
+=head2 refNameFull
+
+       Parameters: node, rootnode, refprop?
+
+       Returns a hyperlinked, fully qualified (ie including parents)
+       name of the node if a reference exists, or just returns the name
+       otherwise. Useful for printing node names.
+
+       If refprop is specified, it is used as the reference property
+       instead of 'Ref'.
+
+=cut
+
+sub refNameFull
+{
+       my ( $node, $rootnode, $refprop ) = @_;
+
+       my $ref = defined $refprop ? $refprop : 'Ref';
+       $ref = $node->{ $ref };
+       my $name = join( "::", kdocAstUtil::heritage( $node ) );
+
+       my $out;
+
+       if ( !defined $ref ) {
+               $out =  esc($name);
+       } else {
+               $out = hyper( encodeURL( $ref ), $name );
+       }
+
+       $out = "<i>".$out."</i>" if exists $node->{Pure};
+
+       return $out;
+}
+
+
+=head2 refNameEvery
+
+       Parameters: node
+
+       Like refNameFull, but every separate link in the chain is
+       referenced.
+
+=cut
+
+sub refNameEvery
+{
+       my ( $node, $rootnode ) = @_;
+
+
+
+       # make full name
+       my $name = $node->{astNodeName};
+
+       my $parent = $node->{Parent};
+
+       while ( $parent != $rootnode ) {
+               $name = refName($parent)."::".$name;
+               $parent = $parent->{Parent};
+       }
+
+       return $name;
+}
+
+=head2 hyper
+
+       Parameters: hyperlink, text
+
+       Returns an HTML hyperlink. The text is escaped.
+
+=cut
+
+sub hyper
+{
+       confess "hyper: undefed parameter $_[0], $_[1]"
+               unless defined $_[0] && defined $_[1];
+       return "<A HREF=\"$_[0]\">".esc($_[1])."</A>";
+}
+
+
+sub B
+{
+               my $tag = shift;
+
+               return "<$tag>". join( "", @_). "</$tag>";
+}
+
+=head2 esc
+
+       Escape special HTML characters.
+
+=cut
+
+sub esc
+{
+       my $str = $_[ 0 ];
+
+       return "" if !defined $str || $str eq "";
+
+       $str =~ s/&/&amp;/g;
+       $str =~ s/</&lt;/g;
+       $str =~ s/>/&gt;/g;
+
+       return $str;
+}
+
+
+=head2 printDoc
+
+       Parameters: docnode, *filehandle, rootnode, compound
+
+       Print a doc node. If compound is specified and non-zero, various
+       compound node properties are not printed.
+
+=cut
+
+sub printDoc
+{
+       my $docNode = shift;
+       local ( *CLASS, $rootnode ) = @_;
+        my ( $comp ) = @_;
+
+        my $type;
+       my $lasttype = "none";
+
+       $comp = defined $comp? $comp : 0;
+
+       if ( defined $docNode->{Main} ) {
+               print CLASS "<H2>", 
+                       deref( $docNode->{Main}, $rootnode ), "</H2>\n";
+       }
+       
+       my $text = $docNode->{Text};
+
+        if ( defined $text ) {
+                print CLASS "<p>";
+
+                foreach my $node ( @$text ) {
+                        $type = $node->{NodeType};
+                       my $name = $node->{astNodeName};
+                        warn "Node '", $name, "' has no type"
+                               if !defined $type;
+
+                       if( $lasttype eq "ListItem" && $type ne $lasttype ) {
+                               print CLASS "</ul><p>\n";
+                       }
+
+                        if( $type eq "DocText" ) {
+                                print CLASS "", deref( $name, $rootnode );
+                        }
+                        elsif ( $type eq "Pre" ) {
+                                print CLASS "</p><pre>\n",
+                                       esc( $name ), "\n</pre><p>";
+                        }
+                       elsif( $type eq "Ref" ) {
+                               my $ref = $node->{Ref};
+                               if ( defined $ref ) {
+                                       print "found reference for $name\n";
+                                       print CLASS refName( $ref );
+                               }
+                               else {
+                                       print CLASS $name;
+                               }
+                       }
+                       elsif ( $type eq "DocSection" ) {
+                               print CLASS "</p><H3>",
+                                       deref( $name, $rootnode),"</H3><p>";
+                       }
+                       elsif ( $type eq "Image" ) {
+                               print CLASS "</p><img url=\"",
+                                       $node->{Path}, "\"><p>";                
+                       }
+                        elsif ( $type eq "ParaBreak" ) {
+                                print CLASS "</p><p>";
+                        }
+                       elsif ( $type eq "ListItem" ) {
+                               if ( $lasttype ne "ListItem" ) {
+                                       print CLASS "</p><ul>\n";
+                               }
+                               print CLASS "<li>", 
+                                       deref( $name, $rootnode ), "</li>\n";
+                       }
+
+                       $lasttype = $type;
+                }
+
+               if( $type eq "ListItem" ) {
+                       print CLASS "</ul><p>\n";
+               }
+
+                print CLASS "</p>";
+
+        }
+
+
+       # Params
+       my @paramlist = ();
+       kdocAstUtil::findNodes( \@paramlist, $docNode->{Text},
+                       "NodeType", "Param" );
+
+       if( $#paramlist >= 0 ) {
+               my $pnode;
+               print CLASS "<p><b>Parameters</b>:",
+                       "<TABLE BORDER=\"0\" CELLPADDING=\"5\">\n";
+               
+               foreach $pnode ( @paramlist ) {
+                       print CLASS "<TR><TD align=\"left\" valign=\"top\"><i>",
+                               esc($pnode->{Name}),
+                               "</i></TD><TD align=\"left\" valign=\"top\">",
+                               deref($pnode->{astNodeName}, $rootnode ),
+                               "</TD></TR>\n";
+               }
+               print CLASS "</TABLE></P>\n";
+       }
+
+       # Return
+       printTextItem( $docNode, *CLASS, "Returns" );
+
+       # Exceptions
+       $text = $docNode->{Throws};
+
+       if ( defined $text ) {
+               my $comma = "<p><b>Throws</b>: ";
+
+               foreach my $tosee ( @$text ) {
+                       print CLASS $comma, esc( $tosee );
+                       $comma = ", ";
+               }
+               print CLASS "</p>\n";
+       }
+
+       # See
+       my $comma = "";
+       
+       Iter::SeeAlso ( $docNode, undef,
+               sub { # start
+                       print CLASS "<p><b>See also</b>: ";
+               },
+               sub { # print
+                       my ( $label, $ref ) = @_;
+                       $label = defined $ref ? refName( $ref ): esc( $label );
+
+                       print CLASS $comma, $label;
+                       $comma = ", ";
+               },
+               sub { # end
+                       print CLASS "</p>\n";
+               }
+       );
+       
+       return if $comp;
+
+       printTextItem( $docNode, *CLASS, "Since" );
+       printTextItem( $docNode, *CLASS, "Version" );
+       printTextItem( $docNode, *CLASS, "Id" );
+       printTextItem( $docNode, *CLASS, "Author" );
+}
+
+=head3 printTextItem
+
+       Parameters: node, *filehandle, prop, label
+
+       If prop is set, it prints the label and the prop value deref()ed.
+
+=cut
+
+sub printTextItem
+{
+       my $node = shift;
+       local *CLASS = shift;
+       my ( $prop, $label ) = @_;
+
+       my $text = $node->{ $prop };
+       
+       return unless defined $text;
+       $label = $prop unless defined $label;
+       
+       print CLASS "<p><b>", $label, "</b>: ", 
+                       deref( $text, $rootnode  ), "</p>\n";
+}
+
+
+=head3 wordRef
+
+       Parameters: word
+
+       Prints a hyperlink to the word's reference if found, otherwise
+       just prints the word. Good for @refs etc.
+
+=cut
+
+sub wordRef
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is undef" if !defined $rootnode;
+
+       return "" if $str eq "";
+
+       my $ref = kdocAstUtil::findRef( $rootnode, $str );
+
+       return esc($str) if !defined $ref;
+
+       warn fullName( $ref ). " hasn't a reference." unless defined $ref->{Ref};
+
+       return hyper( $ref->{Ref}, $str ) unless !defined $ref->{Ref};
+}
+
+=head2 textRef
+
+       Parameters: string
+       Returns: hyperlinked, escaped text.
+
+       Tries to find a reference for EVERY WORD in the string, replacing it
+       with a hyperlink where possible. All non-hyper text is escaped.
+
+       Needless to say, this is quite SLOW.
+
+=cut
+
+sub textRef
+{
+       my ( $str, $rootnode ) = @_;
+       my $word;
+       my $out = "";
+       
+       foreach $word ( split( /([^\w:]+)/, $str ) ) {
+               if ( $word =~ /^[^\w:]/ ) {
+                       $out .= esc($word);
+               }
+               else {
+                       $out .= wordRef( $word, $rootnode );
+               }
+       }
+
+       return $out;
+}
+
+=head2 deref
+
+       Parameters: text
+       returns text
+
+       dereferences all @refs in the text and returns it.
+
+=cut
+
+sub deref
+{
+       my ( $str, $rootnode ) = @_;
+       confess "rootnode is null" if !defined $rootnode;
+       my $out = "";
+       my $text;
+
+       foreach $text ( split (/(\@\w+\s+[\w:#]+)/, $str ) ) {
+               if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
+                       my $name = $1;
+                       $name =~ s/^\s*#//g;
+                       $out .= wordRef( $name, $rootnode );
+               }
+               elsif ( $text =~ /\@p\s+([\w:#]+)/ ) {
+                       $out .= "<code>".esc($1)."</code>";
+               }
+               elsif ( $text =~/\@em\s+(\w+)/ ) {       # emphasized
+                       $out .= "<em>".esc($1)."</em>";
+               }
+               else {
+                       $out .= esc($text);
+               }
+       }
+
+       return $out;
+}
+
+=head2 encodeURL
+
+       Parameters: url
+
+       Returns: encoded URL
+
+=cut
+
+sub encodeURL
+{
+       my $url = shift;
+       $url =~ s/:/%3A/g;
+       $url =~ s/</%3C/g;
+       $url =~ s/>/%3E/g;
+       $url =~ s/ /%20/g;
+       $url =~ s/%/%25/g;
+
+       return $url;
+}
+
+=head2 tabRow
+
+       Returns a table row with each element in the arg list as
+       one cell.
+       
+=cut
+
+sub tabRow
+{
+       return "<TR><TH>$_[0]</TH><TD>$_[1]</TD></TR>\n";
+}
+
+=head2 makeHeader
+
+       Writes an HTML version of a file.
+
+=cut
+
+sub makeHeader
+{
+       my ( $out, $filename ) = @_;
+
+       open ( SOURCE, "$filename" ) || die "Couldn't read $filename\n";
+
+       print $out "<pre>\n";
+
+       while ( <SOURCE> ) {
+               print $out esc( $_ );
+       }
+
+       print $out "</pre>\n";
+}
+
+=head2 HeaderPathToHTML
+
+       Takes the path to a header file and returns an html file name.
+
+=cut
+
+sub HeaderPathToHTML
+{
+       my ( $path ) = @_;
+
+       $path =~ s/_/__/g;
+       $path =~ s/\//___/g;
+       $path =~ s/\./_/g;
+       $path =~ s/:/____/g;
+
+       return $path.".html";
+}
+
+# for printing debug node.
+
+sub fullName
+{
+               return join( "::", kdocAstUtil::heritage( shift ) );
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocIDLhtml.pm b/deal.II/contrib/kdoc/src/kdocIDLhtml.pm
new file mode 100644 (file)
index 0000000..a7b73f2
--- /dev/null
@@ -0,0 +1,745 @@
+package kdocIDLhtml;
+
+use File::Path;
+use File::Basename;
+
+use Carp;
+use Ast;
+use kdocAstUtil;
+use kdocHTMLutil;
+
+=head1 kdocIDLhtml
+
+Generate HTML docs for an IDL syntax tree.
+
+=cut
+
+BEGIN
+{
+       @clist = ();
+
+       # Host information
+
+       if ( $^O eq "MsWin32" ) {
+               # Windows
+               $host=$ENV{COMPUTERNAME};
+               $who = $ENV{USERNAME};  
+       }
+       else {
+               # Unix
+               $host = `uname -n`;     chop $host;
+               $who = `whoami`;        chop $who;
+       }
+
+       $now = localtime;
+       $gentext = "$who\@$host on $now, using kdoc $main::Version.";
+
+       # bottom of every page
+       $docBotty =<<EOF;
+<HR>
+       <table>
+       <tr><td><small>Generated by: $gentext</small></td></tr>
+       </table>
+</BODY>
+</HTML>
+EOF
+
+       # used to convert node types to headings
+
+       %typedesc = (   
+                       'enum'  => 'Enumerations',
+                       'exception' => 'Exceptions',
+                       'interface' => 'Interfaces',
+                       'method' => 'Methods',
+                       'struct' => 'Structures',
+                       'typedef' => 'Types',
+                       'var' => 'Constants'
+       );
+}
+
+sub writeDoc
+{
+       ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+       $debug = $main::debug;
+       @docQueue = ();
+
+       print "Generating HTML documentation. \n" unless $main::quiet;
+
+       mkpath( $outputdir ) unless -f $outputdir;
+
+       makeReferences( $rootnode );
+       makeModuleList( $rootnode );
+
+       writeModList( $rootnode );
+       writeAnnotatedList( $rootnode );
+       writeHeaderList();
+
+       my $node;
+
+       foreach $node ( @{$rootnode->{Kids}} ) {
+               next if !defined $node->{Compound} 
+                       || defined $node->{ExtSource};
+               print "list: Queueing $node->{astNodeName} for doc\n"
+                       if $debug;
+               push @docQueue, $node;
+       }
+
+       while( $#docQueue >= 0 ) {
+               $node = pop @docQueue;
+               print "Dequeueing $node->{astNodeName} for doc\n"
+                       if $debug;
+               writeCompoundDoc( $node );
+       }
+}
+
+=head2 writeAnnotatedList
+
+       Parameters: rootnode
+
+       Writes out a list of classes with short descriptions to
+       index-long.html.
+
+=cut
+
+sub writeAnnotatedList
+{
+       my ( $root ) = @_;
+       my $short;
+
+       open(CLIST, ">$outputdir/index-long.html") 
+               || die "Couldn't create $outputdir/index-long.html: $?\n";
+
+       print CLIST pageHeader( $lib." Annotated List" ),
+               "<TABLE WIDTH=\"100%\" BORDER=\"0\">\n";
+
+       foreach my $node ( @clist ) {
+               confess "undef in clist\n" if !defined $node;
+
+               $docnode = $node->{DocNode};
+               $short = "";
+
+               if( defined $docnode && exists $docnode->{ClassShort} ) {
+                       $short = deref($docnode->{ClassShort}, $rootnode );
+                       if( !defined $short ) {
+                               print $root->{astNodeName}, "has undef short\n";
+                               next;
+                       }
+                               
+               }
+
+               print CLIST "<TR><TD>", refName( $node ), 
+                       "</TD><TD>", $short, "</TD></TR>";
+       }
+
+       print CLIST "</TABLE>", $docBotty;
+       close CLIST;
+}
+
+=head2 writeModList
+
+       Parameters: rootnode
+
+       Writes out a concise list of classes to index.html
+
+=cut
+
+sub writeModList
+{
+       my ( $root ) = @_;
+
+       open(CLIST, ">$outputdir/index.html") 
+               || die "Couldn't create $outputdir/index.html: $?\n";
+
+       print CLIST pageHeader( $lib." Module Index" ),
+               "<TABLE WIDTH=\"100%\" BORDER=\"0\">\n";
+
+       my $cols = exists $opt->{"html-cols"} ? $opt->{"html-cols"} : 3;
+       my ( $ctr, $size ) = ( 0, int(($#clist+1)/$cols) );
+       $size = 1 if $size < 1;
+
+       print CLIST "<TR>";
+       my $s;
+
+       while ( $ctr <= $#clist ) {
+               print CLIST "<TD>";
+               $s = $ctr+$size-1;
+
+               if ( $s > $#clist ) {
+                       $s = $#clist;
+               }
+               elsif ( ($#clist - $s) < $cols) {
+                       $s = $#clist;
+               }
+
+               print "Writing from $ctr to ",$ctr+$size-1,"\n" if $debug;
+               writeListPart( \@clist, $ctr, $s );
+               print CLIST "</TD>";
+               $ctr = $s+1;
+       }
+
+       print CLIST<<EOF;
+</TR>
+</TABLE>
+$docBotty
+EOF
+       close CLIST;
+}
+
+=head3
+
+       Parameters: list, start index, end index
+
+       Helper for writeModList.  Prints a table containing a hyperlinked
+       list of all nodes in the list from start index to end index. A
+       table header is also printed.
+
+=cut
+
+sub writeListPart
+{
+       my( $list, $start, $stop ) = @_;
+
+       print CLIST "<TABLE BORDER=\"0\">";
+
+       print CLIST "<TR><TH>", 
+               esc( $list->[ $start ]->{astNodeName} ),
+               " - ", esc( $list->[ $stop ]->{astNodeName} ), 
+               "</TH></TR>";
+
+       for $ctr ( $start..$stop ) {
+               print CLIST "<TR><TD>", refName( $list->[ $ctr ] ),
+                       "</TD></TR>\n";
+       }
+
+       print CLIST "</TABLE>";
+}
+
+
+=head2 writeAllMembers
+
+       Parameters: node
+
+       Writes a list of all methods to "full-list-<class file>"
+
+=cut
+
+sub writeAllMembers
+{
+       my( $node ) = @_;
+       my $file = "$outputdir/full-list-".$node->{Ref};
+       my %allmem = ();
+
+       kdocAstUtil::allMembers( \%allmem, $node );
+
+       open( ALLMEM, ">$file" ) || die "Couldn't create $file: $?\n";
+
+       print ALLMEM pageHeader( esc($node->{astNodeName})." - All Methods" ),
+               "<UL>";
+
+       my $mem;
+       foreach $mem ( sort keys %allmem ) {
+               print ALLMEM "<LI>", refName( $allmem{ $mem } ), "</LI>\n";
+       }
+
+       print ALLMEM "</UL>$docBotty";
+
+       close ALLMEM;
+}
+
+=head2 writeHeaderList
+
+       Generates the header-list.html file, which contains links
+       to each processed header. The ARGV list is used.
+
+=cut
+
+sub writeHeaderList
+{
+       open(HDRIDX, ">$outputdir/header-list.html") 
+               || die "Couldn't create $outputdir/header-list.html: $?\n";
+
+       print HDRIDX pageHeader( $lib." File Index" ), "<UL>\n";
+
+       foreach $header ( sort @main::ARGV ) {
+               $_ = $header;
+               $header = basename ( $_ ) if $main::striphpath;
+# convert dashes to double dash, convert path to dash
+               s/-/--g/g;
+               s/\/|\./-/g;
+
+               print HDRIDX  "\t<LI>",hyper($_.".html",$header),"</LI>\n";
+       }
+       
+print HDRIDX "</UL>\n",$docBotty;
+
+}
+
+=head2 pageHeader
+
+       Parameters: heading, description
+
+       Returns a string containing an HTML page heading.
+
+=cut
+
+sub pageHeader
+{
+       my( $heading, $desc ) = @_;
+
+       $desc = "" if !defined $desc;
+
+       my $libtext = "";
+       if( $lib ne "" ) {
+               $libtext = "<TR><TD><small>$lib documentation</small>".
+                       "</TD></TR>";
+       }
+
+       return <<EOF;
+<HTML><HEAD>
+<TITLE>$heading</TITLE>
+<META NAME="Generator" CONTENT="KDOC $main::Version">
+</HEAD>
+<BODY bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#000099" alink= "#ffffff">
+<TABLE WIDTH="100%" BORDER="0">
+<TD VALIGN="top" align="left">
+<TABLE BORDER="0"><TR>
+$libtext
+<TR><TD><small><A HREF="index.html">Index</small></TD></TR>
+<TR><TD><small><A HREF="index-long.html">Annotated List</small></TD></TR>
+<TR><TD><small><A HREF="header-list.html">Files</A></small></TD></TR>
+</TABLE>
+</TD>
+
+<TD VALIGN="top" align="right"><H1>$heading</H1><p>$desc</p></TD>
+</TR></TABLE>
+<HR>
+EOF
+       
+}
+
+=head2 writeCompoundDoc
+
+       Parameters: $node
+
+       Write documentation for one compound node.
+
+=cut
+
+sub writeCompoundDoc
+{
+       my( $node ) = @_;
+       if( exists $node->{ExtSource} ) {
+               warn "Trying to write doc for ".$node->{AstNodeName}.
+                       " from ".$node->{ExtSource}."\n";
+               return;
+       }
+
+       my $file = "$outputdir/".$node->{Ref};
+       my $docnode = $node->{DocNode};
+       my $hasdoc = exists $node->{DocNode} ? 1 : 0;
+       my @list = ();
+       my $version = undef;
+       my $author = undef;
+
+       open( CLASS, ">$file" ) || die "Couldn't create $file: $?\n";
+
+       # Header
+        
+       my $source = kdocAstUtil::nodeSource( $node );
+       my $short = "";
+
+       if( $hasdoc ) {
+               if ( exists $docnode->{ClassShort} ) {
+                       $short .= deref($docnode->{ClassShort}, $rootnode );
+               }
+
+               if ( exists $docnode->{Deprecated} ) {
+                       $short .= "</p><p><b>Deprecated: use with care</b>";
+               }
+
+               if ( exists $docnode->{Internal} ) {
+                       $short .= "</p><p><b>Internal use only</b>";
+               }
+               $version = esc($docnode->{Version}) 
+                               if exists $docnode->{Version};
+               $author = esc($docnode->{Author}) 
+                               if exists $docnode->{Author};
+       }
+
+       # check for pure abstract
+       if ( exists $node->{Pure} ) {
+               $short .= 
+                       "</p><p><b>Contains pure virtuals</b></p><p>";
+       }
+
+       # full name
+       $short .= "</p><p><code>".refNameEvery( $node, $rootnode )."</code><p>"
+                       unless $node->{Parent} eq $rootnode;
+
+       # include
+       $short .= "</p><p><code>#include &lt;".$source
+                       ."&gt;</code></p><p>";
+
+       # inheritance
+       if ( $node != $rootnode && exists $node->{InList} ) {
+               my $comma = "Inherits: ";
+
+               # FIXME: bad hack to get rid of duplicates.
+               my $last = undef;
+               my $out = "";
+
+               foreach my $in ( sort{ $a->{astNodeName} cmp $b->{astNodeName}}
+                               @{$node->{InList}} ) {
+                       next if $in == $last;
+
+                       my $n = $in->{Node};
+                       if( defined $n ) {
+                               next if $n eq $rootnode;
+                               $out .= $comma.refNameFull( $n, $rootnode );
+                               if ( exists $n->{ExtSource} ) {
+                                       $out .= " <small>(".$n->{ExtSource}
+                                       .")</small>";
+                               }
+                       }
+                       else {
+                               $out .= esc( $in->{astNodeName} );
+                       }
+                       
+                       $comma = ", ";
+                       $last = $in;
+               }
+
+               $short .= "$out</p><p>" unless $out eq "";
+       }
+
+       if ( $node != $rootnode && exists $node->{InBy} ) {
+               my $comma .= "Inherited by: ";
+
+               @list = ();
+               kdocAstUtil::inheritedBy( \@list, $node );
+
+               # FIXME: bad hack to get rid of duplicates.
+               my $last = 1;
+
+               foreach $in ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+                               @list ) {
+                       $short .= $comma.refNameFull( $in, $rootnode );
+                       if ( exists $in->{ExtSource} ) {
+                               $short .= " <small>(".
+                               $in->{ExtSource}.")</small>";
+                       }
+       
+                       $comma = ", ";
+               }
+               $short .= "</p><p>";
+       }
+
+       $short .= "<small>".hyper( "#longdesc", "More..." )."</small>";
+
+       # print it
+
+       print CLASS pageHeader( 
+               $node->{NodeType}." ".esc($node->{astNodeName}), 
+               $short );
+
+
+       # member list
+       
+       print CLASS "<p>", hyper( encodeURL("full-list-".$node->{Ref}),
+               "List of all Methods" ),"</p>\n";
+
+       if ( exists $node->{Kids} ) {
+               foreach my $type ( kdocAstUtil::allTypes( $node->{Kids} ) ) {
+                       @list = ();
+                       kdocAstUtil::findNodes( \@list, $node->{Kids}, 
+                                       "NodeType", $type );
+
+                       listMembers( $node, exists $typedesc{$type}
+                               ? $typedesc{$type} : $type, \@list );
+               }
+
+       }
+       else {
+               print CLASS "<center><H4>No members</H4></center>\n";
+               return;
+       }
+
+       # long description
+       if ( $hasdoc ) {
+               print CLASS "<HR><A NAME=\"longdesc\">",
+                       "<H2>Detailed Description</H2>";
+               printDoc( $docnode, *CLASS, $rootnode, 1 );
+       }
+
+       # member doc
+       my $kid;
+       my ($numref, $ref);
+
+       foreach $kid ( @{$node->{Kids}} ) {
+                       next if defined $kid->{ExtSource} 
+                       || (!$main::doPrivate && 
+                               $kid->{Access} =~ /private/);
+
+               if( exists $kid->{Compound} ) {
+                       print "idl: Queueing $kid->{astNodeName} for doc\n"
+                               if $debug;
+                       push @docQueue, $kid;
+               }
+
+               # we check this after checking if the node is compound,
+               # so it is queued for c.doc even if it doesn't have explicit
+               # documentation.
+               next if !defined $kid->{DocNode};
+
+               if( !exists $kid->{NumRef} ) {
+                       warn $kid->{astNodeName}, " type ",
+                       $kid->{NodeType}, " doesn't have a numref\n";
+               }
+
+               ( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
+               ( $ref = $kid->{Ref} ) =~ s/^.*?#//g;
+
+               printMemberName( $kid, $ref, $numref );
+               printDoc( $kid->{DocNode}, *CLASS, $rootnode );
+
+               if ( $kid->{NodeType} eq "method" ) {
+                       $ref = kdocAstUtil::findOverride( $rootnode, $node, 
+                               $kid->{astNodeName} );
+                       if ( defined $ref ) {
+                               print CLASS "<p>Reimplemented from ",
+                                       refNameFull( $ref, $rootnode ), "</p>\n";
+                       }
+               }
+       }
+
+       # done
+
+       if ( defined $version || defined $author ) {
+               print CLASS "<HR><UL>",
+                       defined $version ? 
+                               "<LI><i>Version</i>: $version</LI>" : "",
+                       defined $author ? 
+                               "<LI><i>Author</i>: $author</LI>" : "",
+                       "<LI><i>Generated</i>: $gentext</LI></UL>",
+                       "</BODY></HTML>\n";
+       }
+       else {
+               print CLASS $docBotty;
+       }
+
+       close CLASS;
+
+       # full member list
+
+       writeAllMembers( $node );
+}
+
+
+
+
+=head2 listMembers
+
+       Parameters: compound node, description, node list ref?
+
+=cut
+
+sub listMembers
+{
+       my( $class, $desc, $nodelist ) = @_;
+       my $name;
+       my $type;
+       my $flags;
+       
+
+       my $nodes = defined $nodelist ? $nodelist : $class->{Kids};
+
+       if (  $#{$nodes} < 0 ) {
+               print CLASS "<center><H4>No members</H4></center>\n";
+               return;
+       }
+
+print CLASS<<EOF;
+<H2>$desc</H2>
+<UL>
+EOF
+       foreach $m ( @{$nodes} ) {
+               next if exists $m->{ExtSource};
+               if( exists $m->{Compound} ) {
+                       # compound docs not printed for rootnode
+                       next if $class eq $rootnode; 
+
+                       $name = refName( $m );
+               }
+               elsif( exists $m->{DocNode} ) {
+                       # compound nodes have their own page
+                       $name = refName( $m,  'NumRef' );
+               } else {
+                       $name = esc( $m->{astNodeName} );
+               }
+
+               $type = $m->{NodeType};
+
+               print CLASS "<LI>";
+
+               if( $type eq "var" ) {
+                       print CLASS esc( $m->{Type}), 
+                               " <b>", $name,"</b>\n";
+               }
+               elsif( $type eq "method" ) {
+                       $flags = $m->{Flags};
+
+                       if ( !defined $flags ) {
+                               warn "Method ".$m->{astNodeName}.
+                                       " has no flags\n";
+                       }
+
+                       $name = "<i>$name</i>" if $flags =~ /p/;
+                       my $extra = "";
+                       $extra .= "virtual " if $flags =~ "v";
+                       $extra .= "static " if $flags =~ "s";
+
+                       print CLASS $extra, esc($m->{ReturnType}),
+                               " <b>", $name, "</b> (", 
+                               esc($m->{Params}), ") ", 
+                               $flags =~ /c/ ? " const\n": "\n";
+               }
+               elsif( $type eq "enum" ) {
+                       print CLASS "enum <b>", $name, "</b> {",
+                               esc($m->{Params}),"}\n";
+               }
+               elsif( $type eq "typedef" ) {
+                       print CLASS "typedef ", 
+                               esc($m->{Type}), " <b>",
+                               $name,"</b>";
+               }
+               else { 
+                       # unknown type
+                       print CLASS esc($type), " <b>",
+                               $name,"</b>\n";
+               }
+
+               print CLASS "</LI>\n";
+       }
+
+print CLASS<<EOF;
+</UL>
+EOF
+
+}
+
+=head2 printMemberName
+
+       Parameters: member node, names...
+
+       Prints the name of one member, customized to type. If names are
+       specified, a name anchor is written for each one.
+
+=cut
+
+sub printMemberName
+{
+       my $m = shift;
+
+       my $name = esc( $m->{astNodeName} );
+       my $type = $m->{NodeType};
+       my $ref;
+       my $flags = undef;
+
+       foreach $ref ( @_ ) {
+               print CLASS "<A NAME=", $ref, "></A>";
+       }
+
+       print CLASS "<HR><p><strong>";
+
+       if( $type eq "var" ) {
+               print CLASS textRef($m->{Type}, $rootnode ), 
+               " <b>", $name,"</b>\n";
+       }
+       elsif( $type eq "method" ) {
+               $flags = $m->{Flags};
+               $name = "<i>$name</i>" if $flags =~ /p/;
+
+               print CLASS textRef($m->{ReturnType}, $rootnode ),
+               " <b>", $name, "</b> (", 
+               textRef($m->{Params}, $rootnode ), ")\n";
+       }
+       elsif( $type eq "enum" ) {
+               print CLASS "enum <b>", $name, "</b> {",
+               esc($m->{Params}),"}\n";
+       }
+       elsif( $type eq "typedef" ) {
+               print CLASS "typedef ", 
+               textRef($m->{Type}, $rootnode ), " <b>",
+               $name,"</b>";
+       }
+       else {
+               print CLASS $name, " <small>(", 
+                       esc($type), ")</small>";
+       }
+
+       print CLASS "</strong>";
+
+# extra attributes
+       my @extra = ();
+
+       if( !exists $m->{Access} ) {
+               print "Member without access:\n";
+               kdocAstUtil::dumpAst( $m );
+       }
+
+       ($ref = $m->{Access}) =~ s/_slots//g;
+
+       push @extra, $ref
+               unless $ref =~ /public/
+               || $ref =~ /signal/;
+
+       if ( defined $flags ) {
+               my $f;
+               my $n;
+               foreach $f ( split( "", $flags ) ) {
+                       $n = $main::flagnames{ $f };
+                       warn "flag $f has no long name.\n" if !defined $n;
+                       push @extra, $n;
+               }
+       }
+
+       if ( $#extra >= 0 ) {
+               print CLASS " <small>[", join( " ", @extra ), "]</small>";
+       }
+
+       print CLASS "</p>";
+       
+# finis
+}
+
+
+
+=head2 makeModuleList
+
+       Parameters: node
+
+       fills global @clist with a list of all direct, non-external
+       compound children of node.
+
+=cut
+
+sub makeModuleList
+{
+       my ( $rootnode ) = @_;
+
+       @clist = ();
+
+       foreach my $node ( @{$rootnode->{Kids}} ) {
+               confess "undefined child in rootnode" unless defined $node;
+
+               push @clist, $node unless (exists $node->{ExtSource}
+                               || !exists $node->{Compound});
+
+       }
+
+       @clist = sort { $a->{astNodeName} cmp $b->{astNodeName}  }
+                       @clist;
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocLib.pm b/deal.II/contrib/kdoc/src/kdocLib.pm
new file mode 100644 (file)
index 0000000..d1a09c2
--- /dev/null
@@ -0,0 +1,301 @@
+
+=head1 kdocLib
+
+Writes out a library file.
+
+NOTES ON THE NEW FORMAT
+
+       Stores: class name, members, hierarchy
+       node types are not stored
+
+
+       File Format Spec
+       ----------------
+
+       header
+       zero or more members, each of
+               method
+               member
+               class, each of
+                       inheritance
+                       zero or more members
+
+
+
+       Unrecognized lines  ignored.
+
+       Sample
+       ------
+
+       <! KDOC Library HTML Reference File>
+       <VERSION="2.0">
+       <BASE URL="http://www.kde.org/API/kdecore/">
+
+       <C NAME="KApplication" REF="KApplication.html">
+               <IN NAME="QObject">
+               <ME NAME="getConfig" REF="KApplication.html#getConfig">
+               <M NAME="" REF="">
+       </C>
+
+=cut
+
+package kdocLib;
+use strict;
+
+use Carp;
+use File::Path;
+use File::Basename;
+
+use Ast;
+use kdocAstUtil;
+use kdocUtil;
+
+
+use vars qw/ $exe $lib $root $plang $outputdir $docpath $url $compress /;
+
+BEGIN {
+       $exe = basename $0;
+}
+
+sub writeDoc
+{
+       ( $lib, $root, $plang, $outputdir, $docpath, $url, 
+               $compress ) = @_;
+       my $outfile = "$outputdir/$lib.kdoc";
+       $url = $docpath unless defined $url;
+
+       mkpath( $outputdir ) unless -f $outputdir;
+
+       if( $compress ) {
+               open( LIB, "| gzip -9 > \"$outfile.gz\"" ) 
+                       || die "$exe: couldn't write to $outfile.gz\n";
+
+       }
+       else {
+               open( LIB, ">$outfile" ) 
+                       || die "$exe: couldn't write to $outfile\n";
+       }
+
+       my $libdesc = "";
+       if ( defined $root->{LibDoc} ) {
+                       $libdesc="<LIBDESC>".$root->{LibDoc}->{astNodeName}."</LIBDESC>";
+       }
+       
+       print LIB<<LTEXT;
+<! KDOC Library HTML Reference File>
+<VERSION="$main::Version">
+<BASE URL="$url">
+<PLANG="$plang">
+<LIBNAME>$lib</LIBNAME>
+$libdesc
+
+LTEXT
+
+       writeNode( $root, "" );
+       close LIB;
+}
+
+sub writeNode
+{
+       my ( $n, $prefix ) = @_;
+       return if !exists $n->{Compound};
+       return if exists $n->{Forward} && !exists $n->{KidAccess};
+
+       if( $n != $root ) {
+               $prefix .= $n->{astNodeName};
+               print LIB "<C NAME=\"", $n->{astNodeName},
+                       "\" REF=\"$prefix.html\">\n";
+       }
+       else {
+               print LIB "<STATS>\n";
+               my $stats = $root->{Stats};
+               foreach my $stat ( keys %$stats ) {
+                       print LIB "<STAT NAME=\"$stat\">",
+                               $stats->{$stat},"</STAT>\n";
+               }
+               print LIB "</STATS>\n";
+       }
+
+       if( exists $n->{Ancestors} ) {
+               my $in;
+               foreach $in ( @{$n->{Ancestors}} ) {
+                       $in =~ s/\s+//g;
+                       print LIB "<IN NAME=\"",$in,"\">\n";
+               }
+       }
+
+       return if !exists $n->{Kids};
+       my $kid;
+       my $type;
+
+       foreach $kid ( @{$n->{Kids}} ) {
+               next if exists $kid->{ExtSource}
+                       || $kid->{Access} eq "private";
+
+               if ( exists $kid->{Compound} ) {
+                       if( $n != $root ) {
+                               writeNode( $kid, $prefix."::" );
+                       }
+                       else {
+                               writeNode( $kid, "" );
+                       }
+                       next;
+               }
+
+               $type = $kid->{NodeType} eq "method" ? 
+                       "ME" : "M";
+
+               print LIB "<$type NAME=\"", $kid->{astNodeName},
+                       "\" REF=\"$prefix.html#", $kid->{astNodeName}, "\">\n";
+       }
+
+       if( $n != $root ) {
+               print LIB "</C>\n";
+       }
+}
+
+sub readLibrary
+{
+       my( $rootsub, $name, $path, $relurl ) = @_;
+       $path = "." unless defined $path;
+       my $real = $path."/".$name.".kdoc";
+       my $url = ".";
+       my @stack = ();
+       my $version = "2.0";
+       my $new;
+       my $root = undef;
+       my $n = undef;
+       my $havecomp = -r "$real.gz";
+       my $haveuncomp = -r "$real";
+       
+       if ( $haveuncomp ) {
+               open( LIB, "$real" ) || die "Can't read lib $real\n";
+       }
+
+       if( $havecomp ) {
+               if ( $haveuncomp ) {
+                       warn "$exe: two libs exist: $real and $real.gz. "
+                               ."Using $real\n";
+               }
+               else {
+                       open( LIB, "gunzip < \"$real.gz\"|" ) 
+                       || die "Can't read pipe gunzip < \"$real.gz\": $?\n";
+               }
+       }
+
+       while( <LIB> ) {
+               next if /^\s*$/;
+               if ( !/^\s*</ ) {
+                       close LIB;
+                       readOldLibrary( $root, $name, $path );
+                       return;
+               }
+
+               if( /<VER\w+\s+([\d\.]+)>/ ) {
+                       # TODO: what do we do with the version number?
+                       $version = $1;
+               }
+               elsif ( /<BASE\s*URL\s*=\s*"(.*?)"/ ) {
+                       $url = $1;
+                       $url .= "/" unless $url =~ m:/$:;
+
+                       my $test = kdocUtil::makeRelativePath( $relurl, $url );
+                       $url = $test;
+               }
+               elsif( /<PLANG\s*=\s*"(.*?)">/ ) {
+                       $root = $rootsub->( $1 );
+                       $n = $root;
+               }
+               elsif ( /<C\s*NAME="(.*?)"\s*REF="(.*?)"\s*>/  ) {
+                       # class
+                       $new = Ast::New( $1 );
+                       $new->AddProp( "NodeType", "class" );
+                       $new->AddProp( "Compound", 1 );
+                       $new->AddProp( "ExtSource", $name );
+
+                       # already escaped at this point!
+                       $new->AddProp( "Ref", $url.$2 );
+
+                       $root = $n = $rootsub->( "CXX" ) unless defined $root;
+                       kdocAstUtil::attachChild( $n, $new );
+                       push @stack, $n;
+                       $n = $new;
+               }
+               elsif ( m#<IN\s*NAME\s*=\s*"(.*?)"\s*># ) {
+                       # ancestor
+                       kdocAstUtil::newInherit( $n, $1 );
+               }
+               elsif ( m#</C># ) {
+                       # end class
+                       $n = pop @stack;
+               }
+               elsif ( m#<(M\w*)\s+NAME="(.*?)"\s+REF="(.*?)"\s*># ) {
+                       # member
+                       $new = Ast::New( $2 );
+                       $new->AddProp( "NodeType", $1 eq "ME" ? "method" : "var" );
+                       $new->AddProp( "ExtSource", $name );
+                       $new->AddProp( "Flags", "" );
+                       $new->AddProp( "Ref", $url.$3 );
+
+                       kdocAstUtil::attachChild( $n, $new );
+               }
+       }
+}
+
+=head2 readLibrary
+
+       Parameters: rootnode, libname.
+
+       Read a kdoc 1.0 library into the node tree. Each external class
+       will have its "ExtSource" property set to the library name.
+
+=cut
+
+sub readOldLibrary
+{
+       my ( $root, $libname, $libdir ) = @_;
+
+       my @nodeStack = ();
+       my $cnode = $root;
+       my $fullpath = $libdir."/".$libname.".kdoc";
+       my $liburl = "";
+       my $newNode;
+       my $newMem;
+       
+       open( LIB,  $fullpath) || die "$exe: Can't read library $fullpath\n"; 
+
+       $liburl = <LIB>;
+       carp "Empty libfile: $fullpath\n" if !defined $liburl;
+       $liburl =~ s/\s+//g;
+
+       while( <LIB> ) {
+               # class url
+               next if !/^([^=]+)=/;
+               my $src = $1;
+               my $target = $';
+               if ( $src =~ /::/ ) {
+                       # member
+                       next if !defined $newNode 
+                               || $newNode->{astNodeName} ne $src;
+                       $newMem = Ast::New( $' );
+                       $newMem->AddProp( "NodeType", "Anon" );
+                       $newMem->AddProp( "Ref", $liburl."/".$target );
+                       kdocAstUtil::attachChild( $newNode, $newMem );
+               }
+               else {
+                       # class
+                       $src =~ s/^\s*(.*?)\s*$/$1/g;
+                       $newNode = Ast::New(  $src );
+                       $newNode->AddProp( "NodeType", "class" );
+                       $newNode->AddProp( "ExtSource", $libname );
+                       $newNode->AddProp( "Compound", 1 );
+                       $newNode->AddProp( "KidAccess", "public" );
+                       $newNode->AddProp( "Ref", $liburl."/".$target );
+                       kdocAstUtil::attachChild( $root, $newNode );
+               }
+       }
+
+       close( LIB );
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocParseDoc.pm b/deal.II/contrib/kdoc/src/kdocParseDoc.pm
new file mode 100644 (file)
index 0000000..143eccc
--- /dev/null
@@ -0,0 +1,414 @@
+package kdocParseDoc;
+
+use Ast;
+use strict;
+
+use vars qw/ $buffer $docNode %extraprops $currentProp $propType /;
+
+=head1 kdocParseDoc
+
+       Routines for parsing of javadoc comments.
+
+=head2 newDocComment
+
+       Parameters: begin (starting line of declaration)
+
+       Reads a doc comment to the end and creates a new doc node.
+
+       Read a line
+       check if it changes the current context
+               yes
+                       flush old context
+                       check if it is a non-text tag 
+                                               (ie internal/deprecated etc)
+                               yes
+                                       reset context to text
+                                       set associated property
+                               no
+                                       set the new context
+                                       assign text to new buffer
+               no      add to text buffer
+                       continue
+       at end
+               flush anything pending.
+
+=cut
+
+sub newDocComment
+{
+       my( $text ) = @_;
+       return undef unless $text =~ m#/\*\*+#;
+
+       setType( "DocText", 2 );
+       $buffer = $';
+       $docNode = undef;
+       %extraprops = ();       # used for textprops when flushing.
+       my $finished = 0;
+       my $inbounded = 0;
+
+       if ( $buffer =~ m#\*/# ) {
+               $buffer = $`;
+               $finished = 1;
+       }
+
+PARSELOOP:
+       while ( defined $text && !$finished ) {
+               # read text and remove leading junk
+               $text = main::readSourceLine();
+               next if !defined $text;
+               $text =~ s#^\s*\*(?!\/)##;
+
+               if ( $text =~ /^\s*<\/pre>/i ) {
+                       flushProp();
+                       $inbounded = 0;
+               }
+               elsif( $inbounded ) {
+                       if ( $text =~ m#\*/# ) {
+                               $finished = 1;
+                               $text = $`;
+                       }
+                       $buffer .= $text;
+                       next PARSELOOP;
+               }
+               elsif ( $text =~ /^\s*<pre>/i ) {
+                       textProp( "Pre" );
+                       $inbounded = 1;
+               }
+               elsif ( $text =~ /^\s*$/ ) {
+                       textProp( "ParaBreak", "\n" );
+               }
+               elsif ( $text =~ /^\s*\@internal\s*/ ) {
+                       codeProp( "Internal", 1 );
+               }
+               elsif ( $text =~ /^\s*\@deprecated\s*/ ) {
+                       codeProp( "Deprecated", 1 );
+               }
+               elsif ( $text =~ /^\s*\@group\s*/ ) {
+                       # logical group tag in which this node belongs
+                       # multiples allowed
+
+                       my $groups = $';
+                       $groups =~ s/^\s*(.*?)\s*$/$1/;
+
+                       if ( $groups ne "" ) {
+                               foreach my $g ( split( /[^_\w]+/, $groups) ) {
+
+                                       codeProp( "InGroup", $g );
+                               }
+                       }
+               }
+               elsif ( $text =~ /^\s*\@defgroup\s+(\w+)\s*/ ) {
+                       # parse group tag and description
+                       my $grptag = $1;
+                       my $grpdesc = $' eq "" ? $grptag : $';
+                       
+                       # create group node
+                       my $grpnode = Ast::New( $grptag );
+                       $grpnode->AddProp( "Desc", $grpdesc );
+                       $grpnode->AddProp( "NodeType", "GroupDef" );
+
+                       # attach
+                       codeProp( "Groups", $grpnode );
+               }
+               elsif ( $text =~ /^\s*\@see\s*/ ) {
+                       docListProp( "See" );
+               }
+               elsif( $text =~ /^\s*\@short\s*/ ) {
+                       docProp( "ClassShort" );
+               }
+               elsif( $text =~ /^\s*\@author\s*/ ) {
+                       docProp( "Author" );
+
+               }
+               elsif( $text =~ /^\s*\@version\s*/ ) {
+                       docProp( "Version" );
+               }
+               elsif( $text =~ /^\s*\@id\s*/ ) {
+
+                       docProp( "Id" );
+               }
+               elsif( $text =~ /^\s*\@since\s*/ ) {
+                       docProp( "Since" );
+               }
+               elsif( $text =~ /^\s*\@returns?\s*/ ) {
+                       docProp( "Returns" );
+               }
+               elsif( $text =~ /^\s*\@(?:throws|exception|raises)\s*/ ) {
+                       docListProp( "Throws" );
+               }
+               elsif( $text =~ /^\s*\@image\s+(\w+)\s*/ ) {
+                       textProp( "Image" );
+                       $extraprops{ "Path" } = $1;
+               }
+               elsif( $text =~ /^\s*\@param\s+(\w+)\s*/ ) {
+                       textProp( "Param" );
+                       $extraprops{ "Name" } = $1;
+               }
+               elsif( $text =~ /^\s*\@sect\s+/ ) {
+
+                       textProp( "DocSection" );
+               }
+               elsif( $text =~ /^\s*\@li\s+/ ) {
+
+                       textProp( "ListItem" );
+               }
+               elsif ( $text =~ /^\s*\@libdoc\s+/ ) {
+                       # Defines the text for the entire library
+                       docProp( "LibDoc" );
+               }
+               else {
+                       if ( $text =~ m#\*/# ) {
+                               $finished = 1;
+                               $text = $`;
+                       }
+                       $buffer .= $text;
+               }
+       }
+
+       flushProp();
+
+
+       return undef if !defined $docNode;
+
+# postprocess docnode
+
+       # add a . to the end of the short if required.
+       my $short = $docNode->{ClassShort};
+
+       if ( defined $short ) {
+               if ( !($short =~ /\.\s*$/) ) {
+                       $docNode->{ClassShort} =~ s/\s*$/./;
+               }
+       }
+       else {
+               # use first line of normal text as short name.
+               if ( defined $docNode->{Text} ) {
+                       my $node;
+                       foreach $node ( @{$docNode->{Text}} ) {
+                               next if $node->{NodeType} ne "DocText";
+                               $short = $node->{astNodeName};
+                               $short = $`."." if $short =~ /\./;
+                               $docNode->{ClassShort} = $short;
+                               goto shortdone;
+                       }
+               }
+       }
+shortdone:
+
+# Join and break all word list props so that they are one string per list 
+# node, ie remove all commas and spaces.
+
+       recombineOnWords( $docNode, "See" );
+       recombineOnWords( $docNode, "Throws" );
+
+       return $docNode;
+}
+
+=head3 setType
+
+       Parameters: propname, proptype ( 0 = single, 1 = list, 2 = text )
+
+       Set the name and type of the pending property.
+
+=cut
+
+sub setType
+{
+       ( $currentProp, $propType ) = @_;
+}
+
+=head3 flushProp
+
+       Flush any pending item and reset the buffer. type is set to DocText.
+
+=cut
+
+sub flushProp
+{
+       return if $buffer eq "";
+       initDocNode() unless defined $docNode;
+
+       if( $propType == 1 ) {
+               # list prop
+               $docNode->AddPropList( $currentProp, $buffer );
+       }
+       elsif ( $propType == 2 ) {
+               # text prop
+               my $textnode = Ast::New( $buffer );
+               $textnode->AddProp( 'NodeType', $currentProp );
+               $docNode->AddPropList( 'Text', $textnode );
+               
+               foreach my $prop ( keys %extraprops ) {
+                       $textnode->AddProp( $prop, 
+                               $extraprops{ $prop } );
+               }
+
+               %extraprops = ();
+       }
+       else {
+               # one-off prop
+               $docNode->AddProp( $currentProp, $buffer );
+       }
+
+       # reset buffer
+       $buffer = "";
+       setType( "DocText", 2 );
+}
+
+=head3 codeProp
+
+       Flush the last node, add a new property and reset type to DocText.
+
+=cut
+
+sub codeProp
+{
+       my( $prop, $val ) = @_;
+
+       flushProp();
+
+       initDocNode() unless defined $docNode;
+       $docNode->AddPropList( $prop, $val );
+       
+       setType( "DocText", 2 );
+
+}
+
+=head3 docListProp
+
+       The next item is a list property of docNode.
+
+=cut
+
+sub docListProp
+{
+       my( $prop ) = @_;
+
+       flushProp();
+
+       $buffer = $';
+       setType( $prop, 1 );
+}
+
+=head3 docProp
+
+       The next item is a simple property of docNode.
+
+=cut
+
+sub docProp
+{
+       my( $prop ) = @_;
+       
+       flushProp();
+
+       $buffer = $';
+       setType( $prop, 0 );
+}
+
+=head3 textProp
+
+       Parameters: prop, val
+
+       Set next item to be a 'Text' list node. if val is assigned, the
+       new node is assigned that text and flushed immediately. If this
+       is the case, the next item is given the 'DocText' text property.
+
+=cut
+
+sub textProp
+{
+       my( $prop, $val ) = @_;
+
+       flushProp();
+
+       if ( defined $val ) {
+               $buffer = $val;
+               setType( $prop, 2 );
+               flushProp();
+               $prop = "DocText";
+       }
+
+       setType( $prop, 2 );
+       $buffer = $';
+}
+
+
+=head3 initDocNode
+
+       Creates docNode if it is not defined.
+
+=cut
+
+sub initDocNode
+{
+       $docNode = Ast::New( "Doc" );
+       $docNode->AddProp( "NodeType", "DocNode" );
+}
+
+sub recombineOnWords
+{
+       my ( $docNode, $prop ) = @_;
+
+       if ( exists $docNode->{$prop} ) {
+               my @oldsee = @{$docNode->{$prop}};
+               @{$docNode->{$prop}} = split (/[\s,]+/, join( " ", @oldsee ));
+       }
+}
+
+###############
+
+=head2 attachDoc
+
+Connects a docnode to a code node, setting any other properties
+if required, such as groups, internal/deprecated flags etc.
+
+=cut
+
+sub attachDoc
+{
+       my ( $node, $doc, $rootnode ) = @_;
+
+       $node->AddProp( "DocNode", $doc );
+       $node->AddProp( "Internal", 1 ) if defined $doc->{Internal};
+       $node->AddProp( "Deprecated", 1 ) if defined $doc->{Deprecated};
+
+       # attach group definitions if they exist
+       if ( defined $doc->{Groups} ) {
+               my $groupdef = $rootnode->{Groups};
+               if( !defined $groupdef ) {
+                       $groupdef = Ast::New( "Groups" );
+                       $rootnode->AddProp( "Groups", $groupdef );
+               }
+
+               foreach my $grp ( @{$doc->{Groups}} ) {
+                       if ( defined $groupdef->{ $grp->{astNodeName} } ) {
+                               $groupdef->{ $grp->{ astNodeName}
+                               }->AddProp( "Desc", $grp->{Desc} );
+                       }
+                       else {
+                               $groupdef->AddProp( $grp->{astNodeName}, $grp );
+                       }
+               }
+       }
+
+       # attach node to group index(es)
+       # create groups if not found, they may be parsed later.
+
+       if ( defined $doc->{InGroup} ) {
+               my $groupdef = $rootnode->{Groups};
+
+               foreach my $grp ( @{$doc->{InGroup}} ) {
+                       if ( !exists $groupdef->{$grp} ) {
+                               my $newgrp = Ast::New( $grp );
+                               $newgrp->AddProp( "Desc", $grp );
+                               $newgrp->AddProp( "NodeType", "GroupDef" );
+                               $groupdef->AddProp( $grp, $newgrp );
+                       }
+
+                       $groupdef->{$grp}->AddPropList( "Kids", $node );
+               }
+       }
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocTeX.pm b/deal.II/contrib/kdoc/src/kdocTeX.pm
new file mode 100644 (file)
index 0000000..c41e296
--- /dev/null
@@ -0,0 +1,292 @@
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+package kdocTeX;
+
+require Ast;
+
+## LaTeX Output.
+# Peeks in main: quiet, version, classSource
+
+BEGIN {
+       $modname = "kdocTeX";
+}
+
+sub dumpDoc {
+       my( $name, $node, $outputdir ) = @_;
+
+       print "Generating LaTeX documentation.\n" unless $main::quiet;
+
+       open(TEX,"> $outputdir/$name.tex") 
+               || die "Couldn't create $outputdir/".$name.".tex.\n";
+
+       print TEX<<EOF;
+\\documentclass[12pt]\{article\}
+\\usepackage\{a4\}
+\\usepackage\{makeidx\}
+\\title\{$name Library Index\}
+\\date\{\\today\}
+\\def\\mtl{{\\tt\\~\\relax}}
+\\author{Generated with KDOC $main::version}
+\\makeindex
+\\begin\{document\}
+\\maketitle
+\\pagestyle\{headings\}
+\\tableofcontents
+\\newpage
+\\sloppy
+EOF
+
+       $node->Visit($modname);
+
+       foreach $class ( @{$classes} )  {
+
+               $class->Visit($modname);
+
+               $inPre = 0;
+               $doc = "";
+
+               foreach $line ( split /\n/, $Description ) {
+                       if( $line =~ /<(pre|PRE)>/ ) {
+                               $inPre = 1;
+                               $doc .= "\\begin{verbatim}\n";
+                               next;
+                       }
+                       if( $line =~ m#</(pre|PRE)># ) {
+                               $inPre = 0;
+                               $doc .= "\\end{verbatim}\n";
+                               next;
+                       }
+                       if( !$inPre ) {
+                               $line =~ s/\@ref(\s*(#|::))?//g;
+                               $line =~ s/([~#\$\\\&%#_\{\}])/\\$1/g;
+                               $line =~ s/<(code|pre)>/\\texttt\{/g;
+                               $line =~ s/<\/(code|pre)>/}/g;
+                               $line =~ s/([<>])/\\texttt\{$1\} /g;
+                               $line =~ s/~/\\texttt{~}\\relax /g;
+                       }
+
+                       $doc .= $line."\n";
+               }
+
+               $ClassName = escape( $astNodeName );
+               $Header =  escape( $Header );
+               $ClassSee = escape( $ClassSee );
+
+               print TEX<<EOF;
+\\section[$ClassName]\{\\emph\{$ClassName\} class reference \\small\\sf ($Header)\}
+\\vspace{-0.6cm}
+\\hrulefill
+\\index\{$ClassName\}
+EOF
+
+               if( $class->{ "TmplArgs" } ne "" ) {
+                       print TEX "\\begin{description}\n", 
+                               "\\item{template form:}",
+                               "\\texttt{template <", escape( $class->{ "TmplArgs" } ),
+                               "> ",
+                                $ClassName, "}\n";
+
+                       print TEX "\\end{description}\n";
+               }
+
+               if( defined $class->{ "Ancestors" } ){
+                       print TEX "\\begin{description}\n",
+                       "\\item{inherits:}";
+
+                       foreach $ancestor ( @{$Ancestors} ) {
+                               $ancName = $ancestor->{"astNodeName"};
+
+                               $str = " ".$ancName;
+
+                               if( defined $main::classSource{ $ancName } ) {
+                                       $str .="(".$main::classSource{$ancName}.
+                                                       ")";
+                               }
+
+                               print TEX escape( $str ),"\n";
+                       }
+
+                       print TEX "\\end{description}\n";
+               }
+
+
+               if( $Author ne "" || $Version ne "" || $ClassShort ne "" 
+                               || $ClassSee ne "" ) {
+                       print TEX "\\begin{description}\n";
+
+                       print TEX "\\item[Description:] ", 
+                                       escape( $ClassShort ),"\n"
+                               if $ClassShort ne "";
+                       print TEX "\\item[Version:] ", escape( $Version ),"\n"
+                               if $Version ne "";
+
+                       print TEX "\\item[Author:] ", escape( $Author ),"\n"
+                               if $Author ne "";               
+
+                       print TEX "\\item[See Also:] ", escape( $ClassSee ),"\n"
+                               if $ClassSee ne "";             
+
+                       print TEX "\\end{description}\n";
+               }
+
+               print TEX "$doc\n\n" if $Description ne "";
+
+               dumpMembers( "public members", $public ) 
+                       if defined $class->{"public"};
+               dumpMembers( "public slots", $public_slots )
+                       if defined $class->{"public_slots"};
+               dumpMembers( "protected members", $protected )
+                       if defined $class->{"protected"};
+               dumpMembers( "protected slots", $protected_slots )
+                       if defined $class->{"protected_slots"};
+               dumpMembers( "signals", $signals )
+                       if defined $class->{"signals"};
+
+               if( $main::dontDoPrivate == 0 ) {
+                       dumpMembers( "private members", $private )
+                               if defined $class->{"private"};
+                       dumpMembers( "private slots", $private_slots )
+                               if defined $class->{"private_slots"};
+               }
+
+               Ast::UnVisit();
+       }
+
+       Ast::UnVisit();
+
+       print TEX "\\printindex\n\\end{document}\n";
+
+}
+
+sub dumpMembers
+{
+       my( $access, $nodes ) = @_;
+
+       print TEX "\\subsection{$access}\n";
+
+       foreach $member ( @{$nodes} ) {
+
+               $member->Visit($modname);
+               
+               $inPre = 0;
+               $doc = "";
+
+               foreach $line ( split /\n/, $Description ) {
+                       if( $line =~ /<(pre|PRE)>/ ) {
+                               $inPre = 1;
+                               $doc .= "\\begin{verbatim}\n";
+                               next;
+                       }
+                       if( $line =~ /<\/(pre|PRE)>/ ) {
+                               $inPre = 0;
+                               $doc .= "\\end{verbatim}\n";
+                               next;
+                       }
+                       if( !$inPre ) {
+                               $line =~ s/\@ref(\s*(#|::))?//g;
+                               $line =~ s/([~#\$\\\&%#_\{\}])/\\$1/g;
+                               $line =~ s/<(code|pre)>/\\texttt\{/g;
+                               $line =~ s/<\/(code|pre)>/}/g;
+                               $line =~ s/([<>])/\\texttt\{$1\} /g;
+                               $line =~ s/~/\\texttt{~}\\relax /g;
+                       }
+
+                       $doc .= $line."\n";
+               }
+
+               $astNodeName = escape( $astNodeName );
+
+
+               print TEX<<EOF;
+\\subsubsection*{$ClassName\:\:$astNodeName}
+\\vspace{-0.65cm}
+\\hrulefill
+\\index{$ClassName!$astNodeName}
+\\index{$astNodeName!$ClassName}
+\\begin{flushleft}
+EOF
+
+               if( $Keyword eq "method" ) {
+                       $ReturnType = escape( $ReturnType );
+                       $Parameters = escape( $Parameters );
+                       $Parameters =~ s/\n+/ /g;
+
+                       print TEX "\\texttt{$ReturnType$astNodeName(",
+                               "$Parameters)$Const;}\n";
+               }
+               elsif ( $Keyword eq "property" ) {
+                       $Type = escape( $Type );
+                       print TEX "\\texttt{$Type$astNodeName;}\n";
+               }
+               elsif ( $Keyword eq "typedef" ) {
+                       $Type = escape( $Type );
+                       print TEX "\\texttt{$Type$astNodeName;}\n";
+               }
+               elsif ( $Keyword eq "enum" ) {
+                       $Constants = escape( $Constants );
+                       $Constants =~ s/\n+/ /g;
+
+                       print TEX<<EOF
+\\texttt{enum $astNodeName\\{
+$Constants
+\\};}
+
+EOF
+               }
+
+               print TEX<<EOF;
+\\end{flushleft}
+
+$doc
+
+EOF
+               if ( $Keyword eq "method" && 
+                       ($Returns ne "" || $Exceptions ne "") ) {
+
+                       if ( $Returns ne "" ) {
+                               $Returns = escape ( $Returns );
+                               print TEX<<EOF;
+\\begin{description}
+\\item[Returns:] $Returns
+\\end{description}
+EOF
+                       }
+
+                       if ( $Exceptions ne "" ) {
+                               $Exceptions = escape ( $Exceptions );
+                               print TEX<<EOF;
+\\begin{description}
+\\item[Throws:] $Exceptions
+\\end{description}
+EOF
+                       }
+
+               }
+               Ast::UnVisit();
+       }
+}
+
+sub escape
+{
+       my( $str ) = @_;
+
+       $str =~ s/\@ref\s+//g;
+       $str =~ s/([#\$\\\&%#_\{\}])/\\$1/g;
+       $str =~ s/([<>]+)/\\texttt\{$1\}/g;
+       $str =~ s/~/\\mtl /g;
+
+       return $str;
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/kdocUtil.pm b/deal.II/contrib/kdoc/src/kdocUtil.pm
new file mode 100644 (file)
index 0000000..a83de6a
--- /dev/null
@@ -0,0 +1,140 @@
+
+package kdocUtil;
+
+use strict;
+
+
+=head1 kdocUtil
+
+       General utilities.
+
+=head2 countReg
+
+       Parameters: string, regexp
+
+       Returns the number of times of regexp occurs in string.
+
+=cut
+
+sub countReg
+{
+       my( $str, $regexp ) = @_;
+       my( $count ) = 0;
+
+       while( $str =~ /$regexp/s ) {
+               $count++;
+               
+               $str =~ s/$regexp//s;
+       }
+
+       return $count;
+}
+
+=head2 findCommonPrefix
+
+       Parameters: string, string
+
+       Returns the prefix common to both strings. An empty string
+       is returned if the strings have no common prefix.
+
+=cut
+
+sub findCommonPrefix
+{
+       my @s1 = split( "/", $_[0] );
+       my @s2 = split( "/", $_[1] );
+       my $accum = "";
+       my $len = ($#s2 > $#s1 ) ? $#s1 : $#s2;
+
+       for my $i ( 0..$len ) {
+#              print "Compare: $i '$s1[$i]', '$s2[$i]'\n";
+               last if $s1[ $i ] ne $s2[ $i ];
+               $accum .= $s1[ $i ]."/";
+       }
+
+       return $accum;
+}
+
+=head2 makeRelativePath
+
+       Parameters: localpath, destpath
+       
+       Returns a relative path to the destination from the local path,
+       after removal of any common prefix.
+
+=cut
+
+sub makeRelativePath
+{
+       my ( $from, $to ) = @_;
+
+       # remove prefix
+       $from .= '/' unless $from =~ m#/$#;
+       $to .= '/' unless $to =~ m#/$#;
+
+       my $pfx = findCommonPrefix( $from, $to );
+
+       if ( $pfx ne "" ) {
+               $from =~ s/^$pfx//g;
+               $to =~ s/^$pfx//g;
+       }
+#      print "Prefix is '$pfx'\n";
+       
+       $from =~ s#/+#/#g;
+       $to =~ s#/+#/#g;
+       $pfx = countReg( $from, '\/' );
+
+       my $rel = "../" x $pfx;
+       $rel .= $to;
+
+       return $rel;
+}
+
+sub hostName
+{
+       my $host = "";
+       my @hostenvs = qw( HOST HOSTNAME COMPUTERNAME );
+
+       # Host name
+       foreach my $evar ( @hostenvs ) {
+                       next unless defined $ENV{ $evar };
+
+                       $host = $ENV{ $evar };
+                       last;
+       }
+
+       if( $host eq "" ) {
+                       $host = `uname -n`;
+                       chop $host;
+       }
+
+       return $host;
+}
+
+sub userName
+{
+       my $who = "";
+       my @userenvs = qw( USERNAME USER LOGNAME );
+
+       # User name
+       foreach my $evar ( @userenvs ) {
+                       next unless defined $ENV{ $evar };
+
+                       $who = $ENV{ $evar };
+                       last;
+       }
+
+       if( $who eq "" ) {
+               if ( $who = `whoami` ) {
+                               chop $who;
+               }
+               elsif ( $who - `who am i` ) {
+                               $who = ( split (/ /, $who ) )[0];
+               }
+       }
+
+       return $who;
+}
+
+1;
+
diff --git a/deal.II/contrib/kdoc/src/kdoctexi.pm b/deal.II/contrib/kdoc/src/kdoctexi.pm
new file mode 100644 (file)
index 0000000..26afb11
--- /dev/null
@@ -0,0 +1,595 @@
+package kdoctexi;
+
+# kdoctexi.pm -- C++ TexInfo output module for KDOC.
+#              Copyright (C) 1998, Bernd Gehrmann
+# $Id$
+
+# The KDOC package is distributed under the GNU Public License.
+
+use Ast;
+use kdocAstUtil;
+use File::Path;
+use File::Basename;
+use Iter;
+
+use strict;
+
+use vars qw/ $lib $rootnode $outputdir @clist $depth /;
+
+=head1 kdoctexi
+       TexInfo output module.
+=cut
+    
+sub writeDoc 
+{
+        ( $lib, $rootnode, $outputdir ) = @_;
+  
+        print "Generating texinfo documentation.\n" unless $main::quiet;
+
+       mkpath( $outputdir ) unless -f $outputdir;
+
+        makeClassList( $rootnode );
+        writeMain();
+        writeHierarchy();
+        writeOverview();
+        writeClasses();
+
+}
+
+
+
+sub makeClassList
+{
+       my ( $rootnode ) = @_;
+
+       @clist = ();
+
+       foreach my $node ( @ {$rootnode->{Kids}} ) {
+               if ( !defined $node ) {
+                       print "makeClassList: undefined child in rootnode!\n";
+                       next;
+               }
+
+               push( @clist, $node ) unless exists $node->{ExtSource}
+                               || !exists $node->{Compound};
+       }
+
+       @clist = sort { $a->{astNodeName} cmp $b->{astNodeName}  }
+                       @clist;
+}
+
+
+
+sub writeMain {
+
+        open( TEXMAIN, ">$outputdir/$lib.texi" ) 
+         || die "Couldn't write to $outputdir/$lib-main.texi\n";
+
+        print TEXMAIN<<EOF;
+\\input texinfo
+\@c %**start of header
+\@comment ----- automatically generated - do not edit! -----
+\@afourpaper
+\@setfilename $lib.info
+\@settitle $lib documentation
+\@headings on
+\@setchapternewpage on
+\@c %**end of header
+
+\@include $lib-hier.tex
+\@include $lib-overvw.tex
+\@include $lib-inc.tex
+
+\@page
+\@comment \@printindex fn
+\@shortcontents
+\@bye
+EOF
+
+        close( TEXMAIN );
+}
+
+
+
+sub writeHierarchy 
+{
+       my @bullets = ( '@bullet', '*', '+', '-' );
+       my $depth = 0;
+
+        open( TEX, ">$outputdir/$lib-hier.tex" ) 
+         || die "Couldn't write to $outputdir/$lib-hier.tex\n";
+       
+       print TEX "\@comment ----- automatically generated - do not edit! -----\n";
+       print TEX "\@unnumbered $lib Class Hierarchy\n\n";
+
+       Iter::Hierarchy( $rootnode,
+               sub { # down
+                       my $bullet = $bullets[ $depth ];
+                       $bullet = "-" unless defined $bullet;
+                       ++$depth;
+
+                       print TEX "\@itemize $bullet\n";
+               },
+               sub { # print
+                       my ($node) = @_;
+                       return if $node == $rootnode;
+
+                       my $src = defined $node->{ExtSource} ?
+                               " (from $node->{ExtSource})" : "";
+                       my $item = $depth > 0 ? "\@item\n" : "";
+
+                       print TEX "$item\@code{",$node->{astNodeName},"$src\n";
+               },
+               sub { # up
+                       print TEX "\@end itemize\n";
+                       --$depth;
+               }
+       );
+               
+       close TEX;
+}
+
+
+sub writeOverview 
+{
+       open( TEX, ">$outputdir/$lib-overvw.tex" ) 
+         || die "Couldn't write to $outputdir/$lib-classes.tex\n";
+       
+       print TEX "\@comment ----- automatically generated - do not edit! -----\n";
+       print TEX "\@unnumbered $lib Library Overview\n\n";
+
+       if ( defined $rootnode->{DocNode} ) {
+               writeDescription( $rootnode->{DocNode} );
+       }
+
+
+       print TEX "\@table \@asis\n";
+       
+       foreach my $node ( @clist ) {
+
+                my $docnode = $node->{DocNode};
+
+               my $short = "";
+               if ( defined $docnode && exists $docnode->{ClassShort} ) {
+                       $short = formatText($docnode->{ClassShort});
+               }
+
+               my $className = $node->{astNodeName};
+
+                # The following is really a dirty hack
+                # Find something better!
+               print TEX "\@item \@code{$className ";
+               print TEX "@ @ @ @ @ @ @ @ @ @ @ @ @ }", "\n";
+               print TEX escape($short), "\n";
+       }
+                                                 
+       print TEX "\@end table\n";
+       close TEX;
+}
+
+
+
+sub writeClasses 
+{
+       open( TEXINC, ">$outputdir/$lib-inc.tex" ) 
+         || die "Couldn't write to $outputdir/$lib-inc.tex\n";
+       print TEXINC "\@comment ----- automatically generated - do not edit! -----\n";
+       
+       foreach my $node ( @clist ) {
+
+               next if !defined $node->{Compound} 
+                 || defined $node->{ExtSource};
+
+               my $className = $node->{astNodeName};
+
+               print TEXINC "\@include $className.tex\n";
+               open( TEX, ">$outputdir/$className.tex" ) 
+                 || die "Couldn't write to $outputdir/$className.tex\n";
+               print TEX "\@comment ----- automatically generated - do not edit! -----\n";
+
+               writeClass( $node );
+               close TEX;
+       }
+       
+       close TEXINC;
+}
+
+
+
+sub writeClass 
+{
+       my ( $node ) = @_;
+
+       my $docnode = $node->{DocNode};
+       my $header = $node->{Source}->{astNodeName};
+       my $className = $node->{astNodeName};
+       
+       my $classType = (exists $node->{Tmpl} )? "Template" : "Class";
+       
+       print TEX<<EOF;
+\@unnumbered \@code\{$className\} $classType Reference \@i\{($header)\}
+\@findex $className
+EOF
+       
+       if ( exists $docnode->{Deprecated} ) {
+               print TEX "\@noindent\n\@b{Deprecated Class}\n";
+       }
+       
+       if ( exists $docnode->{Internal} ) {
+               print TEX "\@noindent\n\@b{For internal use only}\n";
+       }
+
+       if ( exists $node->{Pure} ) {
+               print TEX "\@noindent\n\@b{Contains pure virtuals}\n";
+       }
+       
+       if ( $classType eq "template" ) {
+               print TEX "\@table \@asis\n\@item Template form:\n",
+               "\@code{template <", escape( $node->{Tmpl} ),
+               "> ", $className, "}\n\@end table\n";
+       }
+       
+       my $comma = "";
+
+       Iter::Ancestors( $node, $rootnode, undef,
+               sub { # start
+                       print TEX "\@table \@asis\n\@item Inherits:\n"
+               },
+               sub { # print
+                       my ( $n, $name, $type, $template ) = @_;
+                       my $source;
+
+                       if ( defined $n ) {
+                               $source = defined $n->{ExtSource} ?
+                               " ($n->{ExtSource})" : "";
+                               $name = $n->{astNodeName};
+                       }
+
+                       print TEX $comma, escape( $name ), $source, "\n";
+               },
+               sub { #end
+                       print TEX "\@end table\n";
+               }
+       );
+       
+       Iter::Descendants( $node, undef,
+               sub { #start
+                       print TEX "\@table \@asis\n\@item Inherited by:\n";
+                       $comma = "";
+               },
+               sub { #print
+                       my ($in) = @_;
+                       my $source;
+                       $source = defined $in->{ExtSource} ?
+                               " ($in->{ExtSource})\n" :"\n";
+
+                       print TEX $comma, escape( $in->{astNodeName} ),
+                               $source;
+               },
+               sub { #end
+                       print TEX "\n\@end table\n";
+               }
+       );
+
+        my $author   = $node->{Author};
+        my $version  = $node->{Version};
+        my $classSee = $node->{See};
+
+       if( $author ne "" || $version ne "" || $classSee ne "" ) {
+               my $escVersion = escape( $version );
+               my $escAuthor = escape( $author );
+               $escAuthor =~ s/<(.+\@\@.+)>/\@email{$1}/mg;
+               $escAuthor =~ s/\((.+\@\@.+)\)/\@email{$1}/mg;
+               my $escSee = escape( $classSee );
+               print TEX "\@table \@asis\n";
+               print TEX "\@item Version:\n$escVersion\n" unless $escVersion eq "";
+               print TEX "\@item Author:\n$escAuthor\n" unless $escAuthor eq "";               
+               print TEX "\@item See Also:\n$escSee\n" unless $escSee eq "";           
+               print TEX "\@end table\n";
+       }
+       
+       writeDescription( $docnode );
+       
+       Iter::MembersByType( $node,
+               sub {   #startgroup
+                       print TEX "\@unnumberedsec $_[0]\n";
+               },
+               sub {   # member
+                       my ( $node, $kid ) = @_;
+
+                       writeMember( $node, $kid );
+               }
+       );
+}
+
+sub writeMember 
+{
+       my ( $classnode, $member ) = @_;
+       my $className = $classnode->{astNodeName};
+       my $memberName = $member->{astNodeName};
+        my $escName = escape( $memberName );
+       my $type = $member->{NodeType};
+        $_ = $type;
+        SWITCH: {
+               
+               if( /^method/ ) {
+                       my $escRetType = escape( $member->{ReturnType} );
+                       my $escParams = escape( $member->{Params} );
+                       my $flags = $member->{Flags};
+
+                       if ( $memberName eq $className ) {
+                               print TEX "\@deftypefn Constructor {} $escName {($escParams)}\n";
+                       }
+                       elsif ( $memberName eq "~$className" ) {
+                               print TEX "\@deftypefn Destructor {} $escName {($escParams)}\n";
+                       }
+                        elsif ( $flags =~ /s/ ) {
+                               print TEX "\@deftypefn {Static Method} {$escRetType} $escName ",
+                               "{($escParams)}\n";
+                       }
+                       else {
+                               print TEX "\@deftypefn Method {$escRetType} $escName ",
+                               "{($escParams)}", $flags =~ /c/? " const\n" : "\n";
+                       }
+                       
+                       my $ref = kdocAstUtil::findOverride( $rootnode, 
+                                       $classnode, $member->{astNodeName} );
+                       if ( defined $ref ) {
+                               print TEX "Reimplemented from $ref\n";
+                       }
+
+                       writeMemberInfo( $member->{DocNode} );
+                       
+                        my @paramlist = ();
+                        kdocAstUtil::findNodes( \@paramlist, $member->{Text},
+                                                "NodeType", "Param" );
+
+                       if ( $#paramlist >= 0 ) {
+                               print TEX "\@noindent\nParameters:\n",
+                                 "\@multitable \@columnfractions .1 .15 .75\n";
+                               foreach my $paramnode ( @paramlist ) {
+                                       print TEX "\@item \@tab ",
+                                       escape($paramnode->{Name}), " \@tab ",
+                                       escape($paramnode->{astNodeName}), "\n";
+                                       
+                               }
+                                       print TEX "\@end multitable\n";
+                       }
+                               
+                       my $returns = $member->{Returns};
+                       print TEX "\@noindent\nReturns: ", 
+                               escape($returns), "\n" unless $returns eq "";
+                               
+                        my $exceptions = $member->{Throws};
+                       if ( $exceptions ne "" ) {
+                               print TEX "\@noindent\n\@table ",
+                                       "\@asis\n\@item Throws:\n",
+                                       escape($exceptions), "\n\@end table\n";
+                       }
+                               
+                       print TEX "\@end deftypefn\n\n";
+                       last SWITCH;
+               } # /^method/
+               
+               if ( /^var/ ) {
+                       my $type = $member->{Type};
+                       print TEX "\@deftypevar ", escape($type), " $escName\n";
+                       writeMemberInfo( $member->{DocNode} );
+                       print TEX "\@end deftypevar\n";
+                       last SWITCH;
+               } # /^var/
+               
+               if( /^typedef/ ) {
+                       my $escType = escape( $member->{Type} );
+                       print TEX "\@deftp {typedef} {$escType} $escName\n";
+                       writeMemberInfo( $member->{DocNode} );
+                       print TEX "\@end deftp\n";
+                       last SWITCH;
+               } # /^typedef/
+               
+               if ( /^enum/ ) {
+                       # I'm not really convinced that it makes sense to list all constants.
+                       # Normally, I would expect that all constants are explained in the
+                       # doc comment, embedded in a <ul>..</ul> list.
+                       my $escConstants = escape( $member->{Params} );
+                       $escConstants =~ s/\n+/\n/g;
+                        my $enumName = ($escName =~ /^\s*$/)? 
+                               "(Anonymous)" : $escName;
+                       print TEX "\@deftp Enumeration \@code{enum} $enumName\n";
+                       print TEX "\@example\nenum $enumName \@{\n",
+                       "$escConstants\@};\n\@end example\n";
+                       writeMemberInfo( $member->{DocNode} );
+                       print TEX "\@end deftp\n";
+                       last SWITCH;
+               } # /^enum/
+               
+       } # SWITCH
+       
+}
+
+
+
+sub writeDescription 
+{
+        my ( $docnode ) = @_;
+
+        my $text = $docnode->{Text};
+       if ( $text eq "") { return; }
+
+        my $lasttype = "";     
+       my $type = undef;
+       foreach my $node ( @$text ) {
+                $type = $node->{NodeType};
+                my $name = $node->{astNodeName};
+
+               if ( $lasttype eq "ListItem" && $type ne $lasttype ) {
+                        print TEX "\@end itemize\n";
+               }
+
+               if ( $type eq "Pre" ) {
+                        print TEX "\@example\n";
+                       print TEX escape($name);
+                        print TEX "\n\@end example\n";
+               }
+                elsif ( $type eq "DocText" || $type eq "Ref" ) {
+                        print TEX formatText($name);
+               }
+                elsif ( $type eq "ParaBreak" ) {
+                        print TEX "\n\n";
+               }
+               elsif ( $type eq "ListItem" ) {
+                       if ( $lasttype ne "ListItem" ) {        
+                                print TEX "\@itemize \@bullet\n";
+                       }
+                        print TEX "\@item ", formatText($name), "\n";
+               }
+
+               $lasttype = $type;
+
+       }
+
+        if( $type eq "ListItem" ) {
+               print TEX "\@end itemize\n"; 
+        }
+
+       print TEX "\n";
+       
+}
+
+
+
+sub writeMemberInfo 
+{
+
+        my ( $docnode ) = @_;
+
+       writeDescription( $docnode );
+       
+#      if( $MethDeprecated ) {
+#              print TEX "\@noindent\n\@b{Deprecated Member}\n";
+#      }
+#      
+#      if( $MethInternal ) {
+#              print TEX "\@noindent\n\@b{For internal use only}\n";
+#      }
+       
+}
+
+
+# This is for conversion of general, non-preformatted text
+
+sub formatText 
+{
+       my ( $text ) = @_;
+       
+       $text = escape($text);
+       # After escape, @ is @@
+       $text =~ s/\@\@ref\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
+        $text =~ s/\@\@ref\s+(#|::)?([\w\d_~]+)/$2/g;
+       $text =~ s/\@\@see\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
+        $text =~ s/\@\@see\s+(#|::)?([\w\d_~]+)/$2/g;
+       $text =~ s/<em>/\@emph\{/ig;
+       $text =~ s/<\/em>/\}/ig;
+       $text =~ s/<strong>/\@strong\{/ig;
+        $text =~ s/<\/strong>/\}/ig;
+        $text =~ s/<dfn>/\@dfn\{/ig;
+        $text =~ s/<\/dfn>/\}/ig;
+        $text =~ s/<code>/\@code\{/ig;
+        $text =~ s/<\/code>/\}/ig;
+        $text =~ s/<samp>/\@samp\{/ig;
+        $text =~ s/<\/samp>/\}/ig;
+        $text =~ s/<kbd>/\@kbd\{/ig;
+        $text =~ s/<\/kbd>/\}/ig;
+        $text =~ s/<var>/\@var\{/ig;
+        $text =~ s/<\/var>/\}/ig;
+        $text =~ s/<cite>/\@cite\{/ig;
+        $text =~ s/<\/cite>/\}/ig;
+        $text =~ s/<i>/\@i\{/ig;
+        $text =~ s/<\/i>/\}/ig;
+        $text =~ s/<b>/\@b\{/ig;
+        $text =~ s/<\/b>/\}/ig;
+        $text =~ s/<tt>/\@t\{/ig;
+        $text =~ s/<\/tt>/\}/ig;
+
+        $text =~ s/<br>/\@*/ig;
+        $text =~ s/<p>/\n/ig;
+        $text =~ s/<\/p>//ig;
+                        
+        $text =~ s/&lt;/</g;
+        $text =~ s/&gt;/>/g;
+        $text =~ s/&amp;/&/g;
+        $text =~ s/&nbsp;/\@ /g;
+        $text =~ s/&copy;/\@copyright{}/g;
+
+# Support for other languages?
+        $text =~ s/&auml;/\@"a/g;
+        $text =~ s/&ouml;/\@"o/g;
+        $text =~ s/&uuml;/\@"u/g;
+        $text =~ s/&Auml;/\@"A/g;
+        $text =~ s/&Ouml;/\@"O/g;
+        $text =~ s/&Uuml;/\@"U/g;
+        $text =~ s/&szlig;/\@ss/g;
+
+        $text =~ s/^\s*<blockquote>\s*$/\@quotation/mig;
+        $text =~ s/^\s*<\/blockquote>\s*$/\@end quotation/mig;
+        $text =~ s/^\s*<ul>\s*$/\@itemize \@bullet/mig;
+        $text =~ s/^\s*<\/ul>\s*$/\@end itemize/mig;
+        $text =~ s/^\s*<ol>\s*$/\@enumerate/mig;
+        $text =~ s/^\s*<\/ol>\s*$/\@end enumerate/mig;
+        $text =~ s/^\s*<dl>\s*$/\@table \@asis/mig;
+        $text =~ s/^\s*<\/dl>\s*$/\@end table/mig;
+        $text =~ s/^\s*<li>/\@item /mig;
+        $text =~ s/^\s*<\/li>//mig;
+        $text =~ s/^\s*<dt>/\@item /mig;
+        $text =~ s/^\s*<\/dt>//mig;
+        $text =~ s/^\s*<dd>//mig;
+        $text =~ s/^\s*<\/dd>//mig;
+
+        return $text;
+}
+
+
+# This is for preformatted or similar text
+sub escape 
+{
+       my( $text ) = @_;
+       
+       $text =~ s/([\@\{\}])/\@$1/g;
+
+# i18n support
+#  $text =~ s/ä/\@"a/g;
+#  $text =~ s/ö/\@"o/g;
+#  $text =~ s/ü/\@"u/g;
+#  $text =~ s/Ä/\@"A/g;
+#  $text =~ s/Ö/\@"O/g;
+#  $text =~ s/Ãœ/\@"U/g;
+#  $text =+ s/ß/\@ss{}/g;
+
+       return $text;
+}
+
+#
+
+sub deref
+{
+       my ( $str ) = @_;
+       my $out = "";
+       my $text;
+
+       $str =~ s/\@\@ref\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
+        $str =~ s/\@\@ref\s+(#|::)?([\w\d_~]+)/$2/g;
+        $out = $str;
+
+#      foreach $text ( split (/(\@ref\s+[\w:#]+)/, $str ) ) {
+#              if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
+#                      $out .= $1;
+#              }
+#              else {
+#                      $out .= $text;
+#              }
+#      }
+       
+       return $out;
+}
+
+1;
diff --git a/deal.II/contrib/kdoc/src/makekdedoc b/deal.II/contrib/kdoc/src/makekdedoc
new file mode 100755 (executable)
index 0000000..a2a152c
--- /dev/null
@@ -0,0 +1,302 @@
+#!/usr/local/bin/perl
+
+# makekdedoc -- Generates HTML documentation KDE libraries using KDOC 2.
+#              Sirtaj Singh Kang <taj@kde.org> Apr 1999.
+#              $Id$
+
+require 5.000;
+
+use Getopt::Long;
+
+%files = ();
+%libs = ();
+%mods = ();
+%dirs = ();
+
+($ver = '$Revision$') =~ s/\$//g;
+$rulefile= "";
+$libdir=$ENV{KDOCLIBS};
+$outdir="srcdoc";
+$url="";
+$srcdir=".";
+$kdoc= "kdoc";
+$kdocopt = "--strip-h-path --format html --compress";
+$cwd = `pwd`;
+chop $cwd;
+
+# options
+
+Getopt::Long::config qw( no_ignore_case permute bundling auto_abbrev );
+
+$err = GetOptions( 
+        "url|u=s",     \$url,
+        "outputdir|d=s", \$outdir,
+       "rule-file|r=s", \$rulefile,
+        "help|h",       \&show_usage,
+        "libdir|L=s",   \$libdir,
+       "kdoc|s=s",     \$kdoc,
+       "srcdir|b=s",   \$srcdir,
+       "kdocopt|p=s",  \$extraopts );
+
+if ( $err == 0 ) {
+       show_usage();
+}
+
+$srcdir =~ s#^\.#$cwd#g;
+$outdir =~ s#^\.#$cwd#g;
+$outdir = $cwd."/$outdir" unless $outdir =~ m#^/#;
+$url = $outdir unless $url ne "";
+$libdir=$ENV{HOME}."/.kdoc" unless defined $libdir;
+
+if ( $rulefile eq "" ) {
+       $rulefile = $srcdir."/kdoc.rules";
+}
+else {
+       $rulefile =~ s#^\.#$cwd#g;
+}
+
+# read rule file
+
+readRules();
+
+die "$0: no modules to document.\n" if $#mods < 0;
+
+# generate docs
+
+if ($#ARGV >= 0 ) {
+       @mods = @ARGV;
+}
+
+foreach my $mod ( @mods ) {
+       print "$0: generating $mod...\n";
+
+       die "module $mod: no files defined\n" unless exists $files{ $mod };
+
+       # build the kdoc command
+       chdir $dirs{ $mod } || 
+               die "Couldn't cd to: $dirs{$mod} (try the -h option)\n";
+       @filelist = glob( $files{ $mod } );
+
+       if ( $#filelist < 0 ) {
+               chdir $cwd;
+               die "module $mod: no files defined\n";
+       }
+
+       $cmd = "$kdoc $kdocopt $extraopts -n '$mod' -d '$outdir/$mod'"
+               ." -L '$libdir' "
+               ."-u '$url/$mod' '".join( "' '", @filelist)."' ".$libs{ $mod };
+
+       system( $cmd ) == 0 || die "kdoc call failed:\n$cmd\n";
+
+       chdir $cwd;
+}
+
+exit 0;
+### done
+
+sub readRules
+{
+       open ( RULES, "$rulefile" ) || die "$0: couldn't read ",$rulefile,".".
+               "(try the -h option)\n";
+
+       while( <RULES> ) {
+               next unless /^\s*([\w\/]+)      # module
+                       _(\w+)                  # key
+                       \s*=\s*/xs;             # rest: value
+
+                       $mod = $1;
+               $key = $2;
+               $v = $';
+               chop $v;
+
+               if ( $key eq "FILES" ) {
+                       $files{ $mod } = $v;
+               }
+               elsif ( $key eq "LIBS" ) {
+                       $libs{ $mod } = $v;
+               }
+               elsif ( $key eq "MODULES" ) {
+                       @mods = split /\s+/, $v;
+
+# default path for module is $srcdir/$mod
+                       foreach my $mod ( @mods ) {
+                               $dirs{ $mod } = "$srcdir/$mod";
+                       }
+               }
+               elsif ( $key eq "PATH" ) {
+                       if ( $v =~ m#^/# ) {
+# allow absolute paths
+                               $dirs{ $mod } = $v;
+                       }
+                       else {
+                               $dirs{ $mod } = "$srcdir/$v";
+                       }
+
+               }
+               else {
+                       die "$rulefile:$.: Unrecognized key: $key\n";
+               }
+       }
+
+       close RULES;
+}
+
+
+
+sub show_usage
+{
+       print STDERR<<EOF;
+$0:
+       Generates HTML documentation for KDE libs.
+       Author: Sirtaj S. Kang <taj\@kde.org>
+       $ver
+       
+Usage:
+       $0 [--rule-file=<rulefile>] [--libdir=<libdir>]
+               [--outputdir=<outputdir>] [--url=<url>]
+               [--srcdir=<kdelibs src dir>]
+               [--kdoc=<path to kdoc>] [<library>...]
+
+       By default all libraries defined by the rule file are
+       documented.
+
+Defaults:
+       rulefile        "<srcdir>/kdoc.rules"
+       libdir          "\$KDOCLIBS" or "\$HOME/.kdoc"
+       outputdir       "./srcdoc"
+       url             same as outdir
+       srcdir          current dir
+       kdoc            "kdoc"
+       kdocopts        ""
+EOF
+
+       exit 1;
+}
+
+
+
+
+
+
+=head1 NAME
+
+makekdedoc -- Generates HTML documentation for KDE libraries using B<KDOC>.
+
+=head1 SYNOPSIS
+
+       makekdedoc [--rule-file=<rulefile>] [--libdir=<libdir>]
+               [--outputdir=<outputdir>] [--url=<url>]
+               [--srcdir=<kdelibs src dir>]
+               [--kdoc=<path to kdoc>] [<library>...]
+
+       makekdedoc --help
+
+=head1 DESCRIPTION
+
+This is a perl script that uses B<KDOC> to generate documentation for
+kdelibs. A "rule" file is used to figure out the libraries to document,
+the order in which to document them and the libraries with which each
+one will be cross-referenced (eg kdeui uses -lkdecore). See L<"FILES"> 
+for more info.
+
+NOTE: The script assumes that you have already generated a Qt
+cross-reference using qt2kdoc[1].
+
+=head1 OPTIONS
+
+Defaults for each option are in square brackets.
+
+=over 4
+
+=item B<library...>
+
+Specify the libraries to document.  By default, all libraries defined by
+the rule file are documented.
+
+=item B<--outputdir> <path>, B<-d> <path> 
+
+The directory where the output will be written.        [`cwd`/srcdoc]
+
+=item B<--url> <url>, B<-u> <url>
+
+The base URL by which the generated docs will be accessed. For
+example, if your web server is configured to use $HOME/public_html for
+your home page, you could set the outputdir to $HOME/public_html/srcdoc
+and the url to http://myhost/~mylogin/srcdoc. [output dir]
+
+=item B<--rule-file> <path>, B<-r> <path>
+
+The path to the rule file to use for generating the documentation.
+[<srcdir>/kdoc.rules]
+
+=item B<--libdir> <path>, B<-L> <path> 
+
+The directory in which the KDOC cross-reference files are
+stored. [$KDOCLIBS if set, otherwise $HOME/.kdoc]
+
+=item B<--kdoc> <path>, B<-k> <path>   
+
+The path to the kdoc program. [kdoc]
+
+=item B<--kdocopt> <options>, B<-p> <options>
+
+Extra options to be passed to kdoc.
+
+=item B<--srcdir> <path>, B<-b> <path> 
+
+The path to the kdelibs source, eg "$HOME/baseline/kdelibs". [`cwd`]
+
+=item B<--help>, B<-h>
+
+Quit with a usage message.
+
+=back
+
+=head1 EXAMPLES
+
+       makekdedoc --srcdir $HOME/baseline/kdelibs 
+               --outputdir $HOME/public_html/src/kdelibs/
+               --url "http://www.ph.unimelb.edu.au/~ssk/src/kdelibs"
+
+=head1 FILES
+
+=over 4
+
+=item B<Rule file>
+
+This file lists the directories in the source directory to document. It
+also lists the files to document from each directory, and the libraries
+with which to cross-reference the generated documentation. Here is a small
+example that documents two libraries and links the second to the first.
+
+       # makekdedoc rule file
+       doc_MODULES = eenie meenie
+
+       # rules for eenie
+       eenie_FILES = *.h
+       eenie_LIBS = -lqt
+
+       # rules for meenie
+       meenie_FILES = a.h b.h
+       meenie_LIBS = -leenie -lqt
+
+In this example, all files in C<eenie/*.h> will be documented then two files
+from C<meenie/> will be documented, in the order declared in
+C<doc_MODULES>.
+
+=back
+
+=head1 SEE ALSO
+
+See L<kdoc[1]> and L<qt2kdoc[1]>.
+
+=head1 VERSION
+
+       makekdedoc $Revision$
+
+=head1 AUTHOR
+
+The script and this documentation were written by Sirtaj Singh Kang
+<taj@kde.org> in April 1999.
+
+=cut
diff --git a/deal.II/contrib/kdoc/src/qt2kdoc b/deal.II/contrib/kdoc/src/qt2kdoc
new file mode 100755 (executable)
index 0000000..d66858a
--- /dev/null
@@ -0,0 +1,232 @@
+#!/usr/local/bin/perl -w
+
+# qt2kdoc -- Generates KDOC reference index for the Qt GUI toolkit.
+# Sirtaj Singh Kang 1997 
+# $Id$
+
+use Getopt::Long;
+
+Getopt::Long::config qw( no_ignore_case permute bundling auto_abbrev );
+
+$lib = "./qt.kdoc";
+$destUrl = "";
+$libdir = $ENV{KDOCLIBS};
+$comp = 0;
+
+$err = GetOptions( "url|u=s", \$destUrl,
+               "outdir|o=s", \$libdir,
+               "compress|z", \$comp );
+
+if( $err == 0 ) {
+       usage();
+}
+
+$libdir = $ENV{HOME}."/.kdoc" unless defined $libdir;
+
+
+if( $#ARGV != 0 ) {
+       usage();
+}
+
+$file = $ARGV[ 0 ];
+$destUrl = $file if $destUrl eq "";
+$lib = $libdir."/qt.kdoc" if $libdir ne "";
+# Read hierarchy
+
+open( IN, $file."/hierarchy.html" ) 
+       || die "Could not open $file for reading\n";
+open( OUT, ">$lib" ) || die "Could not open $lib for writing\n";
+
+@stack = ();
+%ref = ();
+%parent = ();
+$current = undef;
+
+while ( <IN> )
+{
+       if( m#<ul\s+# ) {
+               push @stack, $current;
+               $current = undef;
+       }
+       elsif ( /^<li><a href=\"([\w\.]*)\">([\w]*)<\/a>/ ) { # "vim..grmbl
+               $current = $2;
+               $ref{ $current } = $1;
+
+               if ( $#stack >= 0 ) {
+                       $parent{ $current } .= $stack[ $#stack ].",";
+               }
+       }
+       elsif ( m#</ul># ) {
+               $current = pop @stack;
+       }
+}
+
+# read all members
+
+%members = ();
+%refs = ();
+
+$lastmem = undef;
+
+open( IN, $file."/functions.html" ) 
+       || die "Could not open $file for reading\n";
+
+while ( <IN> ) {
+       if ( /^\s*<li.*?>(\w+):/ ) {
+               # function
+               $lastmem = $1;
+       }
+       elsif ( /^\s*<a href=\"(.*?)\">(\w+)/ && defined $lastmem ) { #"
+               # class
+               if ( !exists $members{ $2 } ) {
+                       $members{ $2 } = [ $lastmem ];
+                       $refs{ $2 } = [ $1 ];
+               }
+               else {
+                       push @{$members{ $2 }}, $lastmem;
+                       push @{$refs{ $2 }}, $1;
+               }
+       }
+       elsif ( defined $lastmem ) {
+               $lastmem = undef;
+       }
+}
+
+# write it
+
+print OUT<<LTEXT;
+<! KDOC Library HTML Reference File>
+<VERSION="2.0">
+<BASE URL="$destUrl">
+LTEXT
+
+foreach my $current ( sort keys %ref ) {
+       print OUT '<C NAME="', $current, '" REF="',
+               $ref{ $current }, '">',"\n";
+       if ( exists $parent{ $current } ) {
+               foreach $p ( sort split( ",", $parent{ $current } ) ) {
+                       print OUT '<IN NAME="', $p, '">', "\n";
+               }
+       }
+
+       my $m = $members{ $current };
+       if( $#{$m} >= 0 ) {
+               my $r = $refs{ $current };
+               for $p ( 0..$#{$m} ) {
+                       print OUT '<ME NAME="', $m->[$p], '" REF="',
+                               $r->[$p],'">',"\n";
+               }
+       }
+       print OUT "</C>\n";
+}
+
+close( IN );
+close( OUT );
+
+# compress
+
+if ( $comp ) {
+       system ( 'gzip -9 "'.$lib.'"' ) == 0
+               || die "Couldn't compress $lib: $?\n";
+       
+       $lib .= ".gz";
+}
+
+print "Qt reference written to $lib\n";
+
+# end main
+
+sub usage
+{
+       my $arg = shift;
+
+       print "qt2kdoc: Creates a kdoc reference file from".
+               " Qt HTML documentation.",
+               "\n\n", "usage:\n\tqt2kdoc [-u<URL>] [-o<dest>] [-z]",
+               " <path-to-Qt-html>\n";
+       exit 1;
+}
+
+=head1 NAME
+
+qt2kdoc -- Generates cross-reference file suitable for use with B<KDOC>
+from Qt Toolkit HTML documentation.
+
+=head1 SYNOPSIS
+
+       qt2kdoc [-u URL] [-o <destdir>] [-z] <path to qt html>
+
+=head1 DESCRIPTION
+
+B<qt2kdoc> generates a kdoc(1) cross-reference file from  the classes.html
+file that is included with the Qt GUI Toolkit HTML documentation.
+
+The resulting file can be used to cross-reference documentation generated
+with KDOC for other classes with the Qt HTML documentation.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--url> <url>, B<-u> <url>
+
+The URL  by  which  the  Qt  documentation  can  be accessed.  This  will
+allow other libraries to link to the Qt documentation.
+
+=item B<--outdir> <path>, B<-o> <path>
+
+The directory where the generated index file will be written.
+
+=item B<--compress>, B<-z>
+
+Compress the generated index with gzip. KDOC can read these compressed
+index files.
+
+=back
+
+=head1 EXAMPLES
+
+       qt2kdoc -u "http://www.mydomain/src/qthtml/" \
+               $HOME/web/src/qthtml
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item B<KDOCLIBS>
+
+If set, it is used as the default output path. It is overridden by the
+B<--outdir> option.
+
+=back
+
+=head1 FILES
+
+=over 4 
+
+=item B<classes.html>, B<functions.html>
+
+The files from which information about the Qt library is read. They are
+parsed by qt2kdoc.
+
+=item B<qt.kdoc>
+
+A kdoc(1) cross-reference file that will be  generated  by qt2kdoc and can
+be used to link documentation generated by kdoc with the Qt documentation.
+
+=back
+
+=head1 SEE ALSO
+
+This script is a utility for kdoc(1).
+
+=head1 BUGS
+
+Dependent on format of Qt documentation.
+
+=head1 AUTHOR
+
+Sirtaj S. Kang <taj@kde.org>, 1998.
+
+=cut
diff --git a/deal.II/contrib/kdoc/src/test/decl.h b/deal.II/contrib/kdoc/src/test/decl.h
new file mode 100644 (file)
index 0000000..dd541fc
--- /dev/null
@@ -0,0 +1,87 @@
+
+const char *bar;
+
+typedef 
+(const char *)
+(Taj::GlobalType, Hi& *) foo;
+
+int sillyVar = 1;
+
+enum Test::FuBar { Test1 = 1,  // Test
+       Test2,          // Also a test
+       Test3,
+       Test4 = 4
+};
+
+/* gringrin
+* multi
+* line \
+  comment
+*/
+
+#include<taj.h>
+#define MY_DEF 1
+
+const char *FuBar( const char *str = "dog", int, 2 )const; 
+
+/**
+* Doc
+* Documentation.
+* 
+* What does it mean to write class documentation? Is it something naughty?
+*
+* Is it something nice?
+* @li Maybe
+* @li Maybe not. Maybe if we wrote lots of text here, it would make it into
+*      the list we have got here.
+* @li Perhaps.
+*
+* Or should it be something that we'll never ever do if we're sober? After
+* all, sobriety is the vice of strife.
+*
+* @li another
+* @li list
+*
+* @see Taj and others.
+* @see Testing
+*
+* @author Taj
+* @version Break
+*/
+template <class T,  // Comment
+       basic_string<T<TWibble>, 2>> 
+class TWibble 
+       : 
+       public normal, 
+       protected templated<T> 
+{
+
+       /**
+       * I believe that I have documentation, and you don't.
+       */
+       virtual const char *retthis( 
+               (TWibble *),            // A pointer thing
+               Test *(test) );         // another one
+
+       struct MyClass {
+               int a;
+               int b;
+               const char *c;
+               void init( int, int, const char * );
+       };
+
+       /** @return a small dog. */
+       const char *doggie() const;
+
+protected:
+       /**
+       * Stufff
+       */
+       int _myVar;
+
+public slots:
+
+       const char *dontRet() const = 0;
+}; /* end of class */
+
+const char *MyVar;
diff --git a/deal.II/contrib/kdoc/src/test/testrelpaths b/deal.II/contrib/kdoc/src/test/testrelpaths
new file mode 100755 (executable)
index 0000000..902b141
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/perl
+
+use kdocUtil;
+
+print kdocUtil::makeRelativePath( $ARGV[0], $ARGV[1] ), "\n";
diff --git a/deal.II/contrib/kdoc/src/test/tweedle.h b/deal.II/contrib/kdoc/src/test/tweedle.h
new file mode 100644 (file)
index 0000000..cefa8bc
--- /dev/null
@@ -0,0 +1,48 @@
+
+/**
+ * @libdoc The Battle of Tweedles Dum and Dee
+ *
+ * Tweedledum 
+ * and Tweedledee
+ * agreed to have a battle,
+ * for Tweedledum 
+ * said TweedleDee
+ * had spoilt his nice new rattle.
+ *
+ * @defgroup animate   Animate Objects
+ * @defgroup inanimate Inanimate Objects.
+ * 
+ */
+
+/**
+ * @group inanimate
+ */
+template <class T>
+class Rattle {
+public:
+       class Prop {
+               vector<int> colours;
+               map<T, string> hums, rattles;
+       };
+               
+       virtual int battle() const;
+};
+
+/**
+ * @group animate
+ */
+class Dum : public Rattle<int>::Prop {
+public:
+       /** You stole it! */
+       virtual int battle() const;
+};
+
+/**
+ * The younger brother.
+ * @group animate
+ */
+class Dee : public Rattle, map<int, int *>::iterator {
+public:
+       /** Did not! */
+       virtual int battle() const;
+};

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.