From a772f8d62568bb11ab56e5610e004cd8e06b0c2f Mon Sep 17 00:00:00 2001 From: wolf Date: Wed, 21 Jun 2000 12:33:53 +0000 Subject: [PATCH] Import kdoc snapshot 2.a35 git-svn-id: https://svn.dealii.org/trunk@3041 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/contrib/kdoc/src/Ast.pm | 91 ++ deal.II/contrib/kdoc/src/Iter.pm | 500 ++++++++ deal.II/contrib/kdoc/src/Makefile.cvs | 5 + deal.II/contrib/kdoc/src/Makefile.in | 67 + deal.II/contrib/kdoc/src/README | 58 + deal.II/contrib/kdoc/src/TODO | 82 ++ deal.II/contrib/kdoc/src/Version | 1 + deal.II/contrib/kdoc/src/config.log | 3 + deal.II/contrib/kdoc/src/configure | 891 +++++++++++++ deal.II/contrib/kdoc/src/configure.in | 35 + deal.II/contrib/kdoc/src/debian/changelog | 27 + deal.II/contrib/kdoc/src/debian/control | 16 + deal.II/contrib/kdoc/src/debian/copyright | 7 + deal.II/contrib/kdoc/src/debian/postinst | 30 + deal.II/contrib/kdoc/src/debian/postrm | 26 + deal.II/contrib/kdoc/src/debian/preinst | 28 + deal.II/contrib/kdoc/src/debian/prerm | 26 + deal.II/contrib/kdoc/src/debian/rules | 52 + deal.II/contrib/kdoc/src/doc/DESIGN | 124 ++ deal.II/contrib/kdoc/src/doc/Makefile.in | 46 + deal.II/contrib/kdoc/src/doc/kdoc.docbook | 444 +++++++ deal.II/contrib/kdoc/src/doc/kdoc.pod | 203 +++ deal.II/contrib/kdoc/src/findperl | 17 + deal.II/contrib/kdoc/src/install-sh | 251 ++++ deal.II/contrib/kdoc/src/kdoc | 1335 ++++++++++++++++++++ deal.II/contrib/kdoc/src/kdocAstUtil.pm | 754 +++++++++++ deal.II/contrib/kdoc/src/kdocCxxDocbook.pm | 771 +++++++++++ deal.II/contrib/kdoc/src/kdocCxxHTML.pm | 848 +++++++++++++ deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm | 1232 ++++++++++++++++++ deal.II/contrib/kdoc/src/kdocDocHelper.pm | 78 ++ deal.II/contrib/kdoc/src/kdocHTMLutil.pm | 703 +++++++++++ deal.II/contrib/kdoc/src/kdocIDLhtml.pm | 745 +++++++++++ deal.II/contrib/kdoc/src/kdocLib.pm | 301 +++++ deal.II/contrib/kdoc/src/kdocParseDoc.pm | 414 ++++++ deal.II/contrib/kdoc/src/kdocTeX.pm | 292 +++++ deal.II/contrib/kdoc/src/kdocUtil.pm | 140 ++ deal.II/contrib/kdoc/src/kdoctexi.pm | 595 +++++++++ deal.II/contrib/kdoc/src/makekdedoc | 302 +++++ deal.II/contrib/kdoc/src/qt2kdoc | 232 ++++ deal.II/contrib/kdoc/src/test/decl.h | 87 ++ deal.II/contrib/kdoc/src/test/testrelpaths | 5 + deal.II/contrib/kdoc/src/test/tweedle.h | 48 + 42 files changed, 11912 insertions(+) create mode 100644 deal.II/contrib/kdoc/src/Ast.pm create mode 100644 deal.II/contrib/kdoc/src/Iter.pm create mode 100644 deal.II/contrib/kdoc/src/Makefile.cvs create mode 100644 deal.II/contrib/kdoc/src/Makefile.in create mode 100644 deal.II/contrib/kdoc/src/README create mode 100644 deal.II/contrib/kdoc/src/TODO create mode 100644 deal.II/contrib/kdoc/src/Version create mode 100644 deal.II/contrib/kdoc/src/config.log create mode 100755 deal.II/contrib/kdoc/src/configure create mode 100644 deal.II/contrib/kdoc/src/configure.in create mode 100644 deal.II/contrib/kdoc/src/debian/changelog create mode 100644 deal.II/contrib/kdoc/src/debian/control create mode 100644 deal.II/contrib/kdoc/src/debian/copyright create mode 100644 deal.II/contrib/kdoc/src/debian/postinst create mode 100644 deal.II/contrib/kdoc/src/debian/postrm create mode 100644 deal.II/contrib/kdoc/src/debian/preinst create mode 100644 deal.II/contrib/kdoc/src/debian/prerm create mode 100755 deal.II/contrib/kdoc/src/debian/rules create mode 100644 deal.II/contrib/kdoc/src/doc/DESIGN create mode 100644 deal.II/contrib/kdoc/src/doc/Makefile.in create mode 100644 deal.II/contrib/kdoc/src/doc/kdoc.docbook create mode 100644 deal.II/contrib/kdoc/src/doc/kdoc.pod create mode 100755 deal.II/contrib/kdoc/src/findperl create mode 100755 deal.II/contrib/kdoc/src/install-sh create mode 100755 deal.II/contrib/kdoc/src/kdoc create mode 100644 deal.II/contrib/kdoc/src/kdocAstUtil.pm create mode 100644 deal.II/contrib/kdoc/src/kdocCxxDocbook.pm create mode 100644 deal.II/contrib/kdoc/src/kdocCxxHTML.pm create mode 100644 deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm create mode 100644 deal.II/contrib/kdoc/src/kdocDocHelper.pm create mode 100644 deal.II/contrib/kdoc/src/kdocHTMLutil.pm create mode 100644 deal.II/contrib/kdoc/src/kdocIDLhtml.pm create mode 100644 deal.II/contrib/kdoc/src/kdocLib.pm create mode 100644 deal.II/contrib/kdoc/src/kdocParseDoc.pm create mode 100644 deal.II/contrib/kdoc/src/kdocTeX.pm create mode 100644 deal.II/contrib/kdoc/src/kdocUtil.pm create mode 100644 deal.II/contrib/kdoc/src/kdoctexi.pm create mode 100755 deal.II/contrib/kdoc/src/makekdedoc create mode 100755 deal.II/contrib/kdoc/src/qt2kdoc create mode 100644 deal.II/contrib/kdoc/src/test/decl.h create mode 100755 deal.II/contrib/kdoc/src/test/testrelpaths create mode 100644 deal.II/contrib/kdoc/src/test/tweedle.h diff --git a/deal.II/contrib/kdoc/src/Ast.pm b/deal.II/contrib/kdoc/src/Ast.pm new file mode 100644 index 0000000000..0fb4bd0d4e --- /dev/null +++ b/deal.II/contrib/kdoc/src/Ast.pm @@ -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 index 0000000000..337825ddad --- /dev/null +++ b/deal.II/contrib/kdoc/src/Iter.pm @@ -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 index 0000000000..3c0d806312 --- /dev/null +++ b/deal.II/contrib/kdoc/src/Makefile.cvs @@ -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 index 0000000000..6b1a433dae --- /dev/null +++ b/deal.II/contrib/kdoc/src/Makefile.in @@ -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 index 0000000000..af8cded481 --- /dev/null +++ b/deal.II/contrib/kdoc/src/README @@ -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 +Distributed under the GPL. diff --git a/deal.II/contrib/kdoc/src/TODO b/deal.II/contrib/kdoc/src/TODO new file mode 100644 index 0000000000..1f27b7d1b4 --- /dev/null +++ b/deal.II/contrib/kdoc/src/TODO @@ -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 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 index 0000000000..9b3dad19f9 --- /dev/null +++ b/deal.II/contrib/kdoc/src/Version @@ -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 index 0000000000..fb9038e996 --- /dev/null +++ b/deal.II/contrib/kdoc/src/config.log @@ -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 index 0000000000..69fdb8ebac --- /dev/null +++ b/deal.II/contrib/kdoc/src/configure @@ -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 </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 < 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 <> $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 <> $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 index 0000000000..9c926e5071 --- /dev/null +++ b/deal.II/contrib/kdoc/src/configure.in @@ -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 index 0000000000..71a274e592 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/changelog @@ -0,0 +1,27 @@ +kdoc (2.0a15-1.0) unstable; urgency=low + + * New upstream version + + -- Ivan E. Moore II Wed, 13 Oct 1999 23:30:06 -0400 + +kdoc (2.0a12-1.0) unstable; urgency=low + + * New upstream version + + -- Ivan E. Moore II Mon, 27 Sep 1999 23:30:06 -0400 + +kdoc (2.0a9-2) unstable; urgency=low + + * Use DESTDIR for 'make install' + + -- Bernd Gehrmann Sat, 22 May 1999 18:30:06 +0200 + +kdoc (2.0a9-1) experimental; urgency=low + + * Initial Release. + + -- Bernd Gehrmann 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 index 0000000000..a430a44988 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/control @@ -0,0 +1,16 @@ +Source: kdoc +Section: devel +Priority: optional +Maintainer: Bernd Gehrmann +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 index 0000000000..8af64498d4 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/copyright @@ -0,0 +1,7 @@ +This package was debianized by Bernd Gehrmann + +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 index 0000000000..df575f1c6a --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/postinst @@ -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 index 0000000000..f8aa6ec5d6 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/postrm @@ -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 index 0000000000..fe9d7aef61 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/preinst @@ -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 index 0000000000..5ba573f34e --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/prerm @@ -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 index 0000000000..8e7b7271a0 --- /dev/null +++ b/deal.II/contrib/kdoc/src/debian/rules @@ -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 index 0000000000..7038d3de73 --- /dev/null +++ b/deal.II/contrib/kdoc/src/doc/DESIGN @@ -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 diff --git a/deal.II/contrib/kdoc/src/doc/Makefile.in b/deal.II/contrib/kdoc/src/doc/Makefile.in new file mode 100644 index 0000000000..955d049a08 --- /dev/null +++ b/deal.II/contrib/kdoc/src/doc/Makefile.in @@ -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 index 0000000000..4ed20179ce --- /dev/null +++ b/deal.II/contrib/kdoc/src/doc/kdoc.docbook @@ -0,0 +1,444 @@ + + + + + + + +The KDOC Handbook +Write developer documentation, easily and quickly + + + +Sirtaj +Singh +Kang + + +
+taj@kde.org +
+ + +KDOC +C++ +C +KDE Libraries +Documentation +API +Literate Programming + + +10/11/1999 +2.0.0 + + + +0.1 +10/11/1999 +S.S.K + + + + + + + + KDOC generates documentation in a +variety of formats, directly from C, C++ and IDL interface definitions. +KDOC uses specially formatted comments in +the source to allow customized documentation. + + + +
+ + + + Introduction + + + What is KDOC? + KDOC generates documentation in a +variety of formats, directly from C, C++ and IDL interface definitions. +KDOC uses specially formatted comments in +the source to allow customized documentation. + +It is also very useful as a general class browser for libraries, +since the output is quickly navigable and many index views are +presented. + +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 COPYING +that comes with the distribution for the full text version of the +license. + + + + Features + + Support for C, C++ and OMG CORBA IDL languages. + + + Output in HTML, LaTeX, Manpage, Texinfo and + DocBook SGML formats. The DocBook format can in turn be + converted to various printable and online formats. + + + Automatically works out many relationships + between objects and their properties, such as hierarchies, + overridden virtuals, non-instantiable (abstract) classes and more. + + + Doc Comments are written in the javadoc style, + with many useful extensions for organizing, documenting + and presenting libraries. + + + Supports a CPP (preprocessor) pass + via an external preprocessor, to expand macros and + #ifdefs. + + Support for the Qt GUI Toolkit's signal and + slot specifiers. + + Cross-reference documentation generated for other + libraries. Links and class hierarchies that reference external + libraries are correctly shown. + + Includes makekdedoc, + an easy automake-like tool for generating documentation for + multiple libraries at once. + + Includes qt2kdoc, + which allows you to link your documentation with the Qt GUI + Toolkit's HTML documentation as if it had been generated by + KDOC itself. + + + An output mode that allows you to check for + errors or omissions in your documentation. + The application is written entirely in Perl, and + is therefore quite portable and extensible. + + + + + + History +Torben Weis weis@kde.org 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. + +Sirtaj Singh Kang taj@kde.org 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%. + +KDOC 1.0 still used some of Torben's source, but never really +worked properly but was useful enough for a year or so. + +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. + + + + + + + + Using KDOC + + + Support and Downloads + + + + +Web page +KDOC has a web page at +http://www.ph.unimelb.edu.au/~ssk/kde/kdoc/. +It can be downloaded from there. + + + + +Via KDE CVS or CVSUp +You can checkout KDOC from the KDE CVS server in the module +kdoc. This is the repository used for KDOC development, +so it will always be up to date. + + + + +Mailing List +There is a KDOC mailing list hosted by the KDE project, at +kdoc-list@kde.org. To subscribe, mail +kdoc-list-request@kde.org +with subscribe in the message body (not the subject). + + + +The KDOC FAQ + +The KDOC FAQ has answers to common questions and problems with KDOC. + + + + +E-mail: The Last Resort +If all else fails, I will respond to decent questions via +email, but I cannot promise prompt replies. Mail the KDOC "team" at +kdoc@kde.org. + + + + + + + Installation + +Supported Environments +KDOC requires Perl 5.004 to function. +Most environments where this is installed are supported by KDOC. + +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. + + + + Building the distribution + +The procedure for building KDOC is similar to most other GPL programs that +come with a configure script. + + + +Unpack the distribution +Unpack the distribution into a temporary directory. It will extract +itself into its own directory. If you have downloaded the tar.bz2 version: + +# bunzip2 < kdoc-2.0a1.tar.bz2 | tar xf - + + +Or if you have downloaded the tar.gz version: + +# gunzip < kdoc-2.0a1.tar.gz | tar xf - + + +Replace the distribution file name in the above procedure with the one +you have downloaded. + + +Build the application +This will configure KDOC to install itself in +/usr/local/: + +# cd kdoc-2.0a1 +# ./configure + + +To install it in a different directory, +say /opt/kdoc, add a prefix option to configure like this: + +# ./configure --prefix=/opt/kdoc + + + + +Perform the installation + +# make; make install + + + +Remove the temporary directory + +# cd .. +# rm -rf kdoc-2.0a1 + + + +Now kdoc should be installed on your system. + + + + + KDOC at the command line + +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. + + + + + + + + Writing Documentation +Commenting Source +TODO: Explain doc comments. Explain tags. Examples. + + + Tips on Style +TODO: Various doc suggestions: internal/deprecated, short +descriptions, link to Qt documentation guidelines. + + + + + Frequently Asked Questions +TODO: No questions, no answers. + + + + Appendix A: Doc tag reference + + Doc Comments + TODO + + + Common tags + + + @li <text> + A list item. + + + @internal + Mark member as internal to the + library and not for external use. + + + @deprecated + Marks member as obsolete. + + + @version <string> + Provide version information about the + member. I normally set this to the RCS/CVS Id tag. + + + + @author <string> + Specify the author. + + + @since <string> + Specify the version of the API in which this + member was added. + + + @sect <string> + A section heading, for grouping your doc + comment logically. + + + <pre> text </pre> + A block of literal (preformatted) text, + useful for code examples. + + + @image <path> + 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. + + + @see <ref>,... + Links to related information. + + + @ref <ref> + 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. + + + + + + Tags for Library Documentation + 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. + + + + @libdoc <string> + Marks a doc comment as documentation for + the library. The string is used as the title of the + library. + + + + + + Tags for Classes + + + + @short <string> + Short description of the class, one + sentence long. + If class documentation is present but no short + description is specified, the first sentence (up to and + including the first period) is used instead. + + + + + + + Tags for Functions + + + @param <paramname> <text> + Documentation for a parameter. + No check is done whether the parameter name specified + is actually a parameter of the function. + + + + @return <text> + Documentation for the value returned by + the function. + + + @throws <ref>,... + Define the exceptions that may be thrown + from this function. Synonyms are: @exception and @raises. + + + + @param <paramname> <text> + Documentation for a parameter. + No check is done whether the parameter name specified + is actually a parameter of the function. + + + + + + +Appendix B: Utilities +qt2kdoc: Link with Qt HTML documentation + +makekdedoc: Generate docs for KDELIBS and other groups of libraries + + + +Appendix B: Other useful tools + +
diff --git a/deal.II/contrib/kdoc/src/doc/kdoc.pod b/deal.II/contrib/kdoc/src/doc/kdoc.pod new file mode 100644 index 0000000000..b784557f2c --- /dev/null +++ b/deal.II/contrib/kdoc/src/doc/kdoc.pod @@ -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> , B<-f> + +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> , B<-d> + +Write output in the specified path. + +=item B<--url> , B<-u> + +The URL which will be used for links when cross-referencing with this library. + +=item B<--name> , B<-n> + +Set the name of the library being processed, eg "kdecore" +If no name is set, no index file is produced. + +=item B<--xref> , B<-l> + +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> , B<-L> + +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> , B<-C> + +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> , B<-I> + +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 + +Output documentation in HTML format. This is the default. + +=item B + +Output documentation as a LaTeX document. (unimplemented) + +=item B + +Output documentation as man pages. (unimplemented) + +=item B + +Output documentation in texinfo format. You must set the library name +with the B<-n> option for the output to be generated. + +=item B + +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 + +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 + +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 for info on linking with the Qt docs, and L for +info on generating documentation for the KDE libraries. + +=head1 BUGS + +Lots and Lots. Please send reports to the address B. + +=head1 AUTHOR + +Sirtaj Singh Kang . B 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 index 0000000000..451758d710 --- /dev/null +++ b/deal.II/contrib/kdoc/src/findperl @@ -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 index 0000000000..e9de23842d --- /dev/null +++ b/deal.II/contrib/kdoc/src/install-sh @@ -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 index 0000000000..b7c0ca2c54 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdoc @@ -0,0 +1,1335 @@ +#!/usr/local/bin/perl + +# KDOC -- C++ and CORBA IDL interface documentation tool. +# Sirtaj Singh Kang , 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 , 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 () { + 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 ; +} + +=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 = ); + + $p =~ s#//.*$##g; # C++ comment + $p =~ s#/\*(?!\*).*?\*/##g; # C comment + + # join all multiline comments + if( $p =~ m#/\*(?!\*)#s ) { + # unterminated comment +LOOP: + while( defined ($l = ) ) { + $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( ) { + last if(/\"$currentfile\"/); + print "Overread $_" if $debug; + }; + print "Cont: $_" if $debug; + } + else { + # multiline macros + while ( defined $p && $p =~ m#\\\s*$# ) { + $p = ; + } + } + 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 { ..." 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<\n"; +} + + diff --git a/deal.II/contrib/kdoc/src/kdocAstUtil.pm b/deal.II/contrib/kdoc/src/kdocAstUtil.pm new file mode 100644 index 0000000000..40e1238f54 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocAstUtil.pm @@ -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 index 0000000000..57fea4fdd5 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocCxxDocbook.pm @@ -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< + + + $time + $lib API Documentation + +EOF + + printLibDoc(); + printHierarchy(); + printClassIndex(); + printClassDoc(); + +print DOC< +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 "\n"; + }, + sub { # print + my $node = shift; + return if $node == $rootnode; + + my $src = defined $node->{ExtSource} ? " ($node->{ExtSource})":""; + print DOC "", refName($node), "$src\n" + }, + sub { # up + if ( $_[0] == $rootnode ) { + print DOC "\n"; + } + else { + print DOC "\n"; + } + }, + sub { print DOC ""; } + ); + + 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 "\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(),"{Path}, "\">"; + } + elsif ( $type eq "ListItem" ) { + if ( $lasttype ne "ListItem" ) { + print CLASS "", pc(),"\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(), ""; + } + + 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 "", esc($pnode->{Name}), + "", + deref($pnode->{astNodeName}, $rootnode ), + "\n"; + } + print CLASS "", C( "TBody", "TGroup", "Table" ); + } + + # Return + printTextItem( $docNode, *CLASS, "Returns" ); + + # Exceptions + $text = $docNode->{Throws}; + + if ( defined $text ) { + my $comma = "Exceptions"; + + 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 "", $label, " ", + deref( $text, $rootnode ), "\n"; +} + + +# utilities + + +sub refName +{ + my( $node ) = @_; + + return fullName( $node ) if defined $node->{ExtSource} + || !kdocAstUtil::hasDoc( $node ); + + return ''; +} + +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/&/&/g; + $str =~ s//>/g; + + return $str; +} + + +sub chapter +{ + my ( $id, $title ) = @_; + + return "$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( "", @_ ).""; +} + + +=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 .= ""; + } + + return $out; +} + +sub po +{ + my $text = $paraOpen ? "" : ""; + $paraOpen = 1; + + return $text; +} + +sub pc +{ + my $text = $paraOpen ? "" : ""; + $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 index 0000000000..2b2d0b35d2 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocCxxHTML.pm @@ -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 =< + + +
Generated by: $gentext
+ + +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 "

No classes

"; + # 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 ''; + + 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 .= " (internal)"; + } + if ( defined $docnode->{Deprecated} ) { + $short .= " (deprecated)"; + } + } + + $col = $col ? 0 : 1; + $colour = $col ? "" : 'bgcolor="#eeeeee"'; + + print CLIST ""; + } + + print CLIST "
", refNameFull( $node ), + "", $short, "
", $docBotty; + close CLIST; +} + + +=head2 writeAllMembers + + Parameters: node + + Writes a list of all methods to "full-list-" + +=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" ), "
    "; + + 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 "
      "; + }, + sub { # print + my ( $node ) = @_; + return if $node == $rootnode; + + my $src = defined $node->{ExtSource} ? + " ($node->{ExtSource})" : ""; + + print HIER "
    • ", refNameFull( $node )," $src\n"; + }, + sub { # up + if ( $_[0] == $root ) { + print HIER "
    \n"; + } + else { + print HIER "
\n"; + } + }, + sub { print HIER "\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 "\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). + " ". + hyper( "#longdesc", "More..." ).""; + } + + if ( exists $docnode->{Deprecated} ) { + $extra .= ''. + 'Deprecated! use with care'; + } + + if ( exists $docnode->{Internal} ) { + $extra .= ''. + 'Internal Use Only'; + + } + $version = esc($docnode->{Version}) + if exists $docnode->{Version}; + $author = esc($docnode->{Author}) + if exists $docnode->{Author}; + } + + # pure virtual check + if ( exists $node->{Pure} ) { + $extra .= '' + .'Contains pure virtuals'; + } + + # full name, if not in global scope + if ( $node->{Parent} != $rootnode ) { + $extra .= tabRow( "Full name", + "".refNameEvery( $node, $rootnode )."" ); + } + + # include (not for namespaces) + if ( $node->{NodeType} ne "namespace" + && $node->{NodeType} ne "Forward" ) { + $extra .= tabRow( 'Definition', '#include <'. + refName( $node->{Source} ).'>' ); + } + + # template form + if ( exists $node->{Tmpl} ) { + $extra .= tabRow( "Template form", + esc($node->{astNodeName}) + ."<".textRef($node->{Tmpl}, $rootnode )."> " + ."" ); + } + + + 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 .= " <".wordRef($template, $rootnode ).">" + unless !defined $template; + + if ( exists $ances->{ExtSource} ) { + $out .=" (".$ances->{ExtSource} + .")"; + } + + $out .= " [$type]" + 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 .= " (". + $in->{ExtSource}.")"; + } + + $comma = ", "; + + }, + sub { # end + $extra .= tabRow( "Inherited by", $out ); + } + ); + + $extra .= ''. + hyper( encodeURL("full-list-".$node->{Ref}), + "List of all Methods" ).""; + + + #### print it + + newPgHeader( *CLASS{IO}, + $node->{NodeType}." ".esc($node->{astNodeName}), + $short, $extra, \%toclinks ); + + + if( $#{$node->{Kids}} < 0 ) { + print CLASS "

No members

\n"; + } + else { + Iter::MembersByType ( $node, + sub { print CLASS "

", $_[0], "

    "; }, + sub { my ($node, $kid ) = @_; + listMember( $node, $kid ); }, + sub { print CLASS "
"; } + ); + } + + # long description + if ( kdocAstUtil::hasDoc( $node ) ) { + print CLASS "
", + "

Detailed Description

"; + 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 "

Reimplemented from ", + refName( $ref ), "

\n"; + } + } + + return; + } + ); + + # done + + if ( defined $version || defined $author ) { + print CLASS "
    ", + defined $version ? + "
  • Version: $version
  • " : "", + defined $author ? + "
  • Author: $author
  • " : "", + "
  • Generated: $gentext
", + "\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 "

#include <", + refName( $source ), + ">

"; + + 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 "
  • "; + + 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 ), + "\ $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 "
  • \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<$desc +
      +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 "
    • "; + + 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 = "$name" if $flags =~ /p/; + my $extra = ""; + $extra .= "virtual " if $flags =~ "v"; + $extra .= "static " if $flags =~ "s"; + + print CLASS $extra, textRef($m->{ReturnType}, $rootnode), + "\ $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 "
    • \n"; + } + +print CLASS< +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 "
      "; + } + + print CLASS '
      '; + + if( $type eq "var" ) { + print CLASS textRef($m->{Type}, $rootnode ), " $name\n"; + } + elsif( $type eq "method" ) { + $flags = $m->{Flags}; + $name = "$name" if $flags =~ /p/; + + print CLASS textRef($m->{ReturnType}, $rootnode ), + "\ $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 "

      "; + +# 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 " [", join( " ", @extra ), "]"; + } + + print CLASS "

      "; + + 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 index 0000000000..8bbcca18c6 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocCxxLaTeX.pm @@ -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 <{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 ""; + + print CLIST ""; + + for $ctr ( $start..$stop ) { + print CLIST "\n"; + } + + print CLIST "
      ", + esc( $list->[ $start ]->{astNodeName} ), + " - ", esc( $list->[ $stop ]->{astNodeName} ), + "
      ", refName( $list->[ $ctr ] ), + "
      "; +} + + +=head2 writeAllMembers + + Parameters: node + + Writes a list of all methods to "full-list-" + +=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) ), + "
        "; + + my $mem; + foreach $mem ( sort keys %allmem ) { + my $parentName = $allmem{$mem}->{Parent}->{astNodeName}; + print ALLMEM "
      • "; + print ALLMEM refName( $allmem{ $mem } ); + if($parentName ne $thisClassName) { + print ALLMEM " [$parentName]" + } + print ALLMEM "
      • \n"; + } + + print ALLMEM "
      $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" ), "
        \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
      • ",hyper($_.".html",$header),"
      • \n"; + } + + print HDRIDX "
      \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 = "Dokumentacja $lib". + ""; + } + + return <{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 <{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<{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<{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 < ) + { + 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 <$outputdir/main.tex") + || die "Couldn't create $outputdir/main.tex\n"; + + print MAIN </\\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 = ''. +# esc($node->{astNodeName}).''; +# } + + $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 < 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 "".esc($_[1]).""; + 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 index 0000000000..f549a9d0a5 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocDocHelper.pm @@ -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 index 0000000000..76f6edc68c --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocHTMLutil.pm @@ -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 < + +$heading + + + + + + +EOF + +# print $html '
      + + + +
      +

      $heading

      +
      $desc
      +
      + + $rest +
      +
      '; + my @klist = keys %$toclist; + + print $html ''; + + # image + print $html '' + if defined $main::options{"html-logo"}; + + # TOC + + foreach my $item ( sort @klist ) { + print $html '\n"; + } + + print $html "
      ', + '', + $item, "
      \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 ''; + + while ( $ctr <= $#$list ) { + print $file '"; + $ctr = $s+1; + } + + print $file '
      '; + $s = $ctr+$size-1; + + if ( $s > $#$list ) { + $s = $#$list; + } + elsif ( ($#$list - $s) < $columns) { + $s = $#$list; + } + + writeListPart( $file, $list, $ctr, $s ); + print $file "
      '; +} + +=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 ""; + + print $file '"; + + my $col = 0; + my $colour = ""; + + for my $ctr ( $start..$stop ) { + $col = $col ? 0 : 1; + $colour = $col ? "" : 'bgcolor="#eeeeee"'; + + print $file "\n"; + } + + print $file "
      ', + esc( $list->[ $start ]->{astNodeName} ), + " - ", esc( $list->[ $stop ]->{astNodeName} ), + "
      ", refNameFull( $list->[ $ctr ] ), + "
      "; +} + + +=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 = "".$out."" 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 = "".$out."" 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 "".esc($_[1]).""; +} + + +sub B +{ + my $tag = shift; + + return "<$tag>". join( "", @_). ""; +} + +=head2 esc + + Escape special HTML characters. + +=cut + +sub esc +{ + my $str = $_[ 0 ]; + + return "" if !defined $str || $str eq ""; + + $str =~ s/&/&/g; + $str =~ s//>/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 "

      ", + deref( $docNode->{Main}, $rootnode ), "

      \n"; + } + + my $text = $docNode->{Text}; + + if ( defined $text ) { + print CLASS "

      "; + + 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 "

    \n"; + } + + if( $type eq "DocText" ) { + print CLASS "", deref( $name, $rootnode ); + } + elsif ( $type eq "Pre" ) { + print CLASS "

    \n",
    +					esc( $name ), "\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 "DocSection" ) { + print CLASS "

    ", + deref( $name, $rootnode),"

    "; + } + elsif ( $type eq "Image" ) { + print CLASS "

    {Path}, "\">

    "; + } + elsif ( $type eq "ParaBreak" ) { + print CLASS "

    "; + } + elsif ( $type eq "ListItem" ) { + if ( $lasttype ne "ListItem" ) { + print CLASS "

      \n"; + } + print CLASS "
    • ", + deref( $name, $rootnode ), "
    • \n"; + } + + $lasttype = $type; + } + + if( $type eq "ListItem" ) { + print CLASS "

    \n"; + } + + print CLASS "

    "; + + } + + + # Params + my @paramlist = (); + kdocAstUtil::findNodes( \@paramlist, $docNode->{Text}, + "NodeType", "Param" ); + + if( $#paramlist >= 0 ) { + my $pnode; + print CLASS "

    Parameters:", + "\n"; + + foreach $pnode ( @paramlist ) { + print CLASS "\n"; + } + print CLASS "
    ", + esc($pnode->{Name}), + "", + deref($pnode->{astNodeName}, $rootnode ), + "

    \n"; + } + + # Return + printTextItem( $docNode, *CLASS, "Returns" ); + + # Exceptions + $text = $docNode->{Throws}; + + if ( defined $text ) { + my $comma = "

    Throws: "; + + foreach my $tosee ( @$text ) { + print CLASS $comma, esc( $tosee ); + $comma = ", "; + } + print CLASS "

    \n"; + } + + # See + my $comma = ""; + + Iter::SeeAlso ( $docNode, undef, + sub { # start + print CLASS "

    See also: "; + }, + sub { # print + my ( $label, $ref ) = @_; + $label = defined $ref ? refName( $ref ): esc( $label ); + + print CLASS $comma, $label; + $comma = ", "; + }, + sub { # end + print CLASS "

    \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 "

    ", $label, ": ", + deref( $text, $rootnode ), "

    \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 .= "".esc($1).""; + } + elsif ( $text =~/\@em\s+(\w+)/ ) { # emphasized + $out .= "".esc($1).""; + } + 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//%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 "$_[0]$_[1]\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 "
    \n";
    +
    +	while (  ) {
    +		print $out esc( $_ );
    +	}
    +
    +	print $out "
    \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 index 0000000000..a7b73f2020 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocIDLhtml.pm @@ -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 =< + + +
    Generated by: $gentext
    + + +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" ), + "\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 ""; + } + + print CLIST "
    ", refName( $node ), + "", $short, "
    ", $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" ), + "\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 ""; + my $s; + + while ( $ctr <= $#clist ) { + print CLIST ""; + $ctr = $s+1; + } + + print CLIST< +
    "; + $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 "
    +$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 ""; + + print CLIST ""; + + for $ctr ( $start..$stop ) { + print CLIST "\n"; + } + + print CLIST "
    ", + esc( $list->[ $start ]->{astNodeName} ), + " - ", esc( $list->[ $stop ]->{astNodeName} ), + "
    ", refName( $list->[ $ctr ] ), + "
    "; +} + + +=head2 writeAllMembers + + Parameters: node + + Writes a list of all methods to "full-list-" + +=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" ), + "
      "; + + my $mem; + foreach $mem ( sort keys %allmem ) { + print ALLMEM "
    • ", refName( $allmem{ $mem } ), "
    • \n"; + } + + print ALLMEM "
    $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" ), "
      \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
    • ",hyper($_.".html",$header),"
    • \n"; + } + +print HDRIDX "
    \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 = "$lib documentation". + ""; + } + + return < +$heading + + + + + + + +
    + +$libtext + + + +
    Index
    Annotated List
    Files
    +

    $heading

    $desc

    +
    +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 .= "

    Deprecated: use with care"; + } + + if ( exists $docnode->{Internal} ) { + $short .= "

    Internal use only"; + } + $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 .= + "

    Contains pure virtuals

    "; + } + + # full name + $short .= "

    ".refNameEvery( $node, $rootnode )."

    " + unless $node->{Parent} eq $rootnode; + + # include + $short .= "

    #include <".$source + .">

    "; + + # 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 .= " (".$n->{ExtSource} + .")"; + } + } + else { + $out .= esc( $in->{astNodeName} ); + } + + $comma = ", "; + $last = $in; + } + + $short .= "$out

    " 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 .= " (". + $in->{ExtSource}.")"; + } + + $comma = ", "; + } + $short .= "

    "; + } + + $short .= "".hyper( "#longdesc", "More..." ).""; + + # print it + + print CLASS pageHeader( + $node->{NodeType}." ".esc($node->{astNodeName}), + $short ); + + + # member list + + print CLASS "

    ", hyper( encodeURL("full-list-".$node->{Ref}), + "List of all Methods" ),"

    \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 "

    No members

    \n"; + return; + } + + # long description + if ( $hasdoc ) { + print CLASS "
    ", + "

    Detailed Description

    "; + 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 "

    Reimplemented from ", + refNameFull( $ref, $rootnode ), "

    \n"; + } + } + } + + # done + + if ( defined $version || defined $author ) { + print CLASS "
      ", + defined $version ? + "
    • Version: $version
    • " : "", + defined $author ? + "
    • Author: $author
    • " : "", + "
    • Generated: $gentext
    ", + "\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 "

    No members

    \n"; + return; + } + +print CLASS<$desc +
      +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 "
    • "; + + 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 = "$name" if $flags =~ /p/; + my $extra = ""; + $extra .= "virtual " if $flags =~ "v"; + $extra .= "static " if $flags =~ "s"; + + print CLASS $extra, esc($m->{ReturnType}), + " ", $name, " (", + esc($m->{Params}), ") ", + $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 "
    • \n"; + } + +print CLASS< +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 "
      "; + } + + print CLASS "

      "; + + if( $type eq "var" ) { + print CLASS textRef($m->{Type}, $rootnode ), + " ", $name,"\n"; + } + elsif( $type eq "method" ) { + $flags = $m->{Flags}; + $name = "$name" if $flags =~ /p/; + + print CLASS textRef($m->{ReturnType}, $rootnode ), + " ", $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, " (", + esc($type), ")"; + } + + print CLASS ""; + +# 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 " [", join( " ", @extra ), "]"; + } + + print CLASS "

      "; + +# 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 index 0000000000..d1a09c2a79 --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocLib.pm @@ -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 + ------ + + + + + + + + + + + +=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="".$root->{LibDoc}->{astNodeName}.""; + } + + print LIB< + + + +$lib +$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 "{astNodeName}, + "\" REF=\"$prefix.html\">\n"; + } + else { + print LIB "\n"; + my $stats = $root->{Stats}; + foreach my $stat ( keys %$stats ) { + print LIB "", + $stats->{$stat},"\n"; + } + print LIB "\n"; + } + + if( exists $n->{Ancestors} ) { + my $in; + foreach $in ( @{$n->{Ancestors}} ) { + $in =~ s/\s+//g; + print LIB "\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 "\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( ) { + next if /^\s*$/; + if ( !/^\s*/ ) { + # TODO: what do we do with the version number? + $version = $1; + } + elsif ( // ) { + $root = $rootsub->( $1 ); + $n = $root; + } + elsif ( // ) { + # 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## ) { + # ancestor + kdocAstUtil::newInherit( $n, $1 ); + } + elsif ( m## ) { + # 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 = ; + carp "Empty libfile: $fullpath\n" if !defined $liburl; + $liburl =~ s/\s+//g; + + while( ) { + # 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 index 0000000000..143eccc12b --- /dev/null +++ b/deal.II/contrib/kdoc/src/kdocParseDoc.pm @@ -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*
      /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
      index 0000000000..c41e29623f
      --- /dev/null
      +++ b/deal.II/contrib/kdoc/src/kdocTeX.pm
      @@ -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<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## ) {
      +				$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<{ "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<]+)/\\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
      index 0000000000..a83de6afcf
      --- /dev/null
      +++ b/deal.II/contrib/kdoc/src/kdocUtil.pm
      @@ -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
      index 0000000000..26afb1139c
      --- /dev/null
      +++ b/deal.II/contrib/kdoc/src/kdoctexi.pm
      @@ -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<$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<{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 
        ..
      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//\@emph\{/ig; + $text =~ s/<\/em>/\}/ig; + $text =~ s//\@strong\{/ig; + $text =~ s/<\/strong>/\}/ig; + $text =~ s//\@dfn\{/ig; + $text =~ s/<\/dfn>/\}/ig; + $text =~ s//\@code\{/ig; + $text =~ s/<\/code>/\}/ig; + $text =~ s//\@samp\{/ig; + $text =~ s/<\/samp>/\}/ig; + $text =~ s//\@kbd\{/ig; + $text =~ s/<\/kbd>/\}/ig; + $text =~ s//\@var\{/ig; + $text =~ s/<\/var>/\}/ig; + $text =~ s//\@cite\{/ig; + $text =~ s/<\/cite>/\}/ig; + $text =~ s//\@i\{/ig; + $text =~ s/<\/i>/\}/ig; + $text =~ s//\@b\{/ig; + $text =~ s/<\/b>/\}/ig; + $text =~ s//\@t\{/ig; + $text =~ s/<\/tt>/\}/ig; + + $text =~ s/
      /\@*/ig; + $text =~ s/

      /\n/ig; + $text =~ s/<\/p>//ig; + + $text =~ s/<//g; + $text =~ s/&/&/g; + $text =~ s/ /\@ /g; + $text =~ s/©/\@copyright{}/g; + +# Support for other languages? + $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; + + $text =~ s/^\s*

      \s*$/\@quotation/mig; + $text =~ s/^\s*<\/blockquote>\s*$/\@end quotation/mig; + $text =~ s/^\s*
        \s*$/\@itemize \@bullet/mig; + $text =~ s/^\s*<\/ul>\s*$/\@end itemize/mig; + $text =~ s/^\s*
          \s*$/\@enumerate/mig; + $text =~ s/^\s*<\/ol>\s*$/\@end enumerate/mig; + $text =~ s/^\s*
          \s*$/\@table \@asis/mig; + $text =~ s/^\s*<\/dl>\s*$/\@end table/mig; + $text =~ s/^\s*
        1. /\@item /mig; + $text =~ s/^\s*<\/li>//mig; + $text =~ s/^\s*
          /\@item /mig; + $text =~ s/^\s*<\/dt>//mig; + $text =~ s/^\s*
          //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 index 0000000000..a2a152c130 --- /dev/null +++ b/deal.II/contrib/kdoc/src/makekdedoc @@ -0,0 +1,302 @@ +#!/usr/local/bin/perl + +# makekdedoc -- Generates HTML documentation KDE libraries using KDOC 2. +# Sirtaj Singh Kang 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( ) { + 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< + $ver + +Usage: + $0 [--rule-file=] [--libdir=] + [--outputdir=] [--url=] + [--srcdir=] + [--kdoc=] [...] + + By default all libraries defined by the rule file are + documented. + +Defaults: + rulefile "/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. + +=head1 SYNOPSIS + + makekdedoc [--rule-file=] [--libdir=] + [--outputdir=] [--url=] + [--srcdir=] + [--kdoc=] [...] + + makekdedoc --help + +=head1 DESCRIPTION + +This is a perl script that uses B 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 + +Specify the libraries to document. By default, all libraries defined by +the rule file are documented. + +=item B<--outputdir> , B<-d> + +The directory where the output will be written. [`cwd`/srcdoc] + +=item B<--url> , B<-u> + +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> , B<-r> + +The path to the rule file to use for generating the documentation. +[/kdoc.rules] + +=item B<--libdir> , B<-L> + +The directory in which the KDOC cross-reference files are +stored. [$KDOCLIBS if set, otherwise $HOME/.kdoc] + +=item B<--kdoc> , B<-k> + +The path to the kdoc program. [kdoc] + +=item B<--kdocopt> , B<-p> + +Extra options to be passed to kdoc. + +=item B<--srcdir> , B<-b> + +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 + +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 will be documented then two files +from C will be documented, in the order declared in +C. + +=back + +=head1 SEE ALSO + +See L and L. + +=head1 VERSION + + makekdedoc $Revision$ + +=head1 AUTHOR + +The script and this documentation were written by Sirtaj Singh Kang + in April 1999. + +=cut diff --git a/deal.II/contrib/kdoc/src/qt2kdoc b/deal.II/contrib/kdoc/src/qt2kdoc new file mode 100755 index 0000000000..d66858a247 --- /dev/null +++ b/deal.II/contrib/kdoc/src/qt2kdoc @@ -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 ( ) +{ + if( m#([\w]*)<\/a>/ ) { # "vim..grmbl + $current = $2; + $ref{ $current } = $1; + + if ( $#stack >= 0 ) { + $parent{ $current } .= $stack[ $#stack ].","; + } + } + elsif ( m#
      # ) { + $current = pop @stack; + } +} + +# read all members + +%members = (); +%refs = (); + +$lastmem = undef; + +open( IN, $file."/functions.html" ) + || die "Could not open $file for reading\n"; + +while ( ) { + if ( /^\s*(\w+):/ ) { + # function + $lastmem = $1; + } + elsif ( /^\s*(\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 + +foreach my $current ( sort keys %ref ) { + print OUT '',"\n"; + if ( exists $parent{ $current } ) { + foreach $p ( sort split( ",", $parent{ $current } ) ) { + print OUT '', "\n"; + } + } + + my $m = $members{ $current }; + if( $#{$m} >= 0 ) { + my $r = $refs{ $current }; + for $p ( 0..$#{$m} ) { + print OUT '',"\n"; + } + } + print OUT "\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] [-o] [-z]", + " \n"; + exit 1; +} + +=head1 NAME + +qt2kdoc -- Generates cross-reference file suitable for use with B +from Qt Toolkit HTML documentation. + +=head1 SYNOPSIS + + qt2kdoc [-u URL] [-o ] [-z] + +=head1 DESCRIPTION + +B 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> , B<-u> + +The URL by which the Qt documentation can be accessed. This will +allow other libraries to link to the Qt documentation. + +=item B<--outdir> , B<-o> + +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 + +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, B + +The files from which information about the Qt library is read. They are +parsed by qt2kdoc. + +=item B + +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 , 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 index 0000000000..dd541fcd64 --- /dev/null +++ b/deal.II/contrib/kdoc/src/test/decl.h @@ -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 +#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 , 2>> +class TWibble + : + public normal, + protected templated +{ + + /** + * 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 index 0000000000..902b1414ef --- /dev/null +++ b/deal.II/contrib/kdoc/src/test/testrelpaths @@ -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 index 0000000000..cefa8bc5dd --- /dev/null +++ b/deal.II/contrib/kdoc/src/test/tweedle.h @@ -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 Rattle { +public: + class Prop { + vector colours; + map hums, rattles; + }; + + virtual int battle() const; +}; + +/** + * @group animate + */ +class Dum : public Rattle::Prop { +public: + /** You stole it! */ + virtual int battle() const; +}; + +/** + * The younger brother. + * @group animate + */ +class Dee : public Rattle, map::iterator { +public: + /** Did not! */ + virtual int battle() const; +}; -- 2.39.5