From 75fed7362598edf5a7210505cd38c92821863a39 Mon Sep 17 00:00:00 2001 From: dimitri Date: Thu, 17 May 2001 19:26:02 +0000 Subject: Release-20010517 --- INSTALL | 2 +- README | 2 +- doc/Makefile.in | 7 +- doc/commands.doc | 11 + doc/htmlcmds.doc | 2 + doc/language.tpl | 130 +++++ doc/translator.bat | 4 + doc/translator.pl | 752 ++++++++++++++++++++++++++++ src/Makefile.in | 2 +- src/classdef.cpp | 506 +++++++++++-------- src/classdef.h | 179 +++++-- src/classlist.cpp | 20 +- src/classlist.h | 13 +- src/definition.cpp | 140 ++++-- src/definition.h | 72 +-- src/diagram.cpp | 2 +- src/doc.l | 3 + src/dot.cpp | 194 +++++++- src/doxygen.cpp | 280 ++++++++--- src/doxygen.h | 13 +- src/example.h | 31 +- src/filedef.cpp | 10 +- src/filedef.h | 5 +- src/groupdef.cpp | 83 +--- src/groupdef.h | 6 +- src/index.cpp | 94 ++-- src/language.cpp | 5 + src/latexgen.cpp | 15 +- src/libdoxygen.pro.in | 3 - src/mangen.cpp | 78 ++- src/mangen.h | 5 +- src/memberdef.cpp | 94 ++-- src/memberdef.h | 20 +- src/memberlist.cpp | 2 +- src/membername.h | 14 + src/namespacedef.cpp | 51 +- src/namespacedef.h | 36 +- src/packagedef.cpp | 18 +- src/packagedef.h | 4 +- src/rtfgen.cpp | 15 +- src/scanner.l | 23 +- src/sortdict.h | 29 ++ src/translator_cz.h | 4 +- src/translator_dk.h | 1309 +++++++++++++++++++++++++++++++++++++++++++++++++ src/translator_en.h | 28 +- src/translator_it.h | 399 ++++++++++++--- src/translator_ru.h | 108 +++- src/util.cpp | 94 +++- src/util.h | 10 +- 49 files changed, 4161 insertions(+), 766 deletions(-) create mode 100644 doc/language.tpl create mode 100644 doc/translator.bat create mode 100644 doc/translator.pl create mode 100644 src/translator_dk.h diff --git a/INSTALL b/INSTALL index 1343964..f249373 100644 --- a/INSTALL +++ b/INSTALL @@ -3,4 +3,4 @@ DOXYGEN Version 1.2.7 Please read the installation section of the manual for instructions. -------- -Dimitri van Heesch (30 April 2001) +Dimitri van Heesch (17 May 2001) diff --git a/README b/README index 28fc233..99836b4 100644 --- a/README +++ b/README @@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at Enjoy, -Dimitri van Heesch (30 April 2001) +Dimitri van Heesch (17 May 2001) diff --git a/doc/Makefile.in b/doc/Makefile.in index b3186ac..1c7a664 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -12,7 +12,7 @@ # Documents produced by Doxygen are derivative works derived from the # input used in their production; they are not affected by this license. -all: FORCE +all: language.doc FORCE DOXYGEN_DOCDIR=$(DOXYDOCS); \ export DOXYGEN_DOCDIR; \ VERSION=$(VERSION) ; \ @@ -26,6 +26,9 @@ all: FORCE @cp doxygen_logo.eps ../latex clean: - rm -rf ../html ../latex + rm -rf ../html ../latex language.doc + +language.doc: language.tpl FORCE + $(PERL) translator.pl FORCE: diff --git a/doc/commands.doc b/doc/commands.doc index bdbbbae..a3b89e7 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -86,6 +86,7 @@ documentation:
  • \refitem cmdingroup \ingroup
  • \refitem cmdinternal \internal
  • \refitem cmdinvariant \invariant +
  • \refitem cmdinterface \interface
  • \refitem cmdlatexonly \latexonly
  • \refitem cmdli \li
  • \refitem cmdline \line @@ -350,6 +351,16 @@ Doxygen. Unrecognized commands are treated as normal text. \sa section \ref cmddefgroup "\\defgroup".
    +\subsection cmdinterface \interface + + \addindex \interface + Indicates that a comment block contains documentation for an + interface with name \. The arguments are equal to the \\class + command. + + \sa section \ref cmdclass "\\class". + +
    \subsection cmdinternal \internal \addindex \internal diff --git a/doc/htmlcmds.doc b/doc/htmlcmds.doc index 7e7f4b6..0429139 100644 --- a/doc/htmlcmds.doc +++ b/doc/htmlcmds.doc @@ -83,6 +83,8 @@ documentation. Note that all attributes of a HTML tag are ignored
  • \c Does not generate any output.
  • \c Starts a piece of text displayed in a typewriter font.
  • \c Ends a \c section. +
  • \c Starts a piece of text displayed in a typewriter font. +
  • \c Ends a \c section.
  • \c
      Starts an unnumbered item list.
    • \c
    Ends an unnumbered item list.
  • \c Starts a piece of text displayed in an italic font. diff --git a/doc/language.tpl b/doc/language.tpl new file mode 100644 index 0000000..f7eb542 --- /dev/null +++ b/doc/language.tpl @@ -0,0 +1,130 @@ +/****************************************************************************** + * This is the template for generating language.doc. Edit this file, + * not the language.doc. + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ +/*! \page langhowto Internationalization + +

    Support for multiple languages

    + +Doxygen has support for multiple languages. This means +that the text fragments that doxygen generates can changed into languages +other than English (the default) at configuration time. +

    +Currently, $numlang languages are supported (sorted alphabetically): +$languages. + +The table of information related to the supported languages follows. +It is sorted by language alphabetically. The Status column +was generated from sources and shows approximately the last version +when the translator was updated. +

    + +$information_table +Have a look at doxygen/doc/translator.txt for more details. +

    + +Most people on the list have indicated that they were also busy +doing other things, so if you want to help to speed things up please +let them (or me) know. + +If you want to add support for a language that is not yet listed +please see the next section. + +

    Adding a new language to doxygen

    + +This short HOWTO explains how to add support for a new language to Doxygen: + +Just follow these steps: +
      +
    1. Tell me for which language you want to add support. If no one else + is already working on support for that language, you will be + assigned as the maintainer for the language. +
    2. Create a copy of translator_en.h and name it + translator_.h + I'll use xx in the rest of this document. +
    3. Edit language.cpp: + Add a +\verbatim +#include +\endverbatim + in setTranslator() add +\verbatim + else if (L_EQUAL("your_language_name")) + { + theTranslator = new TranslatorYourLanguage; + } +\endverbatim + after the if { ... } +
    4. Edit libdoxygen.pro.in and add \c translator_xx.h to + the \c HEADERS line in the file doxygen.pro. +
    5. Edit translator_xx.h: +
        +
      • Rename TRANSLATOR_EN_H to TRANSLATOR_XX_H twice. +
      • Rename TranslatorEnglish to TranslatorYourLanguage +
      • In the member idLanguage() change "english" into the + name of the your language (use lower case characters only). Depending + on the language you may also wish to change the member functions + latexLanguageSupportCommand() and idLanguageCharset(). +
      • Edit all the strings that are returned by the member functions that + start with tr. + Try to match punctuation and capitals! + To enter special characters (with accents) you can: +
          +
        • Enter them directly if your keyboard supports that and you are + using a Latin-1 font. + Doxygen will translate the characters to proper Latex and + leave the Html and man output for what it is (which is fine, if + idLanguageCharset() is set correctly). +
        • Use html codes like \ä for an a with an umlaut (i.e. ä). + See the HTML specification for the codes. +
        +
      +
    6. Run configure and make again from the root of the distribution, + in order to regenerated the Makefiles. +
    7. Now you can use OUTPUT_LANGUAGE = your_language_name + in the config file to generate output in your language. +
    8. Send translator_xx.h to me so I can add it to doxygen. +
    + +

    Maintaining a language

    + +As new versions of doxygen appear, new sentences will be +added to the Translator interface class. Of course these need to be translated +as well (otherwise doxygen wouldn't even compile!). + +Waiting until all language maintainers have translated these new sentences +and sent the results would not be very practical for me. + +Instead, a new class TranslatorAdapter_x_y_z will be added to +translator_adapter.h (here x,y, and z correspond to the current +version of doxygen). And all translators that previous derived from +Translator will now derive from this adapter class. + +The Adapter class contains the new sentences with +default translations using the English translator (which is always up to date). +Instead of deriving your TranslatorXX class directly from Translator it will +derive from the intermediate class TranslatorAdapter_x_y_z. + +Thus, if a translator class inherits from a adapter class +maintenance is needed. By looking at the adapter class itself (and its base +classes) you can easily see which methods need to be updated. + +To update a language simply make your translator class derive from +the abstract class Translator and provide translations for the methods that +were previously provided by the adapter class (and its base classes). + +*/ + diff --git a/doc/translator.bat b/doc/translator.bat new file mode 100644 index 0000000..fc12581 --- /dev/null +++ b/doc/translator.bat @@ -0,0 +1,4 @@ +:start +call perl -w translator.pl +pause +goto start \ No newline at end of file diff --git a/doc/translator.pl b/doc/translator.pl new file mode 100644 index 0000000..f5b889e --- /dev/null +++ b/doc/translator.pl @@ -0,0 +1,752 @@ +#! /usr/bin/perl -w +# -*- mode: perl; mode: fold -*- + +# This is a Perl script for Doxygen developers. +# Its main purpose is to extract the information from sources +# related to internationalization (the translator classes). +# +# Petr Prikryl (prikrylp@skil.cz) +# History: +# -------- +# 2001/04/27 +# - First version of the script. +# +# 2002/05/02 +# - Update to accept updateNeededMessage() in the Translator class. +# - First version that generates doc/language.doc. +# +################################################################ + +require 5.005; +use strict; +use Carp; + +# Global variables +# +my $doxygenrootdir = ".."; +my $srcdir = "$doxygenrootdir/src"; +my $docdir = "$doxygenrootdir/doc"; + +# Names of the output files. +# +my $ftxt = "translator_report.txt"; +my $fdoc = "language.doc"; + + +################################################################ +# GetPureVirtual returns a hash of pure virtual method prototypes +# in a hash where the key is the method prototype, and the value +# is 1. The input argument is the full name of the source file. +# +sub GetPureVirtualFrom ##{{{ +{ + my $fin = shift; # Get the file name. + + # Let's open the file and read it into a single string. + # + open(FIN, "< $fin") or die "\nError when open < $fin: $!"; + my @content = ; + close FIN; + my $cont = join("", @content); + + # Remove comments and empty lines. + # + $cont =~ s{\s*//.*$}{}mg; # remove one-line comments + while ($cont =~ s{/\*.+?\*/}{}sg ) {} # remove C comments + $cont =~ s{\n\s*\n}{\n}sg; # remove empty lines + + # Remove the beginning up to the first virtual method. + # Remove also the text behind the class. + # + $cont =~ s/^.*?virtual/virtual/s; + $cont =~ s/\n\};.*$//s; + + # Erase anything between "=0;" and "virtual". Only the pure + # virtual methods will remain. Remove also the text behind + # the last "= 0;" + # + $cont =~ s{(=\s*0\s*;).*?(virtual)}{$1 $2}sg; + $cont =~ s{^(.+=\s*0\s*;).*?$}{$1}s; + + # Remove the empty implementation of the updateNeededMessage() + # method which is to be implemented by adapters only, not by + # translators. + # + $cont =~ s{\s*virtual + \s+QCString + \s+updateNeededMessage\(\) + \s+\{\s*return\s+"";\s*\} + } + {}xs; + + # Replace all consequent white spaces (including \n) by a single + # space. Trim also the leading and the trailing space. + # + $cont =~ s{\s+}{ }sg; + $cont =~ s{^\s+}{}s; + $cont =~ s{\s+$}{}s; + + # Split the result to the lines again. Remove the "= 0;". + # + $cont =~ s{\s*=\s*0\s*;\s*}{\n}sg; + + # Remove the keyword "virtual" because the derived classes + # may not use it. + # + $cont =~ s{^virtual\s+}{}mg; + + # Split the string into array of lines and fill the output hash. + # + my %result = (); + + foreach (split(/\n/, $cont)) { + $result{$_} = 1; + } + + return %result; +} +##}}} + + +################################################################ +# GetInfoFrom returns the list of information related to the +# parsed source file. The input argument is the name of the +# translator_xx.h file including path. +# +# The output list contains the following items: +# - class identifier +# - base class identifier +# - method prototypes (each in a separate item) +# +sub GetInfoFrom ##{{{ +{ + # Get the file name. + # + my $fin = shift; + + # Let's open the file and read it into a single string. + # + open(FIN, "< $fin") or die "\nError when open < $fin: $!"; + my @content = ; + close FIN; + my $cont = join("", @content); + + # Remove comments and empty lines. + # + $cont =~ s{\s*//.*$}{}mg; # remove one-line comments + $cont =~ s{/\*.+?\*/}{}sg; # remove C comments + $cont =~ s{\n\s*\n}{\n}sg; # remove empty lines + + # Extract the class and base class identifiers. Remove the + # opening curly brace. Remove also the first "public:" + # Put the class and the base class into the output list. + # + $cont =~ s{^.*class\s+(Translator\w+)[^:]*: + \s*public\s+(\w+)\b.*?\{\s* + (public\s*:\s+)? + } + {}sx; + + @content = ($1, $2); + + # Cut the things after the class. + # + $cont =~ s{\}\s*;\s*#endif\s*$}{}s; + + # Remove the "virtual" keyword, because some the derived class + # is not forced to use it. + # + $cont =~ s{^\s*virtual\s+}{}mg; + + # Remove all strings from lines. + # + $cont =~ s{".*?"}{}mg; + + # Remove all bodies of methods; + # + while ($cont =~ s/{[^{}]+?}//sg) {} + + # Remove all private methods, i.e. from "private:" to "public:" + # included. Later, remove also all from "private:" to the end. + # + $cont =~ s{private\s*:.*?public\s*:}{}sg; + $cont =~ s{private\s*:.*$}{}s; + + # Some of the translators use conditional compilation where + # the branches define the body of the method twice. Remove + # the ifdef/endif block content. + # + $cont =~ s{#ifdef.*?#endif}{}sg; + + # Now the string should containt only method prototypes. + # Let's unify their format by removing all spaces that + # are not necessary. Then let's put all of them on separate + # lines (one protototype -- one line; no empty lines). + # + $cont =~ s{\s+}{ }sg; + $cont =~ s{^\s+}{}s; + $cont =~ s{\s+$}{}s; + + $cont =~ s{\)\s*}{)\n}g; + + # Split the string and add it to the ouptut list. + # + @content = (@content, split(/\n/, $cont)); + return @content; +} +##}}} + + +################################################################ +# GenerateLanguageDoc takes document templates and code sources +# generates the content as expected in the language.doc file (the +# part of the Doxygen documentation), and returns the result as a +# string. +# +sub GenerateLanguageDoc ##{{{ +{ + # Get the references to the hash of class/base class. + # + my $rcb = shift; + + # Define templates for HTML table parts of the documentation. #{{{ + # + my $htmlTableHead = <<'xxxTABLE_HEADxxx'; +\htmlonly + + + + +
    + + + + + + + +xxxTABLE_HEADxxx + + my $htmlTableRow = <<'xxxTABLE_ROWxxx'; + + + + + + +xxxTABLE_ROWxxx + + my $htmlTableFoot = <<'xxxTABLE_FOOTxxx'; +
    Language Maintainer Contact address + (remove the NOSPAM.) Status
    $lang$maintainer$email$status
    +
    +\endhtmlonly +xxxTABLE_FOOTxxx + ##}}} + + # Define templates for LaTeX table parts of the documentation. #{{{ + # + my $latexTableHead = <<'xxxTABLE_HEADxxx'; +\latexonly +\begin{tabular}{|l|l|l|l|} + \hline + {\bf Language} & {\bf Maintainer} & {Contact address} & {Status} \\ +xxxTABLE_HEADxxx + + my $latexTableRow = <<'xxxTABLE_ROWxxx'; + $lang & $maintainer & {\tt $email} & $status \\ +xxxTABLE_ROWxxx + + my $latexTableFoot = <<'xxxTABLE_FOOTxxx'; + \hline +\end{tabular} +\endlatexonly +xxxTABLE_FOOTxxx + ##}}} + + # Read the template of the documentation, and join the content + # to a single string. #{{{ + # + my $fin = "$docdir/language.tpl"; + open(FIN, "< $fin") or die "\nError when open < $fin: $!"; + my @content = ; + close FIN; + + my $output = join("", @content); + ##}}} + + # Make and substitute the list of supported languages and their + # number. #{{{ + # + my @languages = sort grep { s{^Translator}{} } keys %{$rcb}; + + my $numlang = @languages; + + $output =~ s{\$numlang}{$numlang}; + + my $languages = join(", ", @languages); + $languages =~ s{((\w+,\s){5})}{$1\n}g; + $languages =~ s{Brazilian}{Brazilian Portuguese}; + $languages =~ s{(,\s+)(\w+)$}{$1and $2}s; + + $output =~ s{\$languages}{$languages}; + ##}}} + + # Create the hash of languages with the initial info. #{{{ + # + my %language = (); + + foreach (@languages) { + $language{$_} = $$rcb{"Translator$_"} . "unknown: unknown"; + } + ##}}} + + # Read the information related to maintainers into the + # string using suitable separators -- one line, one language. #{{{ + # + $fin = "$docdir/maintainers.txt"; + open(FIN, "< $fin") or die "\nError when open < $fin: $!"; + my @maintainers = ; + close FIN; + + my $maintainers = join("", @maintainers); + + # Trim the spaces on the lines. Strip the comment lines that + # start with % sign. + # + $maintainers =~ s{^[ \t]+}{}mg; + $maintainers =~ s{[ \t]+$}{}mg; + + $maintainers =~ s{^%.*$}{}mg; + + # Join the information for one language into one line, + # and remove empty lines. + # + $maintainers =~ s{\b\n\b}{}sg; + $maintainers =~ s{\n{2,}}{\n}sg; + $maintainers =~ s{^\n+}{}s; + $maintainers =~ s{\n+$}{}s; + ##}}} + + # Split the string back to the list, and update the information + # in the hash with information for languages. #{{{ + # + foreach my $line (sort split(/\n/, $maintainers)) { + + # Split the line for one language to separate lines for + # the language and one or more maintainers. + # + my @info = split(//, $line); + + my $lang = shift @info; + + # Ensure that the language starts with uppercase and + # continues with lowercase. + # + $lang =~ s{^(\w)(\w+)}{\U$1\L$2\E}; + + # Add information to the %language hash. If the language + # was not defined in sources, add the question mark to the + # language identifier. + # + if (defined $language{$lang}) { + $language{$lang} = $$rcb{"Translator$lang"} . '' + . join("", @info); + } + else { + $lang .= " (?)"; + $language{$lang} = "unknown" . join("", @info); + } + } + ##}}} + + # Now, the %language hash contains all the information needed for + # generating the tables (HTML and LaTeX). Define string variables + # for each of the tables, and initialize them. #{{{ + # + my $tableHTML = $htmlTableHead; + my $tableLATEX = $latexTableHead; + ##}}} + + # Loop through sorted keys for the languages, parse the + # information, and add it to the tables. #{{{ + # + foreach my $lang (sort keys %language) { + + # Read the line with info for the language and separate + # the information of status. #{{{ + # + my @list = split(//, $language{$lang}); + my $status = shift @list; + + my $i = $status =~ s{^Translator$}{up-to-date}; + + if ($i == 0) { + $i = $status =~ s{^TranslatorAdapter_(\d)_(\d)_(\d)} + {$1.$2.$3}x; + } + + if ($i == 0) { $status = '?'; } + + ##}}} + + # Split the rest of the list (should be a single item) into + # the list with one or more maintainers -- one line, one + # maintainer. #{{{ + # + my $rest = shift @list; + @list = split(//, $rest); + ##}}} + + # In HTML table, maintainer names are placed in the same + # cell. Also their e-mails are placed in a single cell. + # Extract the string with concatenated names and the string + # with concatenated e-mails. Add the row to the HTML + # table. #{{{ + # + my $name = ''; + my $email = ''; + + foreach my $maintainer (@list) { + + if ($name ne '') { $name .= '
    '; } + if ($email ne '') { $email .= '
    '; } + + $maintainer =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + $name .= $1; + $email .= $2; + } + + # Prepare the HTML row template, modify it, and add the + # result to the HTML table. + # + my $item = $htmlTableRow; + + $item =~ s{\$lang}{$lang}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{$status}; + + $tableHTML .= $item; + + ##}}} + + # For LaTeX, more maintainers for the same language are + # placed on separate rows in the table. The line separator + # in the table is placed explicitly above the first + # maintainer. Add rows for all maintainers to the LaTeX + # table. #{{{ + # + # Prepare the LATEX row template, modify it, and add the + # result to the LATEX table. + # + $item = $latexTableRow; + + my $first = shift @list; # the first maintainer. + $first =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + $name = $1; + $email = $2; + + $item =~ s{\$lang}{$lang}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{$status}; + + $tableLATEX .= " \\hline\n" . $item; + + # List the other maintainers for the language. Do not set + # lang and status for them. + # + while (@list) { + my $next = shift @list; + $next =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + my $name = $1; + my $email = $2; + my $item = $latexTableRow; + + $item =~ s{\$lang}{}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{}; + + $tableLATEX .= $item; + } + ##}}} + } + ##}}} + + # Finish the tables, and substitute the mark in the doc + # template by the contatenation of the tables. Add NOSPAM to + # email addresses in the HTML table. Replace the special + # character sequences. #{{{ + # + $tableHTML .= $htmlTableFoot; + $tableLATEX .= $latexTableFoot; + + $tableHTML =~ s{@}{\@NOSPAM.}sg; + $tableHTML =~ s{ř}{ř}sg; + + $tableLATEX =~ s/ř/\\v{r}/sg; + $tableLATEX =~ s/á/\\'{a}/sg; + $tableLATEX =~ s/ä/\\"{a}/sg; + $tableLATEX =~ s/ö/\\"{o}/sg; + $tableLATEX =~ s/_/\\_/sg; + + $output =~ s{\$information_table}{$tableHTML$tableLATEX}; + ##}}} + + # Replace the introduction notice in the output. #{{{ + # + $output =~ s{.+?} +{Warning: this file was generated from the language.tpl template + * Do not edit this file. Edit the template!}sx; + ##}}} + + # Return the content of the generated output file. + # + return $output; +} +##}}} + + +################################################################ +# Body +# +{ + # The translator base class must be present. Exit otherwise. #{{{ + # + if (!-f "$srcdir/translator.h") + { + print STDERR "\n\nThe translator.h not found in $srcdir.\n\n\a"; + exit 1; + } + ##}}} + + # Find all translator_xx.h files. #{{{ + # + my @entries = (); # init + + opendir DIR, $srcdir or confess "opendir error for $srcdir: $!"; + foreach (readdir(DIR)) { if (!/^\./) { push @entries, $_; } } + closedir DIR; # ignore names with dot at the beginning + + my @files = sort + grep { -f "$srcdir/$_" && m{^translator_..\.h$}i } + @entries; + ##}}} + + # Get only the pure virtual methods from the Translator class + # into a hash structure for later testing present/not present. + # + my %required = GetPureVirtualFrom("$srcdir/translator.h"); + + # Collect base classes of translators the hash. + # + my %cb = (); + + # The details for translators will be collected into the output + # string. + # + my $output = ''; + + # Loop through all translator files. Extract the implemented + # virtual methods and compare it with the requirements. Prepare + # the output. + # + foreach (@files) { + + # Get the information from the sources. Remember the base + # class for each of the classes. #{{{ + # + my @info = GetInfoFrom("$srcdir/$_"); + + my $class = shift @info; + my $base = shift @info; + + $cb{$class} = $base; + ##}}} + + # Set the value of the required methods to 1 (true). Let + # this indicate that the method was not defined in the + # translator class. + # + foreach (keys %required) { $required{$_} = 1; } + + # Loop through all items and compare the prototypes. Mark + # the implemented method and collect the old ones. #{{{ + # + my @old_methods = (); + + foreach my $method (@info) { + if (defined $required{$method}) { $required{$method} = 0; } + else {push(@old_methods, $method); } + } + ##}}} + + # Loop through the required hash and collect the missing + # (new) methods. Do this only when it derives from + # Translator or TranslatorAdapter classes. #{{{ + # + my @missing_methods = (); + + if ($base =~ m/^Translator(Adapter.*)?$/) { + foreach (keys %required) { + if ($required{$_}) { push(@missing_methods, $_); } + } + } + ##}}} + + # The detailed output will be produced only when it is + # needed. #{{{ + # + if (@old_methods || @missing_methods + || $base !~ m/^Translator(Adapter.*)?$/) { + + $output .= "\n\n\n"; + $output .= $class . " ($base)\n" . '-' x length($class) . "\n"; + + if ($base !~ m/^Translator(Adapter.*)?$/) { + $output .= "\nThis is the unusual implementation of the " + . "translator. Its class is derived\n" + . "from the $base base class. The usual translator" + . "class derives\n" + . "or from the Translator class or from some " + . "TranslatorAdapter_x_x_x classes.\n" + . "Because of that, nothing can be guessed about " + . "missing methods.\n"; + } + + if (@missing_methods) { + $output .= "\nMissing methods (should be implemented):\n\n"; + foreach (@missing_methods) { $output .= " $_\n"; } + } + + if (@old_methods) { + $output .= "\nObsolete methods (should be removed):\n\n"; + foreach (sort @old_methods) { $output .= " $_\n"; } + } + } + ##}}} + } + + + # Generate the textual output file. + # + my $fout = "$docdir/$ftxt"; + + # Open it first. + # + open(FOUT, "> $fout") or die "\nError when open > $fout: $!"; + + # List the supported languages. #{{{ + # + my @all_translators = keys %cb; + + print FOUT "Doxygen supports the following (" . @all_translators + . ") languages (sorted alphabetically):\n\n"; + + foreach (sort grep { s/^Translator(\w+)\b.*$/$1/ } @all_translators) { + print FOUT " $_\n"; + } + ##}}} + + # If there are up-to-date translators, list them. #{{{ + # + my @list = sort grep { $cb{$_} =~ m/^Translator$/ } keys %cb; + + if (@list) { + print FOUT "\n" .'-' x 70 . "\n"; + print FOUT "The following translator classes are up-to-date " + . "(sorted alphabetically).\n" + . "This means that they derive from the Translator class. " + . "However, there still\n" + . "may be some details listed below " + . "for them. Please, check it.\n\n"; + + foreach (@list) { print FOUT " $_\n"; } + } + ##}}} + + # If there are obsolete translators, list them. #{{{ + # + @list = sort grep { $cb{$_} =~ m/^TranslatorAdapter/ } keys %cb; + + if (@list) { + print FOUT "\n" .'-' x 70 . "\n"; + print FOUT "The following translator classes are obsolete " + . "(sorted alphabetically).\n" + . "This means that they derive from some of " + . "the adapter classes.\n\n"; + + foreach (@list) { print FOUT " $_\t($cb{$_})\n"; } + } + ##}}} + + # If there are other translators, list them. #{{{ + # + @list = sort + grep { $cb{$_} !~ m/^Translator$/ } + grep { $cb{$_} !~ m/^TranslatorAdapter/ } + keys %cb; + + if (@list) { + print FOUT "\n" .'-' x 70 . "\n"; + print FOUT "The following translator classes are somehow different\n" + . "(sorted alphabetically). This means that they " + . "do not derive from\n" + . "the Translator class, nor from some of the adapter classes.\n\n"; + + foreach (@list) { print FOUT " $_\t($cb{$_})\n"; } + } + ##}}} + + # List the methods that are expected to be implemented. #{{{ + print FOUT "\n\n" .'-' x 70 . "\n"; + print FOUT "Localized translators are expected to implement " + . "the following methods\n" + . "(prototypes sorted aplhabetically):\n\n"; + + foreach (sort keys(%required)) { + print FOUT "$_\n"; + } + ##}}} + + # If there are some details for the translators, show them. #{{{ + # + if ($output !~ m/^\s*$/) { + print FOUT "\n\n" .'-' x 70 . "\n"; + print FOUT "Details related to specific translator classes follows.\n" + . "Notice that the prototypes are recognized only when they\n" + . "are the same as in the Translator class."; + + print FOUT $output . "\n"; + } + ##}}} + + # Close the output file + # + close FOUT; + + # Generate the language.doc file. + # + $fout = "$docdir/$fdoc"; + + # Open it first for the output. + # + open(FOUT, "> $fout") or die "\nError when open > $fout: $!"; + + print FOUT GenerateLanguageDoc(\%cb); + + # Close the output file + # + close FOUT; + + + exit 0; +} +# end of body +################################################################ + diff --git a/src/Makefile.in b/src/Makefile.in index 682caf7..9ce2734 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,6 +1,6 @@ # -# $Id$ +# # # Copyright (C) 1997-2001 by Dimitri van Heesch. # diff --git a/src/classdef.cpp b/src/classdef.cpp index 58b0e65..c3219d6 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -49,76 +49,73 @@ ClassDef::ClassDef( const char *lref,const char *fName) : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm)) { - //name=n; - - compType=ct; + m_compType=ct; QCString compoundName=compoundTypeString(); if (fName) { - fileName=stripExtension(fName); + m_fileName=stripExtension(fName); } else { - fileName=compoundName+nm; + m_fileName=compoundName+m_name; } if (lref) { - //url=(QCString)"doxygen=\""+lref+":\" href=\""+fileName; - exampleList = 0; - exampleDict = 0; + m_exampleSDict = 0; } else { - //url="href=\""+fileName; - exampleList = new ExampleList; - exampleDict = new ExampleDict(17); + m_exampleSDict = new ExampleSDict(17); } - memListFileName=convertNameToFile(compoundName+nm+"-members"); - inherits = new BaseClassList; - inherits->setAutoDelete(TRUE); - inheritedBy = new BaseClassList; - inheritedBy->setAutoDelete(TRUE); - allMemberNameInfoList = new MemberNameInfoList; - allMemberNameInfoList->setAutoDelete(TRUE); - allMemberNameInfoDict = new MemberNameInfoDict(257); + m_memListFileName=convertNameToFile(compoundName+m_name+"-members"); + m_inherits = new BaseClassList; + m_inherits->setAutoDelete(TRUE); + m_inheritedBy = new BaseClassList; + m_inheritedBy->setAutoDelete(TRUE); + m_allMemberNameInfoSDict = new MemberNameInfoSDict(257); + m_allMemberNameInfoSDict->setAutoDelete(TRUE); visited=FALSE; setReference(lref); - incInfo=0; - tempArgs=0; - prot=Public; - nspace=0; - fileDef=0; - usesImplClassDict=0; - usesIntfClassDict=0; - memberGroupList = new MemberGroupList; - memberGroupList->setAutoDelete(TRUE); - memberGroupDict = new MemberGroupDict(17); + m_incInfo=0; + m_tempArgs=0; + m_prot=Public; + m_nspace=0; + m_fileDef=0; + m_usesImplClassDict=0; + m_usesIntfClassDict=0; + m_memberGroupList = new MemberGroupList; + m_memberGroupList->setAutoDelete(TRUE); + m_memberGroupDict = new MemberGroupDict(17); + m_innerClasses = new ClassSDict(17); int i=name().findRev("::"); if (i==-1) { - scopelessName=name(); + m_scopelessName=name(); } else { - scopelessName=name().right(name().length()-i-2); + m_scopelessName=name().right(name().length()-i-2); } - subGrouping=TRUE; + m_subGrouping=TRUE; + m_isTemplBaseClass=-1; + m_templateMapping = new StringDict; + m_templateMapping->setAutoDelete(TRUE); } // destroy the class definition ClassDef::~ClassDef() { - delete inherits; - delete inheritedBy; - delete allMemberNameInfoList; - delete allMemberNameInfoDict; - delete exampleList; - delete exampleDict; - delete usesImplClassDict; - delete usesIntfClassDict; - delete incInfo; - delete memberGroupList; - delete memberGroupDict; + delete m_inherits; + delete m_inheritedBy; + delete m_allMemberNameInfoSDict; + delete m_exampleSDict; + delete m_usesImplClassDict; + delete m_usesIntfClassDict; + delete m_incInfo; + delete m_memberGroupList; + delete m_memberGroupDict; + delete m_innerClasses; + delete m_templateMapping; } QCString ClassDef::displayName() const @@ -139,7 +136,7 @@ void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p, { //printf("*** insert base class %s into %s\n",cd->name().data(),name().data()); //inherits->inSort(new BaseClassDef(cd,p,s,t)); - inherits->append(new BaseClassDef(cd,n,p,s,t)); + m_inherits->append(new BaseClassDef(cd,n,p,s,t)); } // inserts a sub class in the inherited list @@ -147,34 +144,34 @@ void ClassDef::insertSubClass(ClassDef *cd,Protection p, Specifier s,const char *t) { //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data()); - inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t)); + m_inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t)); } void ClassDef::addMembersToMemberGroup() { - ::addMembersToMemberGroup(&pubTypes,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&pubMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&pubAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&pubSlots,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&signals,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&dcopMethods,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&pubStaticMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&pubStaticAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proTypes,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proSlots,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proStaticMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&proStaticAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priTypes,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priSlots,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priStaticMembers,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&priStaticAttribs,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&friends,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&related,memberGroupDict,memberGroupList); - ::addMembersToMemberGroup(&properties,memberGroupDict,memberGroupList); + ::addMembersToMemberGroup(&pubTypes,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&pubMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&pubAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&pubSlots,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&signals,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&dcopMethods,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&pubStaticMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&pubStaticAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proTypes,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proSlots,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proStaticMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&proStaticAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priTypes,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priSlots,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priStaticMembers,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&priStaticAttribs,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&friends,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&related,m_memberGroupDict,m_memberGroupList); + ::addMembersToMemberGroup(&properties,m_memberGroupDict,m_memberGroupList); } // adds new member definition to the class @@ -410,7 +407,7 @@ void ClassDef::insertMember(MemberDef *md) enumValMembers.append(md); break; case MemberDef::Function: - if (md->name()==scopelessName || // constructor + if (md->name()==m_scopelessName || // constructor (md->name().find('~')!=-1 && // hack to detect destructor md->name().find("operator")==-1 ) @@ -452,7 +449,7 @@ void ClassDef::insertMember(MemberDef *md) MemberInfo *mi = new MemberInfo((MemberDef *)md, md->protection(),md->virtualness(),FALSE); MemberNameInfo *mni=0; - if ((mni=(*allMemberNameInfoDict)[md->name()])) + if ((mni=m_allMemberNameInfoSDict->find(md->name()))) { mni->append(mi); } @@ -460,15 +457,14 @@ void ClassDef::insertMember(MemberDef *md) { mni = new MemberNameInfo(md->name()); mni->append(mi); - allMemberNameInfoList->inSort(mni); - allMemberNameInfoDict->insert(mni->memberName(),mni); + m_allMemberNameInfoSDict->inSort(mni->memberName(),mni); } } //void ClassDef::computeMemberGroups() //{ -// MemberNameInfoListIterator mnili(*allMemberNameInfoList); +// MemberNameInfoListIterator mnili(*m_allMemberNameInfoList); // MemberNameInfo *mni; // for (;(mni=mnili.current());++mnili) // { @@ -478,10 +474,10 @@ void ClassDef::insertMember(MemberDef *md) // { // MemberDef *md=mi->memberDef; // MemberGroup *mg = md->getMemberGroup(); -// if (mg && memberGroupDict->find(mg->groupId())==0) +// if (mg && m_memberGroupDict->find(mg->groupId())==0) // { -// memberGroupDict->insert(mg->groupId(),mg); -// memberGroupList->append(mg); +// m_memberGroupDict->insert(mg->groupId(),mg); +// m_memberGroupList->append(mg); // } // } // } @@ -517,7 +513,7 @@ void ClassDef::computeAnchors() void ClassDef::distributeMemberGroupDocumentation() { - MemberGroupListIterator mgli(*memberGroupList); + MemberGroupListIterator mgli(*m_memberGroupList); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -529,7 +525,7 @@ void ClassDef::distributeMemberGroupDocumentation() // add a file name to the used files set void ClassDef::insertUsedFile(const char *f) { - if (files.find(f)==-1) files.append(f); + if (m_files.find(f)==-1) m_files.append(f); } static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd) @@ -557,15 +553,15 @@ static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd) void ClassDef::setIncludeFile(FileDef *fd,const char *includeName,bool local) { //printf("ClassDef::setInclude(%p,%s,%d)\n",fd,includeName,local); - if (!incInfo) incInfo=new IncludeInfo; - if ((includeName && incInfo->includeName.isEmpty()) || - (fd!=0 && incInfo->fileDef==0) + if (!m_incInfo) m_incInfo=new IncludeInfo; + if ((includeName && m_incInfo->includeName.isEmpty()) || + (fd!=0 && m_incInfo->fileDef==0) ) { //printf("Setting file info\n"); - incInfo->fileDef = fd; - incInfo->includeName = includeName; - incInfo->local = local; + m_incInfo->fileDef = fd; + m_incInfo->includeName = includeName; + m_incInfo->local = local; } } @@ -574,7 +570,7 @@ ArgumentList *ClassDef::outerTemplateArguments() const int ti; ClassDef *pcd=0; int pi=0; - if (tempArgs) return tempArgs; + if (m_tempArgs) return m_tempArgs; // find the outer most class scope while ((ti=name().find("::",pi))!=-1 && (pcd=getClass(name().left(ti)))==0 @@ -632,7 +628,7 @@ void ClassDef::writeDocumentation(OutputList &ol) if (outerTempArgList) pageTitle.prepend(" Template"); startFile(ol,getOutputFileBase(),pageTitle); startTitle(ol,getOutputFileBase()); - parseText(ol,theTranslator->trCompoundReference(name(),compType,outerTempArgList!=0)); + parseText(ol,theTranslator->trCompoundReference(name(),m_compType,outerTempArgList!=0)); endTitle(ol,getOutputFileBase(),name()); ol.startTextBlock(); @@ -643,7 +639,7 @@ void ClassDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,defFileName,defLine,name(),0,briefDescription()); + parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); ol+=briefOutput; ol.writeString(" \n"); ol.pushGeneratorState(); @@ -658,18 +654,18 @@ void ClassDef::writeDocumentation(OutputList &ol) } ol.writeSynopsis(); - if (incInfo) + if (m_incInfo) { - QCString nm=incInfo->includeName.isEmpty() ? - (incInfo->fileDef ? - incInfo->fileDef->docName().data() : "" + QCString nm=m_incInfo->includeName.isEmpty() ? + (m_incInfo->fileDef ? + m_incInfo->fileDef->docName().data() : "" ) : - incInfo->includeName.data(); + m_incInfo->includeName.data(); if (!nm.isEmpty()) { ol.startTypewriter(); ol.docify("#include "); - if (incInfo->local) + if (m_incInfo->local) ol.docify("\""); else ol.docify("<"); @@ -678,16 +674,16 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.docify(nm); ol.disableAllBut(OutputGenerator::Html); ol.enable(OutputGenerator::Html); - if (incInfo->fileDef) + if (m_incInfo->fileDef) { - ol.writeObjectLink(0,incInfo->fileDef->includeName(),0,nm); + ol.writeObjectLink(0,m_incInfo->fileDef->includeName(),0,nm); } else { ol.docify(nm); } ol.popGeneratorState(); - if (incInfo->local) + if (m_incInfo->local) ol.docify("\""); else ol.docify(">"); @@ -711,11 +707,11 @@ void ClassDef::writeDocumentation(OutputList &ol) // write subclasses int count; - if ((count=inherits->count())>0) + if ((count=m_inherits->count())>0) { //parseText(ol,theTranslator->trInherits()+" "); - QCString inheritLine = theTranslator->trInheritsList(inherits->count()); + QCString inheritLine = theTranslator->trInheritsList(m_inherits->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -724,7 +720,7 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,inheritLine.mid(index,newIndex-index)); bool ok; uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - BaseClassDef *bcd=inherits->at(entryIndex); + BaseClassDef *bcd=m_inherits->at(entryIndex); if (ok && bcd) { ClassDef *cd=bcd->classDef; @@ -765,9 +761,9 @@ void ClassDef::writeDocumentation(OutputList &ol) } // write subclasses - if ((count=inheritedBy->count())>0) + if ((count=m_inheritedBy->count())>0) { - QCString inheritLine = theTranslator->trInheritedByList(inheritedBy->count()); + QCString inheritLine = theTranslator->trInheritedByList(m_inheritedBy->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -776,7 +772,7 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,inheritLine.mid(index,newIndex-index)); bool ok; uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - BaseClassDef *bcd=inheritedBy->at(entryIndex); + BaseClassDef *bcd=m_inheritedBy->at(entryIndex); if (ok && bcd) { ClassDef *cd=bcd->classDef; @@ -801,19 +797,19 @@ void ClassDef::writeDocumentation(OutputList &ol) count=0; BaseClassDef *ibcd; - ibcd=inheritedBy->first(); + ibcd=m_inheritedBy->first(); while (ibcd) { ClassDef *icd=ibcd->classDef; if ( icd->isVisibleInHierarchy()) count++; - ibcd=inheritedBy->next(); + ibcd=m_inheritedBy->next(); } - ibcd=inherits->first(); + ibcd=m_inherits->first(); while (ibcd) { ClassDef *icd=ibcd->classDef; if ( icd->isVisibleInHierarchy()) count++; - ibcd=inherits->next(); + ibcd=m_inherits->next(); } @@ -879,10 +875,11 @@ void ClassDef::writeDocumentation(OutputList &ol) } // write link to list of all members (HTML only) - if (allMemberNameInfoList->count()>0 && !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + if (m_allMemberNameInfoSDict->count()>0 && + !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) { ol.disableAllBut(OutputGenerator::Html); - ol.startTextLink(memListFileName,0); + ol.startTextLink(m_memListFileName,0); parseText(ol,theTranslator->trListOfAllMembers()); ol.endTextLink(); ol.enableAll(); @@ -894,11 +891,11 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.startMemberSections(); // write user defined member groups - MemberGroupListIterator mgli(*memberGroupList); + MemberGroupListIterator mgli(*m_memberGroupList); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - if (!mg->allMembersInSameSection() || !subGrouping) // group is in its own section + if (!mg->allMembersInSameSection() || !m_subGrouping) // group is in its own section { mg->writeDeclarations(ol,this,0,0,0); } @@ -908,40 +905,52 @@ void ClassDef::writeDocumentation(OutputList &ol) } } - // non static public members + // public types pubTypes.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicTypes(),0); - pubMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicMembers(),0); - pubAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicAttribs(),0); + + // public methods pubSlots.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicSlots(),0); signals.writeDeclarations(ol,this,0,0,0,theTranslator->trSignals(),0); dcopMethods.writeDeclarations(ol,this,0,0,0,theTranslator->trDCOPMethods(),0); properties.writeDeclarations(ol,this,0,0,0,theTranslator->trProperties(),0); - - // static public members + pubMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicMembers(),0); pubStaticMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticPublicMembers(),0); + + // public attribs + pubAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicAttribs(),0); pubStaticAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticPublicAttribs(),0); - // protected non-static members + // protected types proTypes.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedTypes(),0); - proMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedMembers(),0); - proAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedAttribs(),0); + + // protected methods proSlots.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedSlots(),0); - // protected static members + proMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedMembers(),0); proStaticMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticProtectedMembers(),0); + + // protected attribs + proAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trProtectedAttribs(),0); proStaticAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticProtectedAttribs(),0); if (Config_getBool("EXTRACT_PRIVATE")) { - // private non-static members + // private types priTypes.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateTypes(),0); - priMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateMembers(),0); - priAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateAttribs(),0); + + // private members priSlots.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateSlots(),0); - // private static members + priMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateMembers(),0); priStaticMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticPrivateMembers(),0); + + // private attribs + priAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trPrivateAttribs(),0); priStaticAttribs.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticPrivateAttribs(),0); } + + // friends friends.writeDeclarations(ol,this,0,0,0,theTranslator->trFriends(),0); + + // related functions related.writeDeclarations(ol,this,0,0,0, theTranslator->trRelatedFunctions(), theTranslator->trRelatedSubscript() @@ -985,7 +994,7 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.disableAllBut(OutputGenerator::RTF); ol.newParagraph(); ol.popGeneratorState(); - parseDoc(ol,defFileName,defLine,name(),0,documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); } // write examples if (exampleFlag) @@ -997,7 +1006,7 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.endDescTitle(); ol.writeDescItem(); ol.newParagraph(); - writeExample(ol,exampleList); + writeExample(ol,m_exampleSDict); //ol.endDescItem(); ol.endDescList(); } @@ -1040,10 +1049,10 @@ void ClassDef::writeDocumentation(OutputList &ol) { ol.disable(OutputGenerator::Man); ol.writeRuler(); - parseText(ol,theTranslator->trGeneratedFromFiles(compType,files.count()==1)); + parseText(ol,theTranslator->trGeneratedFromFiles(m_compType,m_files.count()==1)); bool first=TRUE; - const char *file = files.first(); + const char *file = m_files.first(); while (file) { bool ambig; @@ -1077,7 +1086,7 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.docify(fd->name()); } } - file=files.next(); + file=m_files.next(); } if (!first) ol.endItemList(); } @@ -1106,12 +1115,13 @@ void ClassDef::writeDocumentation(OutputList &ol) // write the list of all (inherited) members for this class void ClassDef::writeMemberList(OutputList &ol) { - if (allMemberNameInfoList->count()==0 || Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) return; + if (m_allMemberNameInfoSDict->count()==0 || + Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) return; // only for HTML ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - startFile(ol,memListFileName,theTranslator->trMemberList()); + startFile(ol,m_memListFileName,theTranslator->trMemberList()); startTitle(ol,0); parseText(ol,name()+" "+theTranslator->trMemberList()); endTitle(ol,0,0); @@ -1121,8 +1131,10 @@ void ClassDef::writeMemberList(OutputList &ol) ol.startItemList(); - MemberNameInfo *mni=allMemberNameInfoList->first(); - while (mni) + //MemberNameInfo *mni=m_allMemberNameInfoList->first(); + MemberNameInfoSDict::Iterator mnii(*m_allMemberNameInfoSDict); + MemberNameInfo *mni; + for (mnii.toFirst();(mni=mnii.current());++mnii) { MemberInfo *mi=mni->first(); while (mi) @@ -1253,7 +1265,6 @@ void ClassDef::writeMemberList(OutputList &ol) } mi=mni->next(); } - mni=allMemberNameInfoList->next(); } ol.endItemList(); endFile(ol); @@ -1265,14 +1276,13 @@ void ClassDef::writeMemberList(OutputList &ol) bool ClassDef::addExample(const char *anchor,const char *nameStr, const char *file) { - if (exampleDict && !exampleDict->find(nameStr)) + if (m_exampleSDict && !m_exampleSDict->find(nameStr)) { Example *e=new Example; e->anchor=anchor; e->name=nameStr; e->file=file; - exampleDict->insert(nameStr,e); - exampleList->inSort(e); + m_exampleSDict->inSort(nameStr,e); return TRUE; } return FALSE; @@ -1281,24 +1291,24 @@ bool ClassDef::addExample(const char *anchor,const char *nameStr, // returns TRUE if this class is used in an example bool ClassDef::hasExamples() { - if (exampleList==0) + if (m_exampleSDict==0) return FALSE; else - return exampleList->count()>0; + return m_exampleSDict->count()>0; } void ClassDef::setTemplateArguments(ArgumentList *al) { if (al==0) return; - if (!tempArgs) delete tempArgs; // delete old list if needed - tempArgs=new ArgumentList; - tempArgs->setAutoDelete(TRUE); + if (!m_tempArgs) delete m_tempArgs; // delete old list if needed + m_tempArgs=new ArgumentList; + m_tempArgs->setAutoDelete(TRUE); ArgumentListIterator ali(*al); Argument *a; for (;(a=ali.current());++ali) { - tempArgs->append(new Argument(*a)); + m_tempArgs->append(new Argument(*a)); } } @@ -1306,7 +1316,7 @@ void ClassDef::setTemplateArguments(ArgumentList *al) bool ClassDef::hasNonReferenceSuperClass() { bool found=!isReference(); - BaseClassListIterator bcli(*inheritedBy); + BaseClassListIterator bcli(*m_inheritedBy); for ( ; bcli.current() && !found ; ++bcli ) found=found || bcli.current()->classDef->hasNonReferenceSuperClass(); return found; @@ -1329,13 +1339,22 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup) if (!cn.isEmpty() && cn.at(0)!='@' && md) { ol.docify(" "); - ol.writeObjectLink(0,0,md->anchor(),cn); + if (isLinkable()) + { + ol.writeObjectLink(0,0,md->anchor(),cn); + } + else + { + ol.startBold(); + ol.docify(cn); + ol.endBold(); + } } ol.docify(" {"); ol.endMemberItem(FALSE); // write user defined member groups - MemberGroupListIterator mgli(*memberGroupList); + MemberGroupListIterator mgli(*m_memberGroupList); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -1397,19 +1416,24 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup) /*! a link to this class is possible within this project */ bool ClassDef::isLinkableInProject() { - return !name().isEmpty() && name().find('@')==-1 && - (prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && - hasDocumentation() && !isReference(); + return !name().isEmpty() && /* no name */ + m_isTemplBaseClass==-1 && /* template base class */ + name().find('@')==-1 && /* anonymous compound */ + (m_prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && /* private */ + hasDocumentation() && /* documented */ + !isReference(); /* not an external reference */ } /*! the class is visible in a class diagram, or class hierarchy */ bool ClassDef::isVisibleInHierarchy() { return // show all classes or a subclass is visible - (Config_getBool("ALLEXTERNALS") || hasNonReferenceSuperClass()) && + (Config_getBool("ALLEXTERNALS") || hasNonReferenceSuperClass()) && // and not an annonymous compound name().find('@')==-1 && + // and not an inherited template argument + m_isTemplBaseClass==-1 && // and not privately inherited - (prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && + (m_prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && // documented or show anyway or documentation is external (hasDocumentation() || !Config_getBool("HIDE_UNDOC_CLASSES") || isReference()); } @@ -1459,11 +1483,11 @@ void ClassDef::mergeMembers() // merge the members in the base class of this inheritance branch first bClass->mergeMembers(); - MemberNameInfoList *srcMnl = bClass->memberNameInfoList(); - MemberNameInfoDict *dstMnd = memberNameInfoDict(); - MemberNameInfoList *dstMnl = memberNameInfoList(); + MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict(); + MemberNameInfoSDict *dstMnd = memberNameInfoSDict(); + //MemberNameInfoList *dstMnl = memberNameInfoList(); - MemberNameInfoListIterator srcMnili(*srcMnl); + MemberNameInfoSDict::Iterator srcMnili(*srcMnd); MemberNameInfo *srcMni; for ( ; (srcMni=srcMnili.current()) ; ++srcMnili) { @@ -1624,15 +1648,16 @@ void ClassDef::mergeMembers() } } - // add it to the list and dictionary - dstMnl->append(newMni); - dstMnd->insert(newMni->memberName(),newMni); + // add it to the dictionary + //dstMnl->append(newMni); + dstMnd->append(newMni->memberName(),newMni); } } } } //---------------------------------------------------------------------------- + /*! Builds up a dictionary of all classes that are used by the state of this * class (the "implementation"). * Must be called before mergeMembers() is called! @@ -1640,7 +1665,7 @@ void ClassDef::mergeMembers() void ClassDef::determineImplUsageRelation() { - MemberNameInfoListIterator mnili(*allMemberNameInfoList); + MemberNameInfoSDict::Iterator mnili(*m_allMemberNameInfoSDict); MemberNameInfo *mni; for (;(mni=mnili.current());++mnili) { @@ -1652,42 +1677,47 @@ void ClassDef::determineImplUsageRelation() if (md->isVariable()) // for each member variable in this class { QCString type=removeRedundantWhiteSpace(md->typeString()); - int typeLen=type.length(); - static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); //printf("in class %s found var type=`%s' name=`%s'\n", // name().data(),type.data(),md->name().data()); - int p=0,i,l; + int pos=0; + QCString usedClassName; + QCString templSpec; bool found=FALSE; - if (typeLen>0) + while (extractClassNameFromType(type,pos,usedClassName,templSpec) && !found) { - while ((i=re.match(type,p,&l))!=-1 && !found) // for each class name in the type + //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data()); + // check if usedClassName is a template argument of its class + ClassDef *cd=md->getClassDef(); + if (cd && cd->templateArguments()) { - int ts=i+l; - int te=ts; - while (type.at(ts)==' ' && tstemplateArguments()); + Argument *arg; + int count=0; + for (ali.toFirst();(arg=ali.current());++ali,++count) { - // locate end of template - te=ts+1; - int brCount=1; - while (tename==usedClassName) // type is a template argument { - if (type.at(te)=='<') - { - if (te') - { - if (te') te++; else brCount--; - } - te++; + found=TRUE; + if (m_usesImplClassDict==0) m_usesImplClassDict = new UsesClassDict(257); + cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(), + usedClassName,ClassDef::Class); + cd->setIsTemplateBaseClass(count); + UsesClassDef *ucd = new UsesClassDef(cd); + m_usesImplClassDict->insert(cd->name(),ucd); + ucd->templSpecifiers = templSpec; + ucd->addAccessor(md->name()); + Doxygen::hiddenClasses.append(cd); + //printf("Adding used template argument %s to class %s\n", + // cd->name().data(),name().data()); + //printf("Adding accessor %s to class %s\n", + // md->name().data(),ucd->classDef->name().data()); } } - QCString templSpec; - if (te>ts) templSpec = type.mid(ts,te-ts); - // TODO: also check using Nx::Cx cases here! - QCString usedClassName = type.mid(i,l); - ClassDef *cd=0; + } + + if (!found) + { + cd=0; if (getNamespaceDef()!=0) { cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec); @@ -1698,12 +1728,12 @@ void ClassDef::determineImplUsageRelation() if (cd) // class exists { found=TRUE; - if (usesImplClassDict==0) usesImplClassDict = new UsesClassDict(257); - UsesClassDef *ucd=usesImplClassDict->find(cd->name()); + if (m_usesImplClassDict==0) m_usesImplClassDict = new UsesClassDict(257); + UsesClassDef *ucd=m_usesImplClassDict->find(cd->name()); if (ucd==0 || ucd->templSpecifiers!=templSpec) { ucd = new UsesClassDef(cd); - usesImplClassDict->insert(cd->name(),ucd); + m_usesImplClassDict->insert(cd->name(),ucd); ucd->templSpecifiers = templSpec; //printf("Adding used class %s to class %s\n", // cd->name().data(),name().data()); @@ -1712,17 +1742,16 @@ void ClassDef::determineImplUsageRelation() //printf("Adding accessor %s to class %s\n", // md->name().data(),ucd->classDef->name().data()); } - p=i+l; } } } } } #ifdef DUMP - if (usesClassDict) + if (m_usesClassDict) { msg("Class %s uses the following classes:\n",name().data()); - UsesClassDictIterator ucdi(*usesClassDict); + UsesClassDictIterator ucdi(*m_usesClassDict); UsesClassDef *ucd; for (;(ucd=ucdi.current());++ucdi) { @@ -1756,15 +1785,15 @@ void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr) if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try inbetween scopes! if (cd && cd!=this && !isBaseClass(cd)) { - if (usesIntfClassDict==0) + if (m_usesIntfClassDict==0) { - usesIntfClassDict = new UsesClassDict(257); + m_usesIntfClassDict = new UsesClassDict(257); } - UsesClassDef *ucd=usesIntfClassDict->find(cd->name()); + UsesClassDef *ucd=m_usesIntfClassDict->find(cd->name()); if (ucd==0) { ucd = new UsesClassDef(cd); - usesIntfClassDict->insert(cd->name(),ucd); + m_usesIntfClassDict->insert(cd->name(),ucd); //printf("in class `%s' adding used intf class `%s'\n", // name().data(),cd->name().data()); } @@ -1778,7 +1807,7 @@ void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr) void ClassDef::determineIntfUsageRelation() { - MemberNameInfoListIterator mnili(*allMemberNameInfoList); + MemberNameInfoSDict::Iterator mnili(*m_allMemberNameInfoList); MemberNameInfo *mni; for (;(mni=mnili.current());++mnili) { @@ -1824,12 +1853,12 @@ void ClassDef::determineIntfUsageRelation() PackageDef *ClassDef::packageDef() const { - return fileDef ? fileDef->packageDef() : 0; + return m_fileDef ? m_fileDef->packageDef() : 0; } QCString ClassDef::compoundTypeString() const { - switch (compType) + switch (m_compType) { case Class: return "class"; case Struct: return "struct"; @@ -1844,21 +1873,94 @@ QCString ClassDef::getOutputFileBase() const { if (isReference()) { - return fileName; + return m_fileName; } else { - return convertNameToFile(fileName); + return convertNameToFile(m_fileName); } } QCString ClassDef::getFileBase() const { - return fileName; + return m_fileName; } QCString ClassDef::getSourceFileBase() const { - return convertNameToFile(fileName+"-source"); + return convertNameToFile(m_fileName+"-source"); +} + +void ClassDef::setGroupDefForAllMembers(GroupDef *gd) +{ + gd->addClass(this); + //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data()); + MemberNameInfoSDict::Iterator mnili(*m_allMemberNameInfoSDict); + MemberNameInfo *mni; + for (;(mni=mnili.current());++mnili) + { + MemberNameInfoIterator mnii(*mni); + MemberInfo *mi; + for (mnii.toFirst();(mi=mnii.current());++mnii) + { + MemberDef *md=mi->memberDef; + md->setGroupDef(gd); + gd->insertMember(md,TRUE); + ClassDef *innerClass = md->getClassDefOfAnonymousType(); + if (innerClass) innerClass->setGroupDefForAllMembers(gd); + } + } +} + +void ClassDef::addInnerCompound(Definition *d) +{ + m_innerClasses->inSort(d->localName(),(ClassDef *)d); +} + +Definition *ClassDef::findInnerCompound(const char *name) +{ + if (name==0) return 0; + return m_innerClasses->find(name); +} + +void ClassDef::initTemplateMapping() +{ + m_templateMapping->clear(); + ArgumentList *al = templateArguments(); + if (al) + { + ArgumentListIterator ali(*al); + Argument *arg; + for (ali.toFirst();(arg=ali.current());++ali) + { + setTemplateArgumentMapping(arg->name,arg->defval); + } + } +} + +void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual) +{ + //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual); + if (m_templateMapping && formal) + { + if (m_templateMapping->find(formal)) + { + m_templateMapping->remove(formal); + } + m_templateMapping->insert(formal,new QCString(actual)); + } +} + +QCString ClassDef::getTemplateArgumentMapping(const char *formal) const +{ + if (m_templateMapping && formal) + { + QCString *s = m_templateMapping->find(formal); + if (s) + { + return *s; + } + } + return ""; } diff --git a/src/classdef.h b/src/classdef.h index 63dabd9..7869759 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -29,21 +29,21 @@ class MemberDict; class ClassList; +class ClassSDict; class OutputList; class FileDef; class BaseClassList; -class MemberInfoList; -class MemberInfoDict; class NamespaceDef; class MemberDef; -class ExampleList; -class MemberNameInfoList; -class MemberNameInfoDict; +class ExampleSDict; +class MemberNameInfoSDict; class UsesClassDict; class MemberGroupList; class MemberGroupDict; class QTextStream; class PackageDef; +class GroupDef; +class StringDict; struct IncludeInfo; /*! \brief This class contains all information about a compound. @@ -76,7 +76,7 @@ class ClassDef : public Definition QCString displayName() const; /*! Returns the type of compound this is */ - CompoundType compoundType() const { return compType; } + CompoundType compoundType() const { return m_compType; } /*! Returns the type of compound as a string */ QCString compoundTypeString() const; @@ -84,21 +84,16 @@ class ClassDef : public Definition /*! Returns the list of base classes from which this class directly * inherits. */ - BaseClassList *baseClasses() { return inherits; } + BaseClassList *baseClasses() { return m_inherits; } /*! Returns the list of sub classes that directly inherit from this class */ - BaseClassList *subClasses() { return inheritedBy; } - - /*! Returns a list of all members. This includes any inherited members. - * Members are sorted alphabetically. - */ - MemberNameInfoList *memberNameInfoList() { return allMemberNameInfoList; } + BaseClassList *subClasses() { return m_inheritedBy; } /*! Returns a dictionary of all members. This includes any inherited * members. Members are sorted alphabetically. */ - MemberNameInfoDict *memberNameInfoDict() { return allMemberNameInfoDict; } + MemberNameInfoSDict *memberNameInfoSDict() { return m_allMemberNameInfoSDict; } void writeDocumentation(OutputList &ol); void writeMemberList(OutputList &ol); @@ -107,7 +102,7 @@ class ClassDef : public Definition /*! Return the protection level (Public,Protected,Private) in which * this compound was found. */ - Protection protection() const { return prot; } + Protection protection() const { return m_prot; } /*! returns TRUE iff a link is possible to an item within this project. */ @@ -127,7 +122,7 @@ class ClassDef : public Definition /*! Returns the template arguments of this class * Will return 0 if not applicable. */ - ArgumentList *templateArguments() const { return tempArgs; } + ArgumentList *templateArguments() const { return m_tempArgs; } /*! Returns the template arguments that this nested class "inherits" * from its outer class (doxygen assumes there is only one!). @@ -138,12 +133,12 @@ class ClassDef : public Definition /*! Returns the namespace this compound is in, or 0 if it has a global * scope. */ - NamespaceDef *getNamespaceDef() { return nspace; } + NamespaceDef *getNamespaceDef() { return m_nspace; } /*! Returns the file in which this compound's definition can be found. * Should not return 0 (but it might be a good idea to check anyway). */ - FileDef *getFileDef() const { return fileDef; } + FileDef *getFileDef() const { return m_fileDef; } /*! Returns the Java package this class is in or 0 if not applicable. */ @@ -155,16 +150,24 @@ class ClassDef : public Definition */ bool isBaseClass(ClassDef *bcd); + /*! Is this an artificial class that is the template argument of + * a class. If so the argument number is returned, otherwise -1 + * is returned. + */ + int isTemplateBaseClass() const { return m_isTemplBaseClass; } + UsesClassDict *usedImplementationClasses() const { - return usesImplClassDict; + return m_usesImplClassDict; } UsesClassDict *usedInterfaceClasses() const { - return usesIntfClassDict; + return m_usesIntfClassDict; } - + + virtual Definition *findInnerCompound(const char *name); + /* member lists by protection */ MemberList pubMembers; MemberList proMembers; @@ -200,7 +203,7 @@ class ClassDef : public Definition MemberList variableMembers; MemberList propertyMembers; - /*! \} */ + /*! \} Public API */ /*! \name Doxygen internal API * \{ @@ -217,16 +220,24 @@ class ClassDef : public Definition bool addExample(const char *anchor,const char *name, const char *file); void addMembersToMemberGroup(); void distributeMemberGroupDocumentation(); - void setNamespace(NamespaceDef *nd) { nspace = nd; } + void setNamespace(NamespaceDef *nd) { m_nspace = nd; } void setTemplateArguments(ArgumentList *al); void mergeMembers(); - void setFileDef(FileDef *fd) { fileDef=fd; } + void setFileDef(FileDef *fd) { m_fileDef=fd; } void determineImplUsageRelation(); void determineIntfUsageRelation(); - void setSubGrouping(bool enabled) { subGrouping = enabled; } - void setProtection(Protection p) { prot=p; } + void setSubGrouping(bool enabled) { m_subGrouping = enabled; } + void setProtection(Protection p) { m_prot=p; } + void setGroupDefForAllMembers(GroupDef *g); + void addInnerCompound(Definition *d); + void setIsTemplateBaseClass(int num) { m_isTemplBaseClass = num; } + void initTemplateMapping(); + void setTemplateArgumentMapping(const char *formal,const char *actual); + QCString getTemplateArgumentMapping(const char *formal) const; /*! Creates a new compound definition. + * \param outerScope class, file or namespace in which this class is + * defined. * \param fileName full path and file name in which this compound was * found. * \param startLine line number where the definition of this compound @@ -252,37 +263,99 @@ class ClassDef : public Definition bool hasExamples(); bool hasNonReferenceSuperClass(); - /*! \} */ + /*! \} Interal API */ private: - QCString fileName; // HTML containing the class docs - IncludeInfo *incInfo; // header file to refer to - QCString incName; // alternative include file name - QCString memListFileName; - QCString scopelessName; // name without any scopes - BaseClassList *inherits; - BaseClassList *inheritedBy; - NamespaceDef *nspace; // the namespace this class is in + /*! file name that forms the base for the output file containing the + * class documentation. For compatibility with Qt (e.g. links via tag + * files) this name cannot be derived from the class name directly. + */ + QCString m_fileName; + + /*! Include information about the header file should be included + * in the documentation. 0 by default, set by setIncludeFile(). + */ + IncludeInfo *m_incInfo; + + /*! file name that forms the base for the "list of members" for this + * class. + */ + QCString m_memListFileName; + + /*! Bare name of the class without any scoping prefixes + * (like for nested classes and classes inside namespaces) + */ + QCString m_scopelessName; + + /*! List of base class (or super-classes) from which this class derives + * directly. + */ + BaseClassList *m_inherits; + + /*! List of sub-classes that directly derive from this class + */ + BaseClassList *m_inheritedBy; + + /*! Namespace this class is part of + * (this is the inner most namespace in case of nested namespaces) + */ + NamespaceDef *m_nspace; + + /*! File this class is defined in */ + FileDef *m_fileDef; + + /*! List of all members (including inherited members) */ + MemberNameInfoSDict *m_allMemberNameInfoSDict; + + /*! Template arguments of this class */ + ArgumentList *m_tempArgs; + + /*! Files that were used for generating the class documentation. */ + QStrList m_files; + + /*! Examples that use this class */ + ExampleSDict *m_exampleSDict; + + /*! Holds the kind of "class" this is. */ + CompoundType m_compType; + + /*! The protection level in which this class was found. + * Typically Public, but for nested classes this can also be Protected + * or Private. + */ + Protection m_prot; + + /*! Does this class group its user-grouped members + * as a sub-section of the normal (public/protected/..) + * groups? + */ + bool m_subGrouping; + + /*! The inner classes contained in this class. Will be 0 if there are + * no inner classes. + */ + ClassSDict *m_innerClasses; /* user defined member groups */ - MemberGroupList *memberGroupList; - MemberGroupDict *memberGroupDict; - - MemberNameInfoList *allMemberNameInfoList; - MemberNameInfoDict *allMemberNameInfoDict; - ArgumentList *tempArgs; - QStrList files; - ExampleList *exampleList; - ExampleDict *exampleDict; - CompoundType compType; - Protection prot; - FileDef *fileDef; - UsesClassDict *usesImplClassDict; - UsesClassDict *usesIntfClassDict; - - bool subGrouping; // does this class group its user-grouped members - // as a sub-section of the normal (public/protected/..) - // groups? + MemberGroupList *m_memberGroupList; + MemberGroupDict *m_memberGroupDict; + + /* classes for the collaboration diagram */ + UsesClassDict *m_usesImplClassDict; + UsesClassDict *m_usesIntfClassDict; + + /*! Is this a class that exists because of template class that + * inherited one of it's template arguments. If so that this + * variable indicate the template argument number, otherwise + * this is -1 + */ + int m_isTemplBaseClass; + + /*! A mapping used by template classes, which maps formal + * template arguments to their actual instantiations. + * This is used while generating inheritance graphs. + */ + StringDict *m_templateMapping; }; /*! \brief Class that contains information about a usage relation. diff --git a/src/classlist.cpp b/src/classlist.cpp index bd3874e..ca05275 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -35,9 +35,15 @@ int ClassList::compareItems(GCI item1, GCI item2) { ClassDef *c1=(ClassDef *)item1; ClassDef *c2=(ClassDef *)item2; - //int prefixLength = Config::instance()->get("").length(); - //int i1 = c1->name().left(prefixLength)==Config::instance()->get("") ? prefixLength : 0; - //int i2 = c2->name().left(prefixLength)==Config::instance()->get("") ? prefixLength : 0; + return stricmp(c1->name().data()+getPrefixIndex(c1->name()), + c2->name().data()+getPrefixIndex(c2->name()) + ); +} + +int ClassSDict::compareItems(GCI item1, GCI item2) +{ + ClassDef *c1=(ClassDef *)item1; + ClassDef *c2=(ClassDef *)item2; return stricmp(c1->name().data()+getPrefixIndex(c1->name()), c2->name().data()+getPrefixIndex(c2->name()) ); @@ -48,13 +54,14 @@ ClassListIterator::ClassListIterator(const ClassList &cllist) : { } -void ClassList::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter,const char *header) +void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter,const char *header) { if (count()>0) { - ClassDef *cd=first(); + ClassSDict::Iterator sdi(*this); + ClassDef *cd=0; bool found=FALSE; - while (cd) + for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->name().find('@')==-1 && (filter==0 || *filter==cd->compoundType()) @@ -124,7 +131,6 @@ void ClassList::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *fi } } } - cd=next(); } if (found) ol.endMemberList(); } diff --git a/src/classlist.h b/src/classlist.h index 02521d0..23c247e 100644 --- a/src/classlist.h +++ b/src/classlist.h @@ -22,6 +22,7 @@ #include #include "classdef.h" +#include "sortdict.h" class ClassList : public QList { @@ -30,8 +31,6 @@ class ClassList : public QList ~ClassList(); int compareItems(GCI item1,GCI item2); - void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0, - const char *header=0); }; class ClassListIterator : public QListIterator @@ -47,4 +46,14 @@ class ClassDict : public QDict ~ClassDict() {} }; +class ClassSDict : public SDict +{ + public: + ClassSDict(int size) : SDict(size) {} + ~ClassSDict() {} + int compareItems(GCI item1,GCI item2); + void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0, + const char *header=0); +}; + #endif diff --git a/src/definition.cpp b/src/definition.cpp index 1beeba9..87f5855 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -31,26 +31,33 @@ Definition::Definition(const char *df,int dl, const char *name,const char *b,const char *d) { - defFileName = df; - defLine = dl; - n=name; - brief=b; - doc=d; - sectionDict=0, - startBodyLine=endBodyLine=-1, - bodyDef=0; - sourceRefList=0; - sourceRefDict=0; + m_defFileName = df; + m_defLine = dl; + m_name=name; + m_localName=name; + int i=m_localName.findRev("::"); + if (i!=-1) + { + m_localName=m_localName.right(m_localName.length()-i-2); + } + m_brief=b; + m_doc=d; + m_sectionDict=0, + m_startBodyLine=m_endBodyLine=-1, + m_bodyDef=0; + m_sourceRefList=0; + m_sourceRefDict=0; m_todoId=0; m_testId=0; m_bugId=0; + m_outerScope=0; } Definition::~Definition() { - delete sectionDict; - delete sourceRefList; - delete sourceRefDict; + delete m_sectionDict; + delete m_sourceRefList; + delete m_sourceRefDict; } @@ -65,13 +72,13 @@ void Definition::addSectionsToDefinition(QList *anchorList) { //printf("Add section `%s' to definition `%s'\n", // si->label.data(),n.data()); - if (sectionDict==0) + if (m_sectionDict==0) { - sectionDict = new SectionDict(17); + m_sectionDict = new SectionDict(17); } - if (sectionDict->find(*s)==0) + if (m_sectionDict->find(*s)==0) { - sectionDict->insert(*s,si); + m_sectionDict->insert(*s,si); } si->definition = this; } @@ -81,9 +88,9 @@ void Definition::addSectionsToDefinition(QList *anchorList) void Definition::writeDocAnchorsToTagFile() { - if (!Config_getString("GENERATE_TAGFILE").isEmpty() && sectionDict) + if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_sectionDict) { - QDictIterator sdi(*sectionDict); + QDictIterator sdi(*m_sectionDict); SectionInfo *si; for (;(si=sdi.current());++sdi) { @@ -99,14 +106,14 @@ void Definition::writeDocAnchorsToTagFile() void Definition::setBriefDescription(const char *b) { - brief=QCString(b).stripWhiteSpace(); - int bl=brief.length(); + m_brief=QCString(b).stripWhiteSpace(); + int bl=m_brief.length(); if (bl>0) // add puntuation if needed { - switch(brief.at(bl-1)) + switch(m_brief.at(bl-1)) { case '.': case '!': case '?': break; - default: brief+='.'; break; + default: m_brief+='.'; break; } } } @@ -219,7 +226,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) { ol.pushGeneratorState(); //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef); - if (Config_getBool("SOURCE_BROWSER") && startBodyLine!=-1 && bodyDef) + if (Config_getBool("SOURCE_BROWSER") && m_startBodyLine!=-1 && m_bodyDef) { //ol.disable(OutputGenerator::RTF); ol.newParagraph(); @@ -231,15 +238,15 @@ void Definition::writeSourceDef(OutputList &ol,const char *) if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this. { QCString lineStr,anchorStr; - lineStr.sprintf("%d",startBodyLine); - anchorStr.sprintf("l%05d",startBodyLine); + lineStr.sprintf("%d",m_startBodyLine); + anchorStr.sprintf("l%05d",m_startBodyLine); if (lineMarkerPosgetSourceFileBase(), + ol.writeObjectLink(0,m_bodyDef->getSourceFileBase(), anchorStr,lineStr); ol.enableAll(); ol.disable(OutputGenerator::Html); @@ -253,12 +260,12 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.disableAllBut(OutputGenerator::Html); // write file link (HTML only) - ol.writeObjectLink(0,bodyDef->getSourceFileBase(), - 0,bodyDef->name()); + ol.writeObjectLink(0,m_bodyDef->getSourceFileBase(), + 0,m_bodyDef->name()); ol.enableAll(); ol.disable(OutputGenerator::Html); // write normal text (Latex/Man only) - ol.docify(bodyDef->name()); + ol.docify(m_bodyDef->name()); ol.enableAll(); // write text right from file marker @@ -271,12 +278,12 @@ void Definition::writeSourceDef(OutputList &ol,const char *) parseText(ol,refText.left(fileMarkerPos)); ol.disableAllBut(OutputGenerator::Html); // write file link (HTML only) - ol.writeObjectLink(0,bodyDef->getSourceFileBase(), - 0,bodyDef->name()); + ol.writeObjectLink(0,m_bodyDef->getSourceFileBase(), + 0,m_bodyDef->name()); ol.enableAll(); ol.disable(OutputGenerator::Html); // write normal text (Latex/Man only) - ol.docify(bodyDef->name()); + ol.docify(m_bodyDef->name()); ol.enableAll(); // write text between markers @@ -285,7 +292,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.disableAllBut(OutputGenerator::Html); // write line link (HTML only) - ol.writeObjectLink(0,bodyDef->getSourceFileBase(), + ol.writeObjectLink(0,m_bodyDef->getSourceFileBase(), anchorStr,lineStr); ol.enableAll(); ol.disable(OutputGenerator::Html); @@ -316,12 +323,12 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) ol.pushGeneratorState(); //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(), // startBodyLine,endBodyLine,bodyDef); - if (Config_getBool("INLINE_SOURCES") && startBodyLine!=-1 && - endBodyLine>=startBodyLine && bodyDef) + if (Config_getBool("INLINE_SOURCES") && m_startBodyLine!=-1 && + m_endBodyLine>=m_startBodyLine && m_bodyDef) { QCString codeFragment; - int actualStart=startBodyLine,actualEnd=endBodyLine; - if (readCodeFragment(bodyDef->absFilePath(), + int actualStart=m_startBodyLine,actualEnd=m_endBodyLine; + if (readCodeFragment(m_bodyDef->absFilePath(), actualStart,actualEnd,codeFragment) ) { @@ -330,7 +337,7 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) if (definitionType()==TypeMember) setParameterList((MemberDef *)this); ol.startCodeFragment(); parseCode(ol,scopeName,codeFragment,FALSE,0, - bodyDef,actualStart,actualEnd,TRUE); + m_bodyDef,actualStart,actualEnd,TRUE); ol.endCodeFragment(); } } @@ -343,13 +350,13 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) { ol.pushGeneratorState(); - if (Config_getBool("SOURCE_BROWSER") && sourceRefList) + if (Config_getBool("SOURCE_BROWSER") && m_sourceRefList) { ol.newParagraph(); parseText(ol,theTranslator->trReferencedBy()); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList(sourceRefList->count()); + QCString ldefLine=theTranslator->trWriteList(m_sourceRefList->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; @@ -359,7 +366,7 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) bool ok; parseText(ol,ldefLine.mid(index,newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - MemberDef *md=sourceRefList->at(entryIndex); + MemberDef *md=m_sourceRefList->at(entryIndex); if (ok && md) { QCString scope=md->getScopeString(); @@ -402,8 +409,8 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) bool Definition::hasDocumentation() const { - return !doc.isEmpty() || // has detailed docs - !brief.isEmpty() || // has brief description + return !m_doc.isEmpty() || // has detailed docs + !m_brief.isEmpty() || // has brief description Config_getBool("EXTRACT_ALL"); // extract everything } @@ -419,16 +426,49 @@ void Definition::addSourceReference(MemberDef *md) name.prepend(scope+"::"); } - if (sourceRefList==0) + if (m_sourceRefList==0) { - sourceRefDict = new MemberDict(53); - sourceRefList = new MemberList; + m_sourceRefDict = new MemberDict(53); + m_sourceRefList = new MemberList; } - if (sourceRefDict->find(name)==0) + if (m_sourceRefDict->find(name)==0) { - sourceRefDict->insert(name,md); - sourceRefList->inSort(md); + m_sourceRefDict->insert(name,md); + m_sourceRefList->inSort(md); } } } +Definition *Definition::findInnerCompound(const char *) +{ + return 0; +} + +void Definition::addInnerCompound(Definition *) +{ + err("Error: Definition::addInnerCompound() called\n"); +} + +QCString Definition::qualifiedName() const +{ + //printf("start Definition::qualifiedName()\n"); + if (m_outerScope==0) return m_localName; // TODO: remove this check + + QCString qualifiedName; + if (m_outerScope->name()=="") + { + qualifiedName = m_localName.copy(); + } + else + { + qualifiedName = m_outerScope->qualifiedName()+"::"+m_localName; + } + //printf("end Definition::qualifiedName()=%s\n",qualifiedName.data()); + return qualifiedName; +}; + +QCString Definition::localName() const +{ + return m_localName; +} + diff --git a/src/definition.h b/src/definition.h index 2018525..6136cc6 100644 --- a/src/definition.h +++ b/src/definition.h @@ -47,26 +47,28 @@ class Definition /*! Destroys the definition */ virtual ~Definition(); /*! Returns the name of the definition */ - const QCString& name() const { return n; } + const QCString& name() const { return m_name; } /*! Returns the base name of the output file that contains this * definition. */ + QCString qualifiedName() const; + QCString localName() const; virtual QCString getOutputFileBase() const = 0; /*! Returns the name of the source listing of this file. */ const QCString getSourceFileBase() const { ASSERT(0); return "NULL"; } /*! Returns the detailed description of this definition */ - const QCString& documentation() const { return doc; } + const QCString& documentation() const { return m_doc; } /*! Returns the brief description of this definition */ - const QCString& briefDescription() const { return brief; } + const QCString& briefDescription() const { return m_brief; } /*! Sets a new \a name for the definition */ - void setName(const char *name) { n=name; } + void setName(const char *name) { m_name=name; } /*! Sets the documentation of this definition to \a d. */ void setDocumentation(const char *d,bool stripWhiteSpace=TRUE) { if (stripWhiteSpace) - doc=((QCString)d).stripWhiteSpace(); + m_doc=((QCString)d).stripWhiteSpace(); else - doc=d; + m_doc=d; } /*! Sets the brief description of this definition to \a b. * A dot is added to the sentence if not available. @@ -77,9 +79,9 @@ class Definition virtual bool isLinkableInProject() = 0; virtual bool isLinkable() = 0; - bool isReference() const { return !ref.isEmpty(); } - void setReference(const char *r) { ref=r; } - QCString getReference() const { return ref; } + bool isReference() const { return !m_ref.isEmpty(); } + void setReference(const char *r) { m_ref=r; } + QCString getReference() const { return m_ref; } /*! Add the list of anchors that mark the sections that are found in the * documentation. @@ -90,13 +92,13 @@ class Definition // source references void setBodySegment(int bls,int ble) { - startBodyLine=bls; - endBodyLine=ble; + m_startBodyLine=bls; + m_endBodyLine=ble; } - void setBodyDef(FileDef *fd) { bodyDef=fd; } - int getStartBodyLine() const { return startBodyLine; } - int getEndBodyLine() const { return endBodyLine; } - FileDef *getBodyDef() { return bodyDef; } + void setBodyDef(FileDef *fd) { m_bodyDef=fd; } + int getStartBodyLine() const { return m_startBodyLine; } + int getEndBodyLine() const { return m_endBodyLine; } + FileDef *getBodyDef() { return m_bodyDef; } void writeSourceDef(OutputList &ol,const char *scopeName); void writeInlineCode(OutputList &ol,const char *scopeName); void writeSourceRefs(OutputList &ol,const char *scopeName); @@ -113,28 +115,40 @@ class Definition int bugId() const { return m_bugId; } /*! returns the file in which this definition was found */ - QCString getDefFileName() const { return defFileName; } + QCString getDefFileName() const { return m_defFileName; } /*! returns the line number at which the definition was found */ - int getDefLine() const { return defLine; } + int getDefLine() const { return m_defLine; } + + virtual Definition *findInnerCompound(const char *name); + virtual Definition *getOuterScope() { return m_outerScope; } + virtual void addInnerCompound(Definition *d); + virtual void setOuterScope(Definition *d) { m_outerScope = d; } protected: - int startBodyLine; // line number of the start of the definition - int endBodyLine; // line number of the end of the definition - FileDef *bodyDef; // file definition containing the function body + int m_startBodyLine; // line number of the start of the definition + int m_endBodyLine; // line number of the end of the definition + FileDef *m_bodyDef; // file definition containing the function body // where the item was found - QCString defFileName; - int defLine; + QCString m_defFileName; + int m_defLine; + + /*! The class, namespace in which this class is located + */ + Definition *m_outerScope; + QCString m_name; // name of the definition + QCString m_localName; // local (unqualified) name of the definition + // in the future m_name should become m_localName private: - QCString n; // name of the definition - QCString brief; // brief description - QCString doc; // detailed description - QCString ref; // reference to external documentation - SectionDict *sectionDict; // dictionary of all sections - MemberList *sourceRefList; // list of entities that refer to this + //QCString m_qualifiedName; // name of the definition + QCString m_brief; // brief description + QCString m_doc; // detailed description + QCString m_ref; // reference to external documentation + SectionDict *m_sectionDict; // dictionary of all sections + MemberList *m_sourceRefList; // list of entities that refer to this // entity in their definition - MemberDict *sourceRefDict; + MemberDict *m_sourceRefDict; int m_testId; // id for test list item int m_todoId; // id for todo list item int m_bugId; // id for bug list item diff --git a/src/diagram.cpp b/src/diagram.cpp index 103bd7a..aeb78df 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -916,7 +916,7 @@ void TreeDiagram::drawConnectors(QTextStream &t,Image *image, void clearVisitFlags() { - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { diff --git a/src/doc.l b/src/doc.l index d04a17f..57b694c 100644 --- a/src/doc.l +++ b/src/doc.l @@ -831,6 +831,7 @@ HREF [hH][rR][eE][fF] I [iI] IMG [iI][mM][gG] INPUT [iI][nN][pP][uU][tT] +KBD [kK][bB][dD] LI [lL][iI] META [mM][eE][tT][aA] MULTICOL [mM][uU][lL][tT][iI][cC][oO][lL] @@ -2099,6 +2100,8 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) "" "<"{TT}{ATTR}">" { outDoc->startTypewriter(); } "" { outDoc->endTypewriter(); } +"<"{KBD}{ATTR}">" { outDoc->startTypewriter(); } +"" { outDoc->endTypewriter(); } "<"{EM}{ATTR}">" { outDoc->startEmphasis(); } "" { outDoc->endEmphasis(); } "<"{HR}{ATTR}">" { outDoc->writeRuler(); } diff --git a/src/dot.cpp b/src/dot.cpp index d1bcc76..4aae44d 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "language.h" #include "scanner.h" +#include "defargs.h" #include #include @@ -175,6 +176,141 @@ static bool isLeaf(ClassDef *cd) return TRUE; } +/*! Builds a mapping from formal arguments of class \a tcd to the + * actual arguments stored in templSpec. To properly initialize + * the mapping with the default template values + * ClassDef::initTemplateMapping() is called once for each class graph + * (the ClassDef::visited flag is used for this). + */ +static void setTemplateInstance(QCString templSpec,ClassDef *tcd) +{ + //printf("====== setTemplateInstance(templ=%s,class=%s)\n",templSpec.data(),tcd->name().data()); + if (!templSpec.isEmpty()) + { + //if (!tcd->visited) + //{ + // tcd->visited=TRUE; + //} + ArgumentList *tempArgList = new ArgumentList; + stringToArgumentList(templSpec,tempArgList); + ArgumentListIterator ali(*tempArgList); + Argument *arg; + uint count=0; + for (ali.toFirst();(arg=ali.current());++ali,++count) + { + ArgumentList *formalArgList = tcd->templateArguments(); + Argument *formalArg=0; + //printf("arg->type=%s count=%d formalArgList=%p\n", + // arg->type.data(),count,formalArgList); + if (formalArgList && formalArgList->count()>count && + (formalArg=formalArgList->at(count))) + { + if (formalArg->name!=arg->type) + { + tcd->setTemplateArgumentMapping(formalArg->name,arg->type); + //printf("%s->setTemplateInstantation(%s,%s)\n",tcd->name().data(), + // formalArg->name.data(),arg->type.data()); + } + } + } + delete tempArgList; + } +} + +/*! Substitutes the formal template argument list \a templSpec + * of class \a cd with the actual template arguments. + * The mapping from formal to actual template is assumed to be stored + * in \a cd using setTemplateInstance(). + */ +static QCString substituteTemplateSpec(ClassDef *cd,const QCString &templSpec) +{ + QCString result; + if (!templSpec.isEmpty()) + { + ArgumentList *tempArgList = new ArgumentList; + stringToArgumentList(templSpec,tempArgList); + ArgumentListIterator ali(*tempArgList); + Argument *arg; + bool first=TRUE; + for (ali.toFirst();(arg=ali.current());) + { + if (first) result="<",first=FALSE; + QCString actual = cd->getTemplateArgumentMapping(arg->type); + if (!actual.isEmpty()) + { + result+=actual; + } + else + { + result+=arg->type; + } + ++ali; + if (ali.current()) result+=","; else result+=">"; + } + delete tempArgList; + } + //printf("substituteTemplateSpec(%s,%s)=`%s'\n",cd->name().data(),templSpec.data(),result.data()); + return removeRedundantWhiteSpace(result); +} + +/*! Determines the actual template instance of template class \a tcd that + * relates to class \a cd. The result is stored in \a tcd. + * \param cd A class + * \param tcd A template base class + * \param templSpec Actual template parameter list to be used for tcd + * \param result resulting instance class + * \param actualArg actual template instance name of the resulting class + */ +static void computeTemplateInstance( + ClassDef *cd,ClassDef *tcd,const QCString templSpec, + ClassDef *&result,QCString &actualArg + + ) +{ + //printf("====== computeTemplateInstance(%s,base=%s,templ=%s)\n", + // cd->name().data(),tcd->name().data(),templSpec.data()); + // store the specific instance inside the class + setTemplateInstance(templSpec,tcd); + int tArgNum = tcd->isTemplateBaseClass(); + if (tArgNum!=-1) + { + //printf("tArgNum=%d\n",tArgNum); + ArgumentList *formalArgList = cd->templateArguments(); + if (formalArgList) + { + //printf("formalArgList=%p\n",formalArgList); + Argument *formalArg=formalArgList->at(tArgNum); + if (formalArg) + { + //printf("formalArg=%s\n",formalArg->name.data()); + actualArg = cd->getTemplateArgumentMapping(formalArg->name); + //printf("ActualArg=%s\n",actualArg.data()); + int pos=0; + QCString name; + QCString templSpec; + while (extractClassNameFromType(actualArg,pos,name,templSpec)) + { + //printf("name=%s templSpec=%s\n",name.data(),templSpec.data()); + ClassDef *acd=getResolvedClass(name); + if (acd && !templSpec.isEmpty()) + { + // store specific template instance in the class + setTemplateInstance(templSpec,acd); + } + if (acd) + { + result = acd; + actualArg = acd->name()+templSpec; + return; + } + } + } + } + } + actualArg.resize(0); + result = 0; +} + //-------------------------------------------------------------------- class DotNodeList : public QList @@ -693,8 +829,8 @@ DotGfxHierarchyTable::DotGfxHierarchyTable() // build a graph with each class as a node and the inheritance relations // as edges - initClassHierarchy(&Doxygen::classList); - ClassListIterator cli(Doxygen::classList); + initClassHierarchy(&Doxygen::classSDict); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for (cli.toLast();(cd=cli.current());--cli) { @@ -784,8 +920,8 @@ int DotClassGraph::m_curNodeNumber; void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot, const char *label,int distance,const char *usedName,const char *templSpec,bool base) { - //printf(":: DoxGfxUsageGraph::addClass(class=%s,parent=%s,prot=%d,label=%s,dist=%d)\n", - // cd->name().data(),n->m_label.data(),prot,label,distance); + //printf("DoxClassGraph::addClass(class=%s,parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n", + // cd->name().data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base); int edgeStyle = label ? EdgeInfo::Dashed : EdgeInfo::Solid; QCString className; if (usedName) // name is a typedef @@ -850,11 +986,25 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base) BaseClassDef *bcd; for ( ; (bcd=bcli.current()) ; ++bcli ) { - //printf("addClass: base=%s this=%s templ=%s\n",bcd->classDef->name().data(), - // cd->name().data(),bcd->templSpecifiers.data()); - QCString templSpec; - if (base) templSpec = bcd->templSpecifiers; - addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,templSpec,base); + //printf("-------- inheritance relation %s->%s templ=`%s'\n", + // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data()); + QCString templSpec; + if (base) templSpec = substituteTemplateSpec( + cd,bcd->templSpecifiers); + ClassDef *acd=0; + QCString actualArg; + computeTemplateInstance(cd,bcd->classDef,templSpec,acd,actualArg); + //printf("acd=%p actualArg=%s\n",acd,actualArg.data()); + if (acd) + { + addClass(acd,n,bcd->prot,0,distance,actualArg, + templSpec,base); + } + else + { + addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName, + templSpec,base); + } } if (m_graphType != Inheritance) { @@ -883,8 +1033,25 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base) label+=QCString("\\n")+s; } } - //printf("Found label=`%s'\n",label.data()); - addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0,ucd->templSpecifiers,base); + QCString actualArg; + ClassDef *acd=0; + //printf("-------- usage relation %s->%s templ=`%s'\n", + // cd->name().data(),ucd->classDef->name().data(), + // ucd->templSpecifiers.data()); + QCString templSpec = substituteTemplateSpec( + cd,ucd->templSpecifiers); + computeTemplateInstance(cd,ucd->classDef, templSpec, acd,actualArg); + if (acd) + { + addClass(acd,n,EdgeInfo::Black,label,distance,actualArg, + templSpec,base); + } + else + { + //printf("Found label=`%s'\n",label.data()); + addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0, + templSpec,base); + } } } } @@ -906,6 +1073,11 @@ DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth) ); m_usedNodes = new QDict(1009); m_usedNodes->insert(cd->name(),m_startNode); + + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *icd; + for (cli.toFirst();(icd=cli.current());++cli) icd->initTemplateMapping(); + //printf("Root node %s\n",cd->name().data()); if (m_recDepth>0) { diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 6f41dfd..3c9cd3a 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -65,8 +65,8 @@ #define pclose _pclose #endif -ClassList Doxygen::classList; // all documented classes -ClassDict Doxygen::classDict(1009); +ClassSDict Doxygen::classSDict(1009); +ClassList Doxygen::hiddenClasses; NamespaceList Doxygen::namespaceList; // all namespaces NamespaceDict Doxygen::namespaceDict(257); @@ -107,6 +107,7 @@ QIntDict Doxygen::memberDocDict(1009); // dictionary of the member PageInfo *Doxygen::mainPage = 0; QTextStream Doxygen::tagFile; +NamespaceDef *Doxygen::globalScope = new NamespaceDef("",1,""); static StringList inputFiles; static StringDict excludeNameDict(1009); // sections @@ -119,7 +120,7 @@ void clearAll() excludeNameDict.clear(); delete outputList; outputList=0; - Doxygen::classList.clear(); + Doxygen::classSDict.clear(); Doxygen::namespaceList.clear(); Doxygen::pageSDict->clear(); Doxygen::exampleSDict->clear(); @@ -128,7 +129,7 @@ void clearAll() Doxygen::inputNameList.clear(); Doxygen::groupList.clear(); Doxygen::formulaList.clear(); - Doxygen::classDict.clear(); + Doxygen::classSDict.clear(); Doxygen::namespaceDict.clear(); Doxygen::memberNameDict.clear(); Doxygen::functionNameDict.clear(); @@ -143,6 +144,7 @@ void clearAll() Doxygen::formulaNameDict.clear(); Doxygen::tagDestinationDict.clear(); delete Doxygen::mainPage; Doxygen::mainPage=0; + } void statistics() @@ -155,8 +157,8 @@ void statistics() Doxygen::exampleNameDict->statistics(); fprintf(stderr,"--- imageNameDict stats ----\n"); Doxygen::imageNameDict->statistics(); - fprintf(stderr,"--- classDict stats ----\n"); - Doxygen::classDict.statistics(); + //fprintf(stderr,"--- classDict stats ----\n"); + //Doxygen::classSDict.statistics(); fprintf(stderr,"--- namespaceDict stats ----\n"); Doxygen::namespaceDict.statistics(); fprintf(stderr,"--- memberNameDict stats ----\n"); @@ -639,6 +641,62 @@ static bool addNamespace(Entry *root,ClassDef *cd) return FALSE; } +static Definition *findScope(Entry *root,int level=0) +{ + if (root==0) return 0; + //printf("start findScope name=%s\n",root->name.data()); + Definition *result=0; + if (root->section&Entry::SCOPE_MASK) + { + result = findScope(root->parent,level+1); // traverse to the root of the tree + if (result) + { + //printf("Found %s inside %s at level %d\n",root->name.data(),result->name().data(),level); + // TODO: look at template arguments + result = result->findInnerCompound(root->name); + } + else // reached the global scope + { + // TODO: look at template arguments + result = Doxygen::globalScope->findInnerCompound(root->name); + //printf("Found in globalScope %s at level %d\n",result->name().data(),level); + } + } + //printf("end findScope(%s,%d)=%s\n",root->name.data(), + // level,result==0 ? "" : result->name().data()); + return result; +} + +static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n) +{ + //printf("findScopeFromName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data()); + QCString name(n); + if (startScope==0) startScope=Doxygen::globalScope; + int i = name.find("::"); + if (i==-1) + { + return startScope; + } + + QCString scope; + while ((i = name.find("::"))!=-1) + { + int ti = name.find('<'); + if (ti!=-1 && tifindInnerCompound(nestedNameSpecifier); + if (startScope==0) + { + //printf("name %s not found in scope %s\n",nestedNameSpecifier.data(),oldScope->name().data()); + return 0; + } + name = name.right(name.length()-i-2); + } + //printf("findScopeFromName() result=%s\n",startScope ? startScope->name().data() : 0); + return startScope; +} + //---------------------------------------------------------------------- // build a list of all classes mentioned in the documentation // and all classes that have a documentation block before their definition. @@ -737,6 +795,7 @@ static void buildClassList(Entry *root) } else // new class { + ClassDef::CompoundType sec=ClassDef::Class; switch(root->section) { @@ -823,10 +882,27 @@ static void buildClassList(Entry *root) // add class to the list - Doxygen::classList.inSort(cd); //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); - //classDict.insert(resolveDefines(fullName),cd); - Doxygen::classDict.insert(fullName,cd); + Doxygen::classSDict.inSort(fullName,cd); + + // also add class to the correct structural context + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName); + if (d==0) + { + // TODO: Due to the order in which the tag file is written + // a nested class can be found before its parent! + // + //warn(root->fileName,root->startLine, + // "Warning: Internal inconsistency: scope for class %s not " + // "found!\n",fullName.data() + // ); + } + else + { + //printf("****** adding %s to scope %s\n",cd->name().data(),d->name().data()); + d->addInnerCompound(cd); + cd->setOuterScope(d); + } } } } @@ -927,6 +1003,23 @@ static void buildNamespaceList(Entry *root) Doxygen::namespaceList.inSort(nd); Doxygen::namespaceDict.insert(fullName,nd); + // also add namespace to the correct structural context + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName); + if (d==0) + { + // TODO: Due to the order in which the tag file is written + // a nested class can be found before its parent! + // + //warn(root->fileName,root->startLine, + // "Warning: Internal inconsistency: scope for namespace %s not " + // "found!\n",fullName.data() + // ); + } + else + { + d->addInnerCompound(nd); + nd->setOuterScope(d); + } } } } @@ -2247,8 +2340,11 @@ static void replaceNamespaceAliases(QCString &scope,int i) } -static bool findBaseClassRelation(Entry *root,ClassDef *cd, +static bool findBaseClassRelation( + Entry *root, + ClassDef *cd, BaseInfo *bi, + int isTemplBaseClass, bool insertUndocumented ) { @@ -2416,7 +2512,7 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd, } } } - if (found) + if (isTemplBaseClass==-1 && found) { Debug::print(Debug::Classes,0," Documented base class `%s'\n",bi->name.data()); // add base class to this class @@ -2427,7 +2523,7 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd, baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); return TRUE; } - else if (scopeOffset==0 && insertUndocumented) + else if ((scopeOffset==0 && insertUndocumented) || isTemplBaseClass!=-1) { Debug::print(Debug::Classes,0, " Undocumented base class `%s' baseClassName=%s\n", @@ -2441,12 +2537,18 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd, baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); // the undocumented base was found in this file baseClass->insertUsedFile(root->fileName); + // is this an inherited template argument? + //printf("%s->setIsTemplateBaseClass(%d)\n",baseClass->name().data(),isTemplBaseClass); + baseClass->setIsTemplateBaseClass(isTemplBaseClass); // add class to the list - //classList.inSort(baseClass); - Doxygen::classList.inSort(baseClass); - //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); - //classDict.insert(resolveDefines(bi->name),baseClass); - Doxygen::classDict.insert(baseClassName,baseClass); + if (isTemplBaseClass==-1) + { + Doxygen::classSDict.inSort(baseClassName,baseClass); + } + else + { + Doxygen::hiddenClasses.append(baseClass); + } return TRUE; } else @@ -2511,16 +2613,34 @@ static void computeClassRelations(Entry *root) cd->visited=TRUE; // mark class as used if (root->extends->count()>0) // there are base classes { + // The base class could ofcouse also be a non-nested class QList *baseList=root->extends; BaseInfo *bi=baseList->first(); while (bi) // for each base class { + // check if the base class is a template argument + int isTemplBaseClass = -1; + ArgumentList *tl = cd->templateArguments(); + if (tl) + { + ArgumentListIterator ali(*tl); + Argument *arg; + int count=0; + for (ali.toFirst();(arg=ali.current());++ali,++count) + { + if (arg->name==bi->name) // base class is a template argument + { + isTemplBaseClass = count; + break; + } + } + } // find a documented base class in the correct scope - if (!findBaseClassRelation(root,cd,bi,FALSE)) + if (!findBaseClassRelation(root,cd,bi,isTemplBaseClass,FALSE)) { // no documented base class -> try to find an undocumented one - findBaseClassRelation(root,cd,bi,TRUE); + findBaseClassRelation(root,cd,bi,isTemplBaseClass,TRUE); } bi=baseList->next(); } @@ -2550,11 +2670,11 @@ static void computeClassRelations(Entry *root) static void computeMemberReferences() { - ClassDef *cd=Doxygen::classList.first(); - while (cd) + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; + for (cli.toFirst();(cd=cli.current());++cli) { cd->computeAnchors(); - cd=Doxygen::classList.next(); } FileName *fn=Doxygen::inputNameList.first(); while (fn) @@ -2585,14 +2705,14 @@ static void computeMemberReferences() static void addTodoTestBugReferences() { - ClassDef *cd=Doxygen::classList.first(); - while (cd) + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; + for (cli.toFirst();(cd=cli.current());++cli) { addRefItem(cd->todoId(),cd->testId(),cd->bugId(), theTranslator->trClass(TRUE,TRUE), cd->getOutputFileBase(),cd->name() ); - cd=Doxygen::classList.next(); } FileName *fn=Doxygen::inputNameList.first(); while (fn) @@ -4115,39 +4235,41 @@ static void findEnums(Entry *root) { MemberNameIterator fmni(*fmn); MemberDef *fmd; - for (fmni.toFirst(); - (fmd=fmni.current()) && fmd->isEnumValue(); - ++fmni - ) // search for the scope with the right name + for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) { - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (fmd->isEnumValue()) { - NamespaceDef *fnd=fmd->getNamespaceDef(); - if (fnd==nd) // enum value is inside a namespace + if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + NamespaceDef *fnd=fmd->getNamespaceDef(); + if (fnd==nd) // enum value is inside a namespace + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } } - } - else if (isGlobal) - { - FileDef *ffd=fmd->getFileDef(); - if (ffd==fd) // enum value has file scope + else if (isGlobal) { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + FileDef *ffd=fmd->getFileDef(); + if (ffd==fd) // enum value has file scope + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } } - } - else - { - ClassDef *fcd=fmd->getClassDef(); - if (fcd==cd) // enum value is inside a class + else { - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + ClassDef *fcd=fmd->getClassDef(); + if (fcd==cd) // enum value is inside a class + { + //printf("Inserting enum field %s in enum scope %s\n", + // fmd->name().data(),md->name().data()); + md->insertEnumField(fmd); // add field def to list + fmd->setEnumScope(md); // cross ref with enum name + } } - } - } + } + } } } } @@ -4373,7 +4495,7 @@ static void computeMemberRelations() static void computeClassImplUsageRelations() { ClassDef *cd; - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for (;(cd=cli.current());++cli) { cd->determineImplUsageRelation(); @@ -4388,7 +4510,7 @@ static void buildCompleteMemberLists() { ClassDef *cd; // merge the member list of base classes into the inherited classes. - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for (cli.toFirst();(cd=cli.current());++cli) { if (!cd->isReference() && // not an external class @@ -4401,7 +4523,7 @@ static void buildCompleteMemberLists() // now sort the member list of all classes. for (cli.toFirst();(cd=cli.current());++cli) { - cd->memberNameInfoList()->sort(); + cd->memberNameInfoSDict()->sort(); } } @@ -4463,7 +4585,7 @@ static void generateFileDocs() static void addSourceReferences() { // add source references for class definitions - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { @@ -4568,7 +4690,7 @@ static void generateClassDocs() msg("Generating example index...\n"); } - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for ( ; cli.current() ; ++cli ) { ClassDef *cd=cli.current(); @@ -4621,7 +4743,7 @@ static void inheritDocumentation() static void addMembersToMemberGroup() { // for each class - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { @@ -4660,7 +4782,7 @@ static void addMembersToMemberGroup() static void distributeMemberGroupDocumentation() { // for each class - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { @@ -4923,7 +5045,7 @@ static void buildPackageList(Entry *root) static void addClassesToPackages() { ClassDef *cd; - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for (;(cd=cli.current());++cli) { PackageDef *pd = cd->packageDef(); @@ -4974,7 +5096,7 @@ static void generatePageDocs() if (!pi->inGroup && !pi->isReference()) { msg("Generating docs for page %s...\n",pi->name.data()); - outputList->disable(OutputGenerator::Man); + //outputList->disable(OutputGenerator::Man); QCString pageName; if (Config_getBool("CASE_SENSE_NAMES")) pageName=pi->name.copy(); @@ -4982,19 +5104,29 @@ static void generatePageDocs() pageName=pi->name.lower(); startFile(*outputList,pageName,pi->title); + + startFile(*outputList,pageName,pi->title); + + // save old generator state and write title only to Man generator + outputList->pushGeneratorState(); + outputList->disableAllBut(OutputGenerator::Man); + outputList->startTitleHead(pageName); + outputList->endTitleHead(pageName, pageName); + outputList->popGeneratorState(); + SectionInfo *si=0; if (!pi->title.isEmpty() && !pi->name.isEmpty() && (si=Doxygen::sectionDict.find(pi->name))!=0) { - outputList->startSection(si->label,si->title,FALSE); + outputList->startSection(si->label,si->title,si->type==SectionInfo::Subsection); outputList->docify(si->title); - outputList->endSection(si->label,FALSE); + outputList->endSection(si->label,si->type==SectionInfo::Subsection); } outputList->startTextBlock(); parseDoc(*outputList,pi->defFileName,pi->defLine,0,0,pi->doc); outputList->endTextBlock(); endFile(*outputList); - outputList->enable(OutputGenerator::Man); + //outputList->enable(OutputGenerator::Man); if (!Config_getString("GENERATE_TAGFILE").isEmpty() && pi->name!="todo" && pi->name!="test") { @@ -5287,7 +5419,8 @@ static bool openOutputFile(const char *outFile,QFile &f) * If the \a shortList parameter is TRUE a configuration file without * comments will be generated. */ -static void generateConfigFile(const char *configFile,bool shortList) +static void generateConfigFile(const char *configFile,bool shortList, + bool updateOnly=FALSE) { QFile f; bool fileOpened=openOutputFile(configFile,f); @@ -5297,13 +5430,20 @@ static void generateConfigFile(const char *configFile,bool shortList) Config::instance()->writeTemplate(&f,shortList); if (!writeToStdout) { - msg("\n\nConfiguration file `%s' created.\n\n",configFile); - msg("Now edit the configuration file and enter\n\n"); - if (strcmp(configFile,"Doxyfile") || strcmp(configFile,"doxyfile")) - msg(" doxygen %s\n\n",configFile); + if (!updateOnly) + { + msg("\n\nConfiguration file `%s' created.\n\n",configFile); + msg("Now edit the configuration file and enter\n\n"); + if (strcmp(configFile,"Doxyfile") || strcmp(configFile,"doxyfile")) + msg(" doxygen %s\n\n",configFile); + else + msg(" doxygen\n\n"); + msg("to generate the documentation for your project\n\n"); + } else - msg(" doxygen\n\n"); - msg("to generate the documentation for your project\n\n"); + { + msg("\n\nConfiguration file `%s' updated.\n\n",configFile); + } } } else @@ -6014,7 +6154,7 @@ void readConfiguration(int argc, char **argv) if (updateConfig) { - generateConfigFile(configName,shortList); + generateConfigFile(configName,shortList,TRUE); exit(1); } diff --git a/src/doxygen.h b/src/doxygen.h index ed661c4..f81241a 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -40,9 +40,15 @@ class PageInfo; typedef QList StringList; typedef QDict FileDict; -typedef QDict StringDict; typedef QDict GroupDict; +class StringDict : public QDict +{ + public: + StringDict(uint size=17) : QDict(size) {} + virtual ~StringDict() {} +}; + extern QCString spaces; /*! \brief This class serves as a namespace for global variables used by doxygen. @@ -52,8 +58,8 @@ extern QCString spaces; class Doxygen { public: - static ClassList classList; - static ClassDict classDict; + static ClassSDict classSDict; + static ClassList hiddenClasses; static PageSDict *exampleSDict; static PageSDict *pageSDict; static PageInfo *mainPage; @@ -87,6 +93,7 @@ class Doxygen static QIntDict memberDocDict; // dictionary of the member groups heading static QDict expandAsDefinedDict; static PackageSDict packageDict; + static NamespaceDef *globalScope; }; void initDoxygen(); diff --git a/src/example.h b/src/example.h index 425b488..4c0ab15 100644 --- a/src/example.h +++ b/src/example.h @@ -31,22 +31,33 @@ struct Example QCString file; }; -class ExampleList : public QList +//class ExampleList : public QList +//{ +// public: +// ExampleList() : QList() {} +// ~ExampleList() {} +// int compareItems(GCI item1,GCI item2) +// { +// return stricmp(((Example *)item1)->name,((Example *)item2)->name); +// } +//}; + +//class ExampleDict : public QDict +//{ +// public: +// ExampleDict(int size=17) : QDict(size) {} +// ~ExampleDict() {} +//}; + +class ExampleSDict : public SDict { public: - ExampleList() : QList() {} - ~ExampleList() {} + ExampleSDict(int size=17) : SDict(size) {} + ~ExampleSDict() {} int compareItems(GCI item1,GCI item2) { return stricmp(((Example *)item1)->name,((Example *)item2)->name); } }; -class ExampleDict : public QDict -{ - public: - ExampleDict(int size=17) : QDict(size) {} - ~ExampleDict() {} -}; - #endif diff --git a/src/filedef.cpp b/src/filedef.cpp index e2fcb76..5974f87 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -44,7 +44,7 @@ FileDef::FileDef(const char *p,const char *nm,const char *lref) filename=nm; diskname=nm; setReference(lref); - classList = new ClassList; + classSDict = new ClassSDict(17); includeList = new QList; includeList->setAutoDelete(TRUE); includeDict = new QDict(61); @@ -72,7 +72,7 @@ FileDef::FileDef(const char *p,const char *nm,const char *lref) /*! destroy the file definition */ FileDef::~FileDef() { - delete classList; + delete classSDict; delete includeDict; delete includeList; delete namespaceList; @@ -298,7 +298,7 @@ void FileDef::writeDocumentation(OutputList &ol) if (found) ol.endMemberList(); } - classList->writeDeclaration(ol); + classSDict->writeDeclaration(ol); /* write user defined member groups */ MemberGroupListIterator mgli(*memberGroupList); @@ -545,9 +545,9 @@ void FileDef::insertMember(MemberDef *md) void FileDef::insertClass(ClassDef *cd) { if (Config_getBool("SORT_MEMBER_DOCS")) - classList->inSort(cd); + classSDict->inSort(cd->name(),cd); else - classList->append(cd); + classSDict->append(cd->name(),cd); } /*! Adds namespace definition \a nd to the list of all compounds of this file */ diff --git a/src/filedef.h b/src/filedef.h index 26a297d..2bdbbcf 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -29,8 +29,9 @@ class FileDef; class FileList; -class ClassList; +class ClassSDict; class ClassDef; +class ClassList; class MemberDef; class OutputList; class NamespaceDef; @@ -168,7 +169,7 @@ class FileDef : public Definition private: - ClassList *classList; + ClassSDict *classSDict; QDict *includeDict; QList *includeList; QDict *includedByDict; diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 18f616a..44389f3 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -36,7 +36,7 @@ GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t) : Definition(df,dl,na) { fileList = new FileList; - classList = new ClassList; + classSDict = new ClassSDict(257); groupList = new GroupList; parentGroupList = new GroupList; namespaceList = new NamespaceList; @@ -78,7 +78,7 @@ GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t) : GroupDef::~GroupDef() { delete fileList; - delete classList; + delete classSDict; delete groupList; delete parentGroupList; delete namespaceList; @@ -108,12 +108,12 @@ void GroupDef::addFile(const FileDef *def) fileList->append(def); } -void GroupDef::addClass(const ClassDef *def) +void GroupDef::addClass(const ClassDef *cd) { if (Config_getBool("SORT_MEMBER_DOCS")) - classList->inSort(def); + classSDict->inSort(cd->name(),cd); else - classList->append(def); + classSDict->append(cd->name(),cd); } void GroupDef::addNamespace(const NamespaceDef *def) @@ -135,51 +135,9 @@ void GroupDef::addExample(const PageInfo *def) exampleDict->append(def->name,def); } -#if 0 -void GroupDef::addMemberListToGroup(MemberList *ml, - bool (MemberDef::*func)() const) -{ - if (ml==0) return; - MemberListIterator mli(*ml); - MemberDef *md; - for (;(md=mli.current());++mli) - { - int groupId=md->getMemberGroupId(); - if ((md->*func)() && groupId!=-1) - { - QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId]; - QCString *pDocs = Doxygen::memberDocDict[groupId]; - if (pGrpHeader) - { - MemberGroup *mg = memberGroupDict->find(groupId); - if (mg==0) - { - mg = new MemberGroup(groupId,*pGrpHeader,pDocs ? pDocs->data() : 0); - memberGroupDict->insert(groupId,mg); - memberGroupList->append(mg); - } - mg->insertMember(md); - md->setMemberGroup(mg); - } - } - } -} -#endif - void GroupDef::addMembersToMemberGroup() { -#if 0 - addMemberListToGroup(allMemberList,&MemberDef::isDefine); - addMemberListToGroup(allMemberList,&MemberDef::isTypedef); - addMemberListToGroup(allMemberList,&MemberDef::isEnumerate); - addMemberListToGroup(allMemberList,&MemberDef::isEnumValue); - addMemberListToGroup(allMemberList,&MemberDef::isFunction); - addMemberListToGroup(allMemberList,&MemberDef::isSlot); - addMemberListToGroup(allMemberList,&MemberDef::isSignal); - addMemberListToGroup(allMemberList,&MemberDef::isVariable); -#endif - ::addMembersToMemberGroup(&decDefineMembers,memberGroupDict,memberGroupList); ::addMembersToMemberGroup(&decProtoMembers,memberGroupDict,memberGroupList); ::addMembersToMemberGroup(&decTypedefMembers,memberGroupDict,memberGroupList); @@ -198,7 +156,7 @@ void GroupDef::addMembersToMemberGroup() } -void GroupDef::insertMember(MemberDef *md) +void GroupDef::insertMember(MemberDef *md,bool docOnly) { //printf("GroupDef::insertMember(%s)\n",md->name().data()); MemberNameInfo *mni=0; @@ -226,28 +184,28 @@ void GroupDef::insertMember(MemberDef *md) switch(md->memberType()) { case MemberDef::Variable: - decVarMembers.append(md); + if (!docOnly) decVarMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docVarMembers.inSort(md); else docVarMembers.append(md); break; case MemberDef::Function: - decFuncMembers.append(md); + if (!docOnly) decFuncMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docFuncMembers.inSort(md); else docFuncMembers.append(md); break; case MemberDef::Typedef: - decTypedefMembers.append(md); + if (!docOnly) decTypedefMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docTypedefMembers.inSort(md); else docTypedefMembers.append(md); break; case MemberDef::Enumeration: - decEnumMembers.append(md); + if (!docOnly) decEnumMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docEnumMembers.inSort(md); else @@ -256,14 +214,14 @@ void GroupDef::insertMember(MemberDef *md) case MemberDef::EnumValue: break; case MemberDef::Prototype: - decProtoMembers.append(md); + if (!docOnly) decProtoMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docProtoMembers.inSort(md); else docProtoMembers.append(md); break; case MemberDef::Define: - decDefineMembers.append(md); + if (!docOnly) decDefineMembers.append(md); if (Config_getBool("SORT_MEMBER_DOCS")) docDefineMembers.inSort(md); else @@ -304,7 +262,7 @@ bool GroupDef::isASubGroup() const int GroupDef::countMembers() const { return fileList->count()+ - classList->count()+ + classSDict->count()+ namespaceList->count()+ groupList->count()+ allMemberList->count()+ @@ -332,7 +290,7 @@ void GroupDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,defFileName,defLine,name(),0,briefDescription()); + parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); ol+=briefOutput; ol.writeString(" \n"); ol.pushGeneratorState(); @@ -375,7 +333,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,defFileName,defLine,0,0,fd->briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,0,0,fd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -404,7 +362,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,defFileName,defLine,0,0,nd->briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,0,0,nd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -432,7 +390,7 @@ void GroupDef::writeDocumentation(OutputList &ol) if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC")) { ol.startMemberDescription(); - parseDoc(ol,defFileName,defLine,0,0,gd->briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,0,0,gd->briefDescription()); ol.endMemberDescription(); ol.newParagraph(); } @@ -441,7 +399,7 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.endMemberList(); } - classList->writeDeclaration(ol); + classSDict->writeDeclaration(ol); if (allMemberList->count()>0) { @@ -490,7 +448,7 @@ void GroupDef::writeDocumentation(OutputList &ol) // write documentation if (!documentation().isEmpty()) { - parseDoc(ol,defFileName,defLine,name(),0,documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); } } PageInfo *pi=0; @@ -604,6 +562,7 @@ void addMemberToGroups(Entry *root,MemberDef *md) QCString *s; for (;(s=sli.current());++sli) { + //printf("addMemberToGroups(group=%s,member=%s)\n",s->data(),md->name().data()); GroupDef *gd=0; if (!s->isEmpty() && (gd=Doxygen::groupDict[*s])) { @@ -612,6 +571,8 @@ void addMemberToGroups(Entry *root,MemberDef *md) { gd->insertMember(md); md->setGroupDef(gd); + ClassDef *cd = md->getClassDefOfAnonymousType(); + if (cd) cd->setGroupDefForAllMembers(gd); } else if (mgd!=gd) { diff --git a/src/groupdef.h b/src/groupdef.h index e55c727..73eaf94 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -27,7 +27,7 @@ #include "htmlhelp.h" class FileList; -class ClassList; +class ClassSDict; class FileDef; class ClassDef; class NamespaceDef; @@ -55,7 +55,7 @@ class GroupDef : public Definition void addParentGroup(const GroupDef *def); void addPage(PageInfo *def); // pages in this group void addExample(const PageInfo *def); // examples in this group - void insertMember(MemberDef *def); + void insertMember(MemberDef *def,bool docOnly=FALSE); void writeDocumentation(OutputList &ol); int countMembers() const; bool isLinkableInProject() @@ -84,7 +84,7 @@ class GroupDef : public Definition QCString title; // title of the group QCString fileName; // base name of the generated file FileList *fileList; // list of files in the group - ClassList *classList; // list of classes in the group + ClassSDict *classSDict; // list of classes in the group NamespaceList *namespaceList; // list of namespaces in the group GroupList *groupList; // list of sub groups. GroupList *parentGroupList; // list of parent groups. diff --git a/src/index.cpp b/src/index.cpp index 1c0c3c4..8954cd3 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -469,26 +469,8 @@ void writeClassTree(BaseClassList *cl) //---------------------------------------------------------------------------- /*! Generates HTML Help tree of classes */ -void writeClassTree(ClassList *cl) +void writeClassTreeNode(ClassDef *cd,bool hasHtmlHelp,bool hasFtvHelp,bool &started) { - HtmlHelp *htmlHelp=0; - FTVHelp *ftvHelp=0; - bool &generateHtml = Config_getBool("GENERATE_HTML") ; - bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP"); - bool hasFtvHelp = generateHtml && Config_getBool("GENERATE_TREEVIEW"); - if (hasHtmlHelp) - { - htmlHelp = HtmlHelp::getInstance(); - } - if (hasFtvHelp) - { - ftvHelp = FTVHelp::getInstance(); - } - ClassListIterator cli(*cl); - bool started=FALSE; - for ( ; cli.current() ; ++cli) - { - ClassDef *cd=cli.current(); if (cd->isVisibleInHierarchy() && !cd->visited) { if (!started) @@ -500,11 +482,11 @@ void writeClassTree(ClassList *cl) { if (hasHtmlHelp) { - htmlHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase()); + HtmlHelp::getInstance()->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase()); } if (hasFtvHelp) { - ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name()); + FTVHelp::getInstance()->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name()); } } if (hasChildren) @@ -513,6 +495,31 @@ void writeClassTree(ClassList *cl) } cd->visited=TRUE; } +} + +void writeClassTree(ClassList *cl) +{ + bool &generateHtml = Config_getBool("GENERATE_HTML") ; + bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP"); + bool hasFtvHelp = generateHtml && Config_getBool("GENERATE_TREEVIEW"); + ClassListIterator cli(*cl); + bool started=FALSE; + for ( ; cli.current() ; ++cli) + { + writeClassTreeNode(cli.current(),hasHtmlHelp,hasFtvHelp,started); + } +} + +void writeClassTree(ClassSDict *d) +{ + bool &generateHtml = Config_getBool("GENERATE_HTML") ; + bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP"); + bool hasFtvHelp = generateHtml && Config_getBool("GENERATE_TREEVIEW"); + ClassSDict::Iterator cli(*d); + bool started=FALSE; + for ( ; cli.current() ; ++cli) + { + writeClassTreeNode(cli.current(),hasHtmlHelp,hasFtvHelp,started); } } @@ -520,7 +527,7 @@ void writeClassTree(ClassList *cl) void writeClassHierarchy(OutputList &ol) { - initClassHierarchy(&Doxygen::classList); + initClassHierarchy(&Doxygen::classSDict); HtmlHelp *htmlHelp=0; FTVHelp *ftvHelp=0; @@ -537,7 +544,7 @@ void writeClassHierarchy(OutputList &ol) } bool started=FALSE; - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for (;cli.current(); ++cli) { ClassDef *cd=cli.current(); @@ -546,9 +553,9 @@ void writeClassHierarchy(OutputList &ol) // hasVisibleRoot(cd->baseClasses()), // cd->isVisibleInHierarchy() // ); - if (!hasVisibleRoot(cd->baseClasses())) + if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes { - if (cd->isVisibleInHierarchy()) + if (cd->isVisibleInHierarchy()) // should it be visible { if (!started) { @@ -560,6 +567,7 @@ void writeClassHierarchy(OutputList &ol) bool hasChildren = !cd->visited && cd->subClasses()->count()>0; if (cd->isLinkable()) { + //printf("Writing class %s\n",cd->name().data()); ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->displayName()); if (cd->isReference()) { @@ -609,9 +617,9 @@ void writeClassHierarchy(OutputList &ol) // TODO: let this function return the real number of items in the hierarchy. int countClassHierarchy() { - initClassHierarchy(&Doxygen::classList); + initClassHierarchy(&Doxygen::classSDict); int count=0; - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); for ( ; cli.current(); ++cli) { if (cli.current()->subClasses()->count()>0) count++; @@ -1060,7 +1068,7 @@ int countAnnotatedClasses() { int count=0; //ClassDef *cd=Doxygen::classList.first(); - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { @@ -1083,7 +1091,7 @@ void writeAnnotatedClassList(OutputList &ol) ol.startIndexList(); //ClassDef *cd=Doxygen::classList.first(); //while (cd) - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { @@ -1164,7 +1172,7 @@ void writeAlphabeticalClassList(OutputList &ol) ol.startAlphabeticalIndexList(); // first count the number of headers - ClassListIterator cli(Doxygen::classList); + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; char startLetter=0; int headerItems=0; @@ -2167,15 +2175,33 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,bool subLevel) // write group info bool hasSubGroups = gd->groupList->count()>0; bool hasSubPages = gd->pageDict->count()>0; + int numSubItems = 0; + if( Config_getBool("TOC_EXPAND")) + { + numSubItems += gd->docDefineMembers.count(); + numSubItems += gd->docTypedefMembers.count(); + numSubItems += gd->docEnumMembers.count(); + numSubItems += gd->docEnumValMembers.count(); + numSubItems += gd->docFuncMembers.count(); + numSubItems += gd->docVarMembers.count(); + numSubItems += gd->docProtoMembers.count(); + numSubItems += gd->namespaceList->count(); + numSubItems += gd->classSDict->count(); + numSubItems += gd->fileList->count(); + numSubItems += gd->exampleDict->count(); + } + + bool isDir = hasSubGroups || hasSubPages || numSubItems>0; //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); if(htmlHelp) { - htmlHelp->addContentsItem(hasSubGroups || hasSubPages,gd->groupTitle(),gd->getOutputFileBase()); + htmlHelp->addContentsItem(isDir,gd->groupTitle(),gd->getOutputFileBase()); htmlHelp->incContentsDepth(); } if(ftvHelp) { - ftvHelp->addContentsItem(hasSubGroups || hasSubPages,gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); + ftvHelp->addContentsItem(isDir,gd->getReference(),gd->getOutputFileBase(), + 0,gd->groupTitle()); ftvHelp->incContentsDepth(); } @@ -2324,7 +2350,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,bool subLevel) } // write classes - if(gd->classList->count()>0) + if(gd->classSDict->count()>0) { if(htmlHelp) { @@ -2339,7 +2365,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,bool subLevel) ftvHelp->incContentsDepth(); } - writeClassTree(gd->classList); + writeClassTree(gd->classSDict); if(htmlHelp) htmlHelp->decContentsDepth(); if(ftvHelp) ftvHelp->decContentsDepth(); } diff --git a/src/language.cpp b/src/language.cpp index 35e92bd..5c3ee5d 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -39,6 +39,7 @@ #include "translator_cn.h" #include "translator_no.h" #include "translator_br.h" +#include "translator_dk.h" #endif #define L_EQUAL(a) !stricmp(langName,a) @@ -132,6 +133,10 @@ bool setTranslator(const char *langName) { theTranslator=new TranslatorBrazilian; } + else if (L_EQUAL("danish")) + { + theTranslator=new TranslatorDanish; + } #endif else // use the default language (i.e. english) { diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 00f12e9..8fb0a50 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -536,9 +536,10 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassDef *cd=Doxygen::classList.first(); + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; bool found=FALSE; - while (cd && !found) + for (cli.toFirst();(cd=cli.current()) && !found;++cli) { if (cd->isLinkableInProject()) { @@ -546,7 +547,6 @@ void LatexGenerator::startIndexSection(IndexSections is) t << "{"; //Compound Documentation}\n"; found=TRUE; } - cd=Doxygen::classList.next(); } } break; @@ -703,25 +703,24 @@ void LatexGenerator::endIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassDef *cd=Doxygen::classList.first(); + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; bool found=FALSE; - while (cd && !found) + for (cli.toFirst();(cd=cli.current()) && !found;++cli) { if (cd->isLinkableInProject()) { t << "}\n\\input{" << cd->getOutputFileBase() << "}\n"; found=TRUE; } - cd=Doxygen::classList.next(); } - while (cd) + for (;(cd=cli.current());++cli) { if (cd->isLinkableInProject()) { if (compactLatex) t << "\\input"; else t << "\\include"; t << "{" << cd->getOutputFileBase() << "}\n"; } - cd=Doxygen::classList.next(); } } break; diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index a371d00..428c15f 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -20,7 +20,6 @@ HEADERS = bufstr.h \ classdef.h \ classlist.h \ code.h \ - config.h \ constexp.h \ cppvalue.h \ debug.h \ @@ -98,7 +97,6 @@ SOURCES = ce_lex.cpp \ classdef.cpp \ classlist.cpp \ code.cpp \ - config.cpp \ cppvalue.cpp \ debug.cpp \ declinfo.cpp \ @@ -124,7 +122,6 @@ SOURCES = ce_lex.cpp \ language.cpp \ latexgen.cpp \ logos.cpp \ - main.cpp \ mangen.cpp \ memberdef.cpp \ membergroup.cpp \ diff --git a/src/mangen.cpp b/src/mangen.cpp index 758be75..2082e2b 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -28,14 +28,31 @@ #include "util.h" #include "doxygen.h" +static QCString getExtension() +{ + QCString ext = Config_getString("MAN_EXTENSION"); + if( ext.length() >= 2 && + ext.data()[0] == '.' && + isdigit( ext.data()[1] ) ) + { + ext = ext.mid(1, 1); + } + else + { + ext = "3"; + } + return ext; +} + ManGenerator::ManGenerator() : OutputGenerator() { - dir=Config_getString("MAN_OUTPUT")+"/man3"; + dir=Config_getString("MAN_OUTPUT")+"/man" + getExtension(); firstCol=TRUE; paragraph=FALSE; col=0; upperCase=FALSE; insideTabbing=FALSE; + inHeader=FALSE; } ManGenerator::~ManGenerator() @@ -54,21 +71,25 @@ void ManGenerator::append(const OutputGenerator *g) else firstCol = ((ManGenerator *)g)->firstCol; col+=((ManGenerator *)g)->col; + inHeader=((ManGenerator *)g)->inHeader; paragraph=FALSE; } void ManGenerator::init() { - QDir d(Config_getString("MAN_OUTPUT")); - if (!d.exists() && !d.mkdir(Config_getString("MAN_OUTPUT"))) + QCString ext = getExtension(); + QCString &manOutput = Config_getString("MAN_OUTPUT"); + + QDir d(manOutput); + if (!d.exists() && !d.mkdir(manOutput)) { - err("Could not create output directory %s\n",Config_getString("MAN_OUTPUT").data()); + err("Could not create output directory %s\n",manOutput.data()); exit(1); } - d.setPath(Config_getString("MAN_OUTPUT")+"/man3"); - if (!d.exists() && !d.mkdir(Config_getString("MAN_OUTPUT")+"/man3")) + d.setPath(manOutput+"/man"+ext); + if (!d.exists() && !d.mkdir(manOutput+"/man"+ext)) { - err("Could not create output directory %s/man3\n",Config_getString("MAN_OUTPUT").data()); + err("Could not create output directory %s/man%s\n",manOutput.data(),ext.data()); exit(1); } } @@ -123,7 +144,8 @@ void ManGenerator::endFile() void ManGenerator::endTitleHead(const char *,const char *name) { - t << ".TH \"" << name << "\" 3 \"" << dateToString(FALSE) << "\" \""; + t << ".TH \"" << name << "\" " << getExtension() << " \"" + << dateToString(FALSE) << "\" \""; if (Config_getString("PROJECT_NAME").isEmpty()) t << "Doxygen"; else @@ -134,6 +156,7 @@ void ManGenerator::endTitleHead(const char *,const char *name) t << ".SH NAME" << endl; t << name << " \\- "; firstCol=FALSE; + inHeader=TRUE; } void ManGenerator::newParagraph() @@ -470,3 +493,42 @@ void ManGenerator::endMemberGroup(bool) t << "\n.in -1c"; firstCol=FALSE; } + +void ManGenerator::startSection(const char *,const char *,bool sub) +{ + if( !inHeader ) + { + if( sub ) + { + startMemberHeader(); + } + else + { + startGroupHeader(); + } + } +} + +void ManGenerator::endSection(const char *,bool sub) +{ + if( !inHeader ) + { + if( sub ) + { + endMemberHeader(); + } + else + { + endGroupHeader(); + } + } + else + { + t << "\n"; + firstCol=TRUE; + paragraph=FALSE; + inHeader=FALSE; + } +} + + diff --git a/src/mangen.h b/src/mangen.h index dec3159..8b841df 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -175,8 +175,8 @@ class ManGenerator : public OutputGenerator void endParamList() { endDescList(); } void endDescTitle(); void writeDescItem(); - void startSection(const char *,const char *,bool) {} - void endSection(const char *,bool) {} + void startSection(const char *,const char *,bool); + void endSection(const char *,bool); void writeSectionRef(const char *,const char *,const char *,const char *) {} void writeSectionRefItem(const char *,const char *,const char *) {} //void writeSectionRefAnchor(const char *,const char *,const char *) {} @@ -231,6 +231,7 @@ class ManGenerator : public OutputGenerator int col; bool upperCase; bool insideTabbing; + bool inHeader; ManGenerator(const ManGenerator &g); ManGenerator &operator=(const ManGenerator &g); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 75b5c21..f64eb96 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -241,8 +241,7 @@ MemberDef::MemberDef(const char *df,int dl, memDec=0; group=0; grpId=-1; - exampleList=0; - exampleDict=0; + exampleSDict=0; enumFields=0; enumScope=0; enumDeclList=0; @@ -271,6 +270,7 @@ MemberDef::MemberDef(const char *df,int dl, indDepth=0; section=0; explExt=FALSE; + cachedAnonymousType=0; maxInitLines=Config_getInt("MAX_INITIALIZER_LINES"); userInitLines=-1; docEnumValues=FALSE; @@ -315,8 +315,7 @@ MemberDef::MemberDef(const char *df,int dl, MemberDef::~MemberDef() { delete redefinedBy; - delete exampleList; - delete exampleDict; + delete exampleSDict; delete enumFields; delete argList; delete tArgList; @@ -338,17 +337,15 @@ bool MemberDef::addExample(const char *anchor,const char *nameStr, const char *file) { //printf("%s::addExample(%s,%s,%s)\n",name.data(),anchor,nameStr,file); - if (exampleDict==0) exampleDict = new ExampleDict; - if (exampleList==0) exampleList = new ExampleList; - if (exampleDict->find(nameStr)==0) + if (exampleSDict==0) exampleSDict = new ExampleSDict; + if (exampleSDict->find(nameStr)==0) { //printf("Add reference to example %s to member %s\n",nameStr,name.data()); Example *e=new Example; e->anchor=anchor; e->name=nameStr; e->file=file; - exampleDict->insert(nameStr,e); - exampleList->inSort(e); + exampleSDict->inSort(nameStr,e); return TRUE; } return FALSE; @@ -356,32 +353,12 @@ bool MemberDef::addExample(const char *anchor,const char *nameStr, bool MemberDef::hasExamples() { - if (exampleList==0) + if (exampleSDict==0) return FALSE; else - return exampleList->count()>0; + return exampleSDict->count()>0; } -#if 0 -void MemberDef::writeExample(OutputList &ol) -{ - Example *e=exampleList->first(); - while (e) - { - ol.writeObjectLink(0,e->file,e->anchor,e->name); - e=exampleList->next(); - if (e) - { - if (exampleList->at()==(int)exampleList->count()-1) - ol.writeString(" and "); - else - ol.writeString(", "); - } - } - ol.writeString("."); -} -#endif - QCString MemberDef::getOutputFileBase() const { if (classDef) @@ -396,7 +373,7 @@ QCString MemberDef::getOutputFileBase() const { return nspace->getOutputFileBase(); } - warn(defFileName,defLine, + warn(m_defFileName,m_defLine, "Warning: Internal inconsistency: member %s does not belong to any" " container!",name().data() ); @@ -457,9 +434,19 @@ void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd, /*! If this member has an anonymous class/struct/union as its type, then * this method will return the ClassDef that describes this return type. */ -ClassDef *MemberDef::getClassDefOfAnonymousType(const char *scopeName) const +ClassDef *MemberDef::getClassDefOfAnonymousType() { - QCString cname=scopeName; + if (cachedAnonymousType) return cachedAnonymousType; + + QCString cname; + if (getClassDef()!=0) + { + cname=getClassDef()->name().copy(); + } + else if (getNamespaceDef()!=0) + { + cname=getNamespaceDef()->name().copy(); + } QCString ltype(type); // strip `static' keyword from ltype if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7); @@ -495,6 +482,7 @@ ClassDef *MemberDef::getClassDefOfAnonymousType(const char *scopeName) const annoClassDef=getClass(ts); } } + cachedAnonymousType = annoClassDef; return annoClassDef; } @@ -539,7 +527,7 @@ void MemberDef::writeDeclaration(OutputList &ol, bool inGroup ) { - //printf("%s MemberDef::writeDeclaration()\n",name().data()); + //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",name().data(),inGroup); // hide members whose brief section should not be visible if (!isBriefSectionVisible()) return; @@ -598,7 +586,7 @@ void MemberDef::writeDeclaration(OutputList &ol, if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); // search for the last anonymous scope in the member type - ClassDef *annoClassDef=getClassDefOfAnonymousType((cd||nd)?cname.data():0); + ClassDef *annoClassDef=getClassDefOfAnonymousType(); // start a new member declaration ol.startMemberItem((annoClassDef || annMemb || annEnumType) ? 1 : 0); @@ -659,7 +647,6 @@ void MemberDef::writeDeclaration(OutputList &ol, if (annoClassDef) // type is an anonymous compound { int ir=i+l; - //printf("class found!\n"); annoClassDef->writeDeclaration(ol,annMemb,inGroup); ol.startMemberItem(2); int j; @@ -674,10 +661,6 @@ void MemberDef::writeDeclaration(OutputList &ol, { ol.docify(";"); } - //else - //{ - // ol.docify(varName); - //} } else { @@ -724,7 +707,8 @@ void MemberDef::writeDeclaration(OutputList &ol, // write name if (!name().isEmpty() && name().at(0)!='@') { - if (isLinkable()) + //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable()); + if (/*d->isLinkable() &&*/ isLinkable()) { if (annMemb) { @@ -738,8 +722,10 @@ void MemberDef::writeDeclaration(OutputList &ol, annMemb->annUsed=annUsed=TRUE; } else + { //printf("writeLink %s->%d\n",name.data(),hasDocumentation()); writeLink(ol,cd,nd,fd,gd); + } } else // there is a brief member description and brief member // descriptions are enabled or there is no detailed description. @@ -796,7 +782,7 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC") && !annMemb) { ol.startMemberDescription(); - parseDoc(ol,defFileName,defLine,cname,name(),briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,cname,name(),briefDescription()); if (detailsVisible) { ol.pushGeneratorState(); @@ -850,6 +836,7 @@ bool MemberDef::isDetailedSectionVisible(bool inGroup) const bool staticFilter = getClassDef()!=0 || !isStatic() || Config_getBool("EXTRACT_STATIC"); // details are not part of a group or this is for a group documentation page + // TODO: FIX THIS!!! This should made such that it is always TRUE. bool groupFilter = getGroupDef()==0 || inGroup; // member is part of an anonymous scope that is the type of @@ -887,7 +874,6 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, QCString cname = container->name(); QCString cfname = container->getOutputFileBase(); - // get member name QCString doxyName=name().copy(); // prepend scope if there is any. TODO: make this optional for C only docs @@ -1122,14 +1108,14 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ) /* || !annMemb */ ) { - parseDoc(ol,defFileName,defLine,scopeName,name(),briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,scopeName,name(),briefDescription()); ol.newParagraph(); } /* write detailed description */ if (!documentation().isEmpty()) { - parseDoc(ol,defFileName,defLine,scopeName,name(),documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,scopeName,name(),documentation()+"\n"); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::RTF); ol.newParagraph(); @@ -1161,7 +1147,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.endEmphasis(); ol.endDescTableTitle(); ol.startDescTableData(); - parseDoc(ol,defFileName,defLine,scopeName,name(),a->docs); + parseDoc(ol,m_defFileName,m_defLine,scopeName,name(),a->docs); ol.endDescTableData(); } } @@ -1218,7 +1204,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (!fmd->briefDescription().isEmpty()) { - parseDoc(ol,defFileName,defLine,scopeName,fmd->name(),fmd->briefDescription()); + parseDoc(ol,m_defFileName,m_defLine,scopeName,fmd->name(),fmd->briefDescription()); //ol.newParagraph(); } if (!fmd->briefDescription().isEmpty() && @@ -1228,7 +1214,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } if (!fmd->documentation().isEmpty()) { - parseDoc(ol,defFileName,defLine,scopeName,fmd->name(),fmd->documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,scopeName,fmd->name(),fmd->documentation()+"\n"); } ol.endDescTableData(); } @@ -1376,7 +1362,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.endBold(); ol.endDescTitle(); ol.writeDescItem(); - writeExample(ol,getExampleList()); + writeExample(ol,getExamples()); //ol.endDescItem(); ol.endDescList(); } @@ -1412,7 +1398,7 @@ void MemberDef::warnIfUndocumented() t="file", d=fd; if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1) - warn_undoc(defFileName,defLine,"Warning: Member %s of %s %s is not documented.", + warn_undoc(m_defFileName,m_defLine,"Warning: Member %s of %s %s is not documented.", name().data(),t,d->name().data()); } @@ -1481,3 +1467,9 @@ QCString MemberDef::anchor() const if (enumScope) return enumScope->anchor()+anc; return anc; } + +void MemberDef::setGroupDef(GroupDef *gd) +{ + printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data()); + group=gd; +} diff --git a/src/memberdef.h b/src/memberdef.h index 4eda16b..39869d4 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -31,8 +31,7 @@ class GroupDef; class FileDef; class MemberList; class MemberGroup; -class ExampleList; -class ExampleDict; +class ExampleSDict; class OutputList; class GroupDef; class QTextStream; @@ -138,7 +137,7 @@ class MemberDef : public Definition void setMaxInitLines(int lines) { userInitLines=lines; } void setMemberClass(ClassDef *cd) { classDef=cd; } void setSectionList(MemberList *sl) { section=sl; } - void setGroupDef(GroupDef *gd) { group=gd; } + void setGroupDef(GroupDef *gd); void setExplicitExternal(bool b) { explExt=b; } void makeRelated() { related=TRUE; } @@ -177,8 +176,7 @@ class MemberDef : public Definition // example related members bool addExample(const char *anchor,const char *name,const char *file); bool hasExamples(); - ExampleList *getExampleList() const { return exampleList; } - + ExampleSDict *getExamples() const { return exampleSDict; } // prototype related members void setPrototype(bool p) { proto=p; } @@ -217,7 +215,7 @@ class MemberDef : public Definition QCString getScopeString() const; - ClassDef *getClassDefOfAnonymousType(const char *scopeName) const; + ClassDef *getClassDefOfAnonymousType(); private: ClassDef *classDef; // member of or related to @@ -228,8 +226,9 @@ class MemberDef : public Definition MemberList *redefinedBy; // the list of members that redefine this one MemberDef *memDef; // member definition for this declaration MemberDef *memDec; // member declaration for this definition - ExampleList *exampleList; // a list of all examples using this member - ExampleDict *exampleDict; // a dictionary of all examples for quick access + + ExampleSDict *exampleSDict; // a dictionary of all examples for quick access + MemberList *enumFields; // enumeration fields OutputList *enumDeclList; // stored piece of documentation for enumeration. NamespaceDef *nspace; // the namespace this member is in. @@ -271,6 +270,11 @@ class MemberDef : public Definition GroupDef *group; // group in which this member is in bool explExt; // member was explicitly declared external + ClassDef *cachedAnonymousType; // if the member has an anonymous compound + // as its type then this is computed by + // getClassDefOfAnonymousType() and + // cached here. + // disable copying of member defs MemberDef(const MemberDef &); diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 036d5c6..bc8ee03 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * $Id$ + * * * Copyright (C) 1997-2001 by Dimitri van Heesch. * diff --git a/src/membername.h b/src/membername.h index 15f407c..74f81f5 100644 --- a/src/membername.h +++ b/src/membername.h @@ -20,6 +20,7 @@ #include #include "memberdef.h" +#include "sortdict.h" class MemberName : public QList { @@ -107,6 +108,19 @@ class MemberNameInfoDict : public QDict ~MemberNameInfoDict() {} }; +class MemberNameInfoSDict : public SDict +{ + public: + MemberNameInfoSDict(int size) : SDict(size) {} + ~MemberNameInfoSDict() {} + int compareItems(GCI item1,GCI item2) + { return stricmp( + ((MemberNameInfo *)item1)->memberName(), + ((MemberNameInfo *)item2)->memberName() + ); + } +}; + class MemberNameInfoListIterator : public QListIterator { public: diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index efcd10f..7df4850 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -32,23 +32,22 @@ NamespaceDef::NamespaceDef(const char *df,int dl, Definition(df,dl,name) { fileName=(QCString)"namespace_"+name; - classList = new ClassList; - classDict = new ClassDict(1009); - //memList = new MemberList; + classSDict = new ClassSDict(257); + namespaceSDict = new NamespaceSDict(257); + m_innerCompounds = new SDict(257); usingDirList = 0; usingDeclList = 0; setReference(lref); memberGroupList = new MemberGroupList; memberGroupList->setAutoDelete(TRUE); memberGroupDict = new MemberGroupDict(1009); - defFileName = df; - defLine = dl; } NamespaceDef::~NamespaceDef() { - delete classList; - delete classDict; + delete classSDict; + delete namespaceSDict; + delete m_innerCompounds; delete usingDirList; delete usingDeclList; delete memberGroupList; @@ -77,13 +76,23 @@ void NamespaceDef::insertUsedFile(const char *f) void NamespaceDef::insertClass(ClassDef *cd) { - if (classDict->find(cd->name())==0) + if (classSDict->find(cd->name())==0) { if (Config_getBool("SORT_MEMBER_DOCS")) - classList->inSort(cd); + classSDict->inSort(cd->name(),cd); else - classList->append(cd); - classDict->insert(cd->name(),cd); + classSDict->append(cd->name(),cd); + } +} + +void NamespaceDef::insertNamespace(NamespaceDef *nd) +{ + if (namespaceSDict->find(nd->name())==0) + { + if (Config_getBool("SORT_MEMBER_DOCS")) + namespaceSDict->inSort(nd->name(),nd); + else + namespaceSDict->append(nd->name(),nd); } } @@ -219,7 +228,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,defFileName,defLine,name(),0,briefDescription()); + parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); ol+=briefOutput; ol.writeString(" \n"); ol.pushGeneratorState(); @@ -237,7 +246,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.endTextBlock(); ol.startMemberSections(); - classList->writeDeclaration(ol); + classSDict->writeDeclaration(ol); /* write user defined member groups */ MemberGroupListIterator mgli(*memberGroupList); @@ -283,7 +292,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) } if (!documentation().isEmpty()) { - parseDoc(ol,defFileName,defLine,name(),0,documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); ol.newParagraph(); } ol.endTextBlock(); @@ -328,7 +337,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) int NamespaceDef::countMembers() { allMemberList.countDocMembers(); - return allMemberList.numDocMembers()+classList->count(); + return allMemberList.numDocMembers()+classSDict->count(); } void NamespaceDef::addUsingDirective(NamespaceDef *nd) @@ -354,3 +363,15 @@ QCString NamespaceDef::getOutputFileBase() const return convertNameToFile(fileName); } +Definition *NamespaceDef::findInnerCompound(const char *name) +{ + if (name==0) return 0; + return m_innerCompounds->find(name); +} + +void NamespaceDef::addInnerCompound(Definition *d) +{ + m_innerCompounds->append(d->localName(),d); +} + + diff --git a/src/namespacedef.h b/src/namespacedef.h index 08a8701..bcfee88 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -21,17 +21,19 @@ #include "qtbc.h" #include #include +#include "sortdict.h" #include "definition.h" #include "memberlist.h" class ClassDef; -class OutputList; class ClassList; -class ClassDict; +class OutputList; +class ClassSDict; class MemberDef; class NamespaceList; class MemberGroupDict; class MemberGroupList; +class NamespaceSDict; class NamespaceDef : public Definition { @@ -43,8 +45,11 @@ class NamespaceDef : public Definition QCString getOutputFileBase() const; void insertUsedFile(const char *fname); void writeDocumentation(OutputList &ol); + void insertClass(ClassDef *cd); + void insertNamespace(NamespaceDef *nd); void insertMember(MemberDef *md); + void computeAnchors(); int countMembers(); void addUsingDirective(NamespaceDef *nd); @@ -65,6 +70,9 @@ class NamespaceDef : public Definition } void addMembersToMemberGroup(); void distributeMemberGroupDocumentation(); + + virtual Definition *findInnerCompound(const char *name); + void addInnerCompound(Definition *d); //protected: // void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const); @@ -73,10 +81,15 @@ class NamespaceDef : public Definition //QCString reference; QCString fileName; QStrList files; - ClassList *classList; - ClassDict *classDict; + + /*! Classes inside this namespace */ + ClassSDict *classSDict; + /*! Namespaces inside this namespace */ + NamespaceSDict *namespaceSDict; + NamespaceList *usingDirList; ClassList *usingDeclList; + SDict *m_innerCompounds; MemberList allMemberList; @@ -128,4 +141,19 @@ class NamespaceDict : public QDict ~NamespaceDict() {} }; +class NamespaceSDict : public SDict +{ + public: + NamespaceSDict(int size) : SDict(size) {} + ~NamespaceSDict() {} + int compareItems(GCI item1,GCI item2) + { + return stricmp(((NamespaceDef *)item1)->name(), + ((NamespaceDef *)item2)->name() + ); + } +}; + + + #endif diff --git a/src/packagedef.cpp b/src/packagedef.cpp index f9828f0..7c21c8e 100644 --- a/src/packagedef.cpp +++ b/src/packagedef.cpp @@ -30,22 +30,22 @@ PackageDef::PackageDef(const char *df,int dl,const char *na,const char *ref) : Definition(df,dl,na) { - classList = new ClassList; + classSDict = new ClassSDict(17); packageFileName = (QCString)"package_"+na; setReference(ref); } PackageDef::~PackageDef() { - delete classList; + delete classSDict; } -void PackageDef::addClass(const ClassDef *def) +void PackageDef::addClass(const ClassDef *cd) { if (Config_getBool("SORT_MEMBER_DOCS")) - classList->inSort(def); + classSDict->inSort(cd->name(),cd); else - classList->append(def); + classSDict->append(cd->name(),cd); } void PackageDef::writeDocumentation(OutputList &ol) @@ -61,7 +61,7 @@ void PackageDef::writeDocumentation(OutputList &ol) OutputList briefOutput(&ol); if (!briefDescription().isEmpty()) { - parseDoc(briefOutput,defFileName,defLine,name(),0,briefDescription()); + parseDoc(briefOutput,m_defFileName,m_defLine,name(),0,briefDescription()); ol+=briefOutput; ol.writeString(" \n"); ol.pushGeneratorState(); @@ -81,9 +81,9 @@ void PackageDef::writeDocumentation(OutputList &ol) ol.startMemberSections(); ClassDef::CompoundType ct; ct=ClassDef::Interface; - classList->writeDeclaration(ol,&ct,theTranslator->trInterfaces()); + classSDict->writeDeclaration(ol,&ct,theTranslator->trInterfaces()); ct=ClassDef::Class; - classList->writeDeclaration(ol,&ct,theTranslator->trClasses()); + classSDict->writeDeclaration(ol,&ct,theTranslator->trClasses()); ol.endMemberSections(); if (!Config_getString("GENERATE_TAGFILE").isEmpty()) @@ -114,7 +114,7 @@ void PackageDef::writeDocumentation(OutputList &ol) // write documentation if (!documentation().isEmpty()) { - parseDoc(ol,defFileName,defLine,name(),0,documentation()+"\n"); + parseDoc(ol,m_defFileName,m_defLine,name(),0,documentation()+"\n"); } } diff --git a/src/packagedef.h b/src/packagedef.h index 1fd8540..5b01dba 100644 --- a/src/packagedef.h +++ b/src/packagedef.h @@ -24,7 +24,7 @@ #include "definition.h" #include "sortdict.h" -class ClassList; +class ClassSDict; class ClassDef; class PackageList; class OutputList; @@ -49,7 +49,7 @@ class PackageDef : public Definition private: QCString packageFileName; // base name of the generated file - ClassList *classList; // list of classes in the package + ClassSDict *classSDict; // list of classes in the package }; class PackageSDict : public SDict diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index be3b676..a85e017 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -991,16 +991,16 @@ void RTFGenerator::startIndexSection(IndexSections is) case isClassDocumentation: { //Compound Documentation - ClassDef *cd=Doxygen::classList.first(); + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; bool found=FALSE; - while (cd && !found) + for (cli.toFirst();(cd=cli.current()) && !found;++cli) { if (cd->isLinkableInProject()) { beginRTFChapter(); found=TRUE; } - cd=Doxygen::classList.next(); } } break; @@ -1220,11 +1220,12 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassDef *cd=Doxygen::classList.first(); + ClassSDict::Iterator cli(Doxygen::classSDict); + ClassDef *cd=0; bool found=FALSE; t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl; - while (cd && !found) + for (cli.toFirst();(cd=cli.current()) && !found;++cli) { if (cd->isLinkableInProject()) { @@ -1234,9 +1235,8 @@ void RTFGenerator::endIndexSection(IndexSections is) t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; found=TRUE; } - cd=Doxygen::classList.next(); } - while (cd) + for (;(cd=cli.current());++cli) { if (cd->isLinkableInProject()) { @@ -1246,7 +1246,6 @@ void RTFGenerator::endIndexSection(IndexSections is) t << cd->getOutputFileBase(); t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n"; } - cd=Doxygen::classList.next(); } } break; diff --git a/src/scanner.l b/src/scanner.l index 6f81966..960e07b 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -1557,11 +1557,10 @@ TITLE [tT][iI][tT][lL][eE] { current->endBodyLine = yyLineNr; QCString &cn = current->name; - //QCString rn = stripAnnonymousScope(current_root->name); QCString rn = current_root->name.copy(); //printf("cn=`%s' rn=`%s'\n",cn.data(),rn.data()); if (!cn.isEmpty() && !rn.isEmpty() && - (current_root->section & Entry::SCOPE_MASK)) + (current_root->section & Entry::SCOPE_MASK)) { cn.prepend(rn+"::"); } @@ -2294,7 +2293,7 @@ TITLE [tT][iI][tT][lL][eE] current->argList->clear(); BEGIN( FindMembers ) ; } -{SCOPENAME}{BN}*/"<" { +{SCOPENAME}{BN}*/"<" { sharpCount = 0; current->name = yytext ; lineCount(); @@ -2317,7 +2316,7 @@ TITLE [tT][iI][tT][lL][eE] . { current->name += yytext; } -{SCOPENAME} { +{SCOPENAME} { current->name = yytext ; lineCount(); BEGIN( ClassVar ); @@ -3855,14 +3854,14 @@ static void parseCompounds(Entry *rt) memberGroupId = NOGROUP; // rebuild compound's group context - QCString *s = ce->groups->first(); - if (s) - { - lastDefGroup=*s; - startGroup(); - } - - current->mGrpId = memberGroupId = ce->mGrpId; + //QCString *s = ce->groups->first(); + //if (s) + //{ + // lastDefGroup=*s; + // startGroup(); + //} + + //current->mGrpId = memberGroupId = ce->mGrpId; scanYYlex() ; delete current; current=0; diff --git a/src/sortdict.h b/src/sortdict.h index 199c34d..64afe8d 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -79,6 +79,14 @@ class SDict m_list->append(d); m_dict->insert(key,d); } + /*! Sorts the members of the dictionary. First appending a number + * of members and then sorting them is faster (O(NlogN) than using + * inSort() for each member (O(N^2)). + */ + void sort() + { + m_list->sort(); + } /*! Inserts a compound into the dictionary in a sorted way. * \param key The unique key to use to quicky find the item later on. * \param d The compound to add. @@ -103,6 +111,12 @@ class SDict { return m_dict->find(key); } + + /*! Returns the item at position \a i in the sorted dictionary */ + T *at(uint i) + { + return m_list->at(i); + } /*! Function that is used to compare two items when sorting. * Overload this to properly sort items. * \sa inSort() @@ -152,6 +166,13 @@ class SDict { return m_li->toFirst(); } + /*! Set the iterator to the last element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toLast() const + { + return m_li->toLast(); + } /*! Returns the current compound */ T *current() const { @@ -165,6 +186,14 @@ class SDict { return m_li->operator++(); } + /*! Moves the iterator to the previous element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the first element. + */ + T *operator--() + { + return m_li->operator--(); + } private: QListIterator *m_li; diff --git a/src/translator_cz.h b/src/translator_cz.h index 479eba6..050cfb1 100644 --- a/src/translator_cz.h +++ b/src/translator_cz.h @@ -120,9 +120,9 @@ // Windows version. The version which does not call the function is // probably slightly faster. -#include "translator_adapter.h" +#include "translator.h" -class TranslatorCzech : public TranslatorAdapterBase +class TranslatorCzech : public Translator { private: /*! The Decode() inline assumes the source written in the diff --git a/src/translator_dk.h b/src/translator_dk.h new file mode 100644 index 0000000..f0d235a --- /dev/null +++ b/src/translator_dk.h @@ -0,0 +1,1309 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +/* OBS! + Til danskere og andet godtfolk: + Jeg har været i tvivl om (i hvert fald) følgende ord: + - Member + - Compound + - Namespace + - Interface + + Jeg har besluttet (indtil videre) at lade følgende ord stå som de er, + da jeg selv overvejende bruger det engelske udtryk: + - Interface + - Typedef + - Union + (union ved jeg ikke engang, hvad jeg skal kalde på dansk... + udover måske 'union') + + (Konstruktivt) input modtages med glæde! + */ + +#ifndef TRANSLATOR_DK_H +#define TRANSLATOR_DK_H + +#include "translator.h" + +class TranslatorDanish : public Translator +{ + public: + + // --- Language control methods ------------------- + + /*! Used for identification of the language. The identification + * should not be translated. It should be replaced by the name + * of the language in English using lower-case characters only + * (e.g. "czech", "japanese", "russian", etc.). It should be equal to + * the identification used in language.cpp. + */ + virtual QCString idLanguage() + { return "danish"; } + + /*! Used to get the LaTeX command(s) for the language support. This method + * was designed for languages which do wish to use a babel package. + */ + virtual QCString latexLanguageSupportCommand() + { + return "danish"; + } + + /*! return the language charset. This will be used for the HTML output */ + virtual QCString idLanguageCharset() + { + return "iso-8859-1"; + } + + // --- Language translation methods ------------------- + + /*! used in the compound documentation before a list of related functions. */ + virtual QCString trRelatedFunctions() + { return "Relaterede funktioner"; } + + /*! subscript for the related functions. */ + virtual QCString trRelatedSubscript() + { return "(Bemærk at disse ikke er medlems-funktioner.)"; } + + /*! header that is put before the detailed description of files, classes and namespaces. */ + virtual QCString trDetailedDescription() + { return "Detaljeret beskrivelse"; } + + /*! header that is put before the list of typedefs. */ + virtual QCString trMemberTypedefDocumentation() + { return "Dokumentation af medlems-typedefs"; } + + /*! header that is put before the list of enumerations. */ + virtual QCString trMemberEnumerationDocumentation() + { return "Dokumentation af medlems-enumerationer"; } + + /*! header that is put before the list of member functions. */ + virtual QCString trMemberFunctionDocumentation() + { return "Dokumentation af medlemsfunktioner"; } + + /*! header that is put before the list of member attributes. */ + virtual QCString trMemberDataDocumentation() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Felt-dokumentation"; + } + else + { + return "Dokumentation af medlems-data"; + } + } + + /*! this is the text of a link put after brief descriptions. */ + virtual QCString trMore() + { return "Mere..."; } + + /*! put in the class documentation */ + virtual QCString trListOfAllMembers() + { return "Liste over alle medlemmer."; } + + /*! used as the title of the "list of all members" page of a class */ + virtual QCString trMemberList() + { return "Liste over medlemmer"; } + + /*! this is the first part of a sentence that is followed by a class name */ + virtual QCString trThisIsTheListOfAllMembers() + { return "Dette er den komplette liste over medlemmer for "; } + + /*! this is the remainder of the sentence after the class name */ + virtual QCString trIncludingInheritedMembers() + { return ", inklusive alle nedarvede medlemmer."; } + + /*! this is put at the author sections at the bottom of man pages. + * parameter s is name of the project name. + */ + virtual QCString trGeneratedAutomatically(const char *s) + { QCString result="Automatisk genereret af Doxygen"; + if (s) result+=(QCString)" for "+s; + result+=" ud fra kildekoden."; + return result; + } + + /*! put after an enum name in the list of all members */ + virtual QCString trEnumName() + { return "enum-navn"; } + + /*! put after an enum value in the list of all members */ + virtual QCString trEnumValue() + { return "enum-værdi"; } + + /*! put after an undocumented member in the list of all members */ + virtual QCString trDefinedIn() + { return "defineret i"; } + + // quick reference sections + + /*! This is put above each page as a link to the list of all groups of + * compounds or files (see the \\group command). + */ + virtual QCString trModules() + { return "Moduler"; } + + /*! This is put above each page as a link to the class hierarchy */ + virtual QCString trClassHierarchy() + { return "Klassehierarki"; } + + /*! This is put above each page as a link to the list of annotated classes */ + virtual QCString trCompoundList() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Datastrukturer"; + } + else + { + return "Compound List"; + } + } + + /*! This is put above each page as a link to the list of documented files */ + virtual QCString trFileList() + { return "Filliste"; } + + /*! This is put above each page as a link to the list of all verbatim headers */ + virtual QCString trHeaderFiles() + { return "Header-filer"; } + + /*! This is put above each page as a link to all members of compounds. */ + virtual QCString trCompoundMembers() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Data-felter"; + } + else + { + return "Compound Members"; + } + } + + /*! This is put above each page as a link to all members of files. */ + virtual QCString trFileMembers() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Globale"; + } + else + { + return "Fil-medlemmer"; + } + } + + /*! This is put above each page as a link to all related pages. */ + virtual QCString trRelatedPages() + { return "Relaterede sider"; } + + /*! This is put above each page as a link to all examples. */ + virtual QCString trExamples() + { return "Eksempler"; } + + /*! This is put above each page as a link to the search engine. */ + virtual QCString trSearch() + { return "Søg"; } + + /*! This is an introduction to the class hierarchy. */ + virtual QCString trClassHierarchyDescription() + { return "Denne nedarvningsliste er sorteret næsten - " + "men ikke helt - alfabetisk:"; + } + + /*! This is an introduction to the list with all files. */ + virtual QCString trFileListDescription(bool extractAll) + { + QCString result="Her er en liste over alle "; + if (!extractAll) result+="dokumenterede "; + result+="filer med korte beskrivelser:"; + return result; + } + + /*! This is an introduction to the annotated compound list. */ + virtual QCString trCompoundListDescription() + { + + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Her er datastrukturerne med korte beskrivelser:"; + } + else + { + return "Her er klasserne, strukturerne, " + "unionerne og grænsefladerne med korte beskrivelser:"; + } + } + + /*! This is an introduction to the page with all class members. */ + virtual QCString trCompoundMembersDescription(bool extractAll) + { + QCString result="Her er en liste over alle "; + if (!extractAll) + { + result+="dokumenterede "; + } + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + result+="felter i strukturer og unioner"; + } + else + { + result+="klassemedlemmer"; + } + result+=" med links til "; + if (extractAll) + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + result+="struktur/unions-dokumentationen for hvert felt:"; + } + else + { + result+="klassedokumentationen for hvert medlem:"; + } + } + else + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + result+="de strukturer/unioner de hører til:"; + } + else + { + result+="de klasser de hører til:"; + } + } + return result; + } + + /*! This is an introduction to the page with all file members. */ + virtual QCString trFileMembersDescription(bool extractAll) + { + QCString result="Her er en liste over alle "; + if (!extractAll) result+="dokumenterede "; + + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + result+="funktioner, variable, #defines, enumerationer " + "og typedefinitioner"; + } + else + { + result+="fil-medlemmer"; + } + result+=" med links til "; + if (extractAll) + result+="de filer de hører til:"; + else + result+="dokumentationen:"; + return result; + } + + /*! This is an introduction to the page with the list of all header files. */ + virtual QCString trHeaderFilesDescription() + { return "Her er de headerfiler der udgør API'en:"; } + + /*! This is an introduction to the page with the list of all examples */ + virtual QCString trExamplesDescription() + { return "Her er en liste over alle eksempler:"; } + + /*! This is an introduction to the page with the list of related pages */ + virtual QCString trRelatedPagesDescription() + { return "Her er en liste over alle relaterede dokumentationssider:"; } + + /*! This is an introduction to the page with the list of class/file groups */ + virtual QCString trModulesDescription() + { return "Her er en liste over alle moduler:"; } + + /*! This sentences is used in the annotated class/file lists if no brief + * description is given. + */ + virtual QCString trNoDescriptionAvailable() + { return "Ikke beskrevet"; } + + // index titles (the project name is prepended for these) + + + /*! This is used in HTML as the title of index.html. */ + virtual QCString trDocumentation() + { return "Dokumentation"; } + + /*! This is used in LaTeX as the title of the chapter with the + * index of all groups. + */ + virtual QCString trModuleIndex() + { return "Modul-index"; } + + /*! This is used in LaTeX as the title of the chapter with the + * class hierarchy. + */ + virtual QCString trHierarchicalIndex() + { return "Hierarkisk index"; } + + /*! This is used in LaTeX as the title of the chapter with the + * annotated compound index. + */ + virtual QCString trCompoundIndex() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Indeks over datastrukturer"; + } + else + { + return "Compound Index"; + } + } + + /*! This is used in LaTeX as the title of the chapter with the + * list of all files. + */ + virtual QCString trFileIndex() + { return "Fil-index"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all groups. + */ + virtual QCString trModuleDocumentation() + { return "Modul-dokumentation"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all classes, structs and unions. + */ + virtual QCString trClassDocumentation() + { return "Klasse-dokumentation"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all files. + */ + virtual QCString trFileDocumentation() + { return "Fil-dokumentation"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all examples. + */ + virtual QCString trExampleDocumentation() + { return "Eksempel-dokumentation"; } + + /*! This is used in LaTeX as the title of the chapter containing + * the documentation of all related pages. + */ + virtual QCString trPageDocumentation() + { return "Side-dokumentation"; } + + /*! This is used in LaTeX as the title of the document */ + virtual QCString trReferenceManual() + { return "Reference-manual"; } + + /*! This is used in the documentation of a file as a header before the + * list of defines + */ + virtual QCString trDefines() + { return "#Defines"; } + + /*! This is used in the documentation of a file as a header before the + * list of function prototypes + */ + virtual QCString trFuncProtos() + { return "Funktionsprototyper"; } + + /*! This is used in the documentation of a file as a header before the + * list of typedefs + */ + virtual QCString trTypedefs() + { return "Typedefs"; } + + /*! This is used in the documentation of a file as a header before the + * list of enumerations + */ + virtual QCString trEnumerations() + { return "Enumerationer"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) functions + */ + virtual QCString trFunctions() + { return "Funktioner"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trVariables() + { return "Variabler"; } + + /*! This is used in the documentation of a file as a header before the + * list of (global) variables + */ + virtual QCString trEnumerationValues() + { return "Enumerationsværdier"; } + + /*! This is used in man pages as the author section. */ + virtual QCString trAuthor() + { return "Forfatter"; } + + /*! This is used in the documentation of a file before the list of + * documentation blocks for defines + */ + virtual QCString trDefineDocumentation() + { return "#Define-dokumentation"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for function prototypes + */ + virtual QCString trFunctionPrototypeDocumentation() + { return "Funktionsprototype-dokumentation"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for typedefs + */ + virtual QCString trTypedefDocumentation() + { return "Typedef-dokumentation"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration types + */ + virtual QCString trEnumerationTypeDocumentation() + { return "Dokumentation af enumerations-typer"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration values + */ + virtual QCString trEnumerationValueDocumentation() + { return "Dokumentation af enumerations-værdier"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for functions + */ + virtual QCString trFunctionDocumentation() + { return "Funktions-dokumentation"; } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for variables + */ + virtual QCString trVariableDocumentation() + { return "Variabel-dokumentation"; } + + /*! This is used in the documentation of a file/namespace/group before + * the list of links to documented compounds + */ + virtual QCString trCompounds() + { + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + return "Datastrukturer"; + } + else + { + return "Compounds"; + } + } + + /*! This is used in the standard footer of each page and indicates when + * the page was generated + */ + virtual QCString trGeneratedAt(const char *date,const char *projName) + { + QCString result=(QCString)"Genereret "+date; + if (projName) result+=(QCString)" for "+projName; + result+=(QCString)" af"; + return result; + } + /*! This is part of the sentence used in the standard footer of each page. + */ + virtual QCString trWrittenBy() + { + return "skrevet af"; + } + + /*! this text is put before a class diagram */ + virtual QCString trClassDiagram(const char *clName) + { + return (QCString)"Nedarvningsdiagram for "+clName+":"; + } + + /*! this text is generated when the \\internal command is used. */ + virtual QCString trForInternalUseOnly() + { return "Kun til intern brug."; } + + /*! this text is generated when the \\reimp command is used. */ + virtual QCString trReimplementedForInternalReasons() + { return "Metode overskrevet af interne grunde; " + "API'en er ikke påvirket."; } + + /*! this text is generated when the \\warning command is used. */ + virtual QCString trWarning() + { return "Advarsel"; } + + /*! this text is generated when the \\bug command is used. */ + virtual QCString trBugsAndLimitations() + { return "Fejl og begrænsninger"; } + + /*! this text is generated when the \\version command is used. */ + virtual QCString trVersion() + { return "Version"; } + + /*! this text is generated when the \\date command is used. */ + virtual QCString trDate() + { return "Dato"; } + + /*! this text is generated when the \\author command is used. */ + virtual QCString trAuthors() + { return "Forfatter(e)"; } + + /*! this text is generated when the \\return command is used. */ + virtual QCString trReturns() + { return "Returnerer"; } + + /*! this text is generated when the \\sa command is used. */ + virtual QCString trSeeAlso() + { return "Se også"; } + + /*! this text is generated when the \\param command is used. */ + virtual QCString trParameters() + { return "Parametre"; } + + /*! this text is generated when the \\exception command is used. */ + virtual QCString trExceptions() + { return "Exceptions"; } + + /*! this text is used in the title page of a LaTeX document. */ + virtual QCString trGeneratedBy() + { return "Genereret af"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990307 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of page containing all the index of all namespaces. */ + virtual QCString trNamespaceList() + { return "Namespace-liste"; } + + /*! used as an introduction to the namespace list */ + virtual QCString trNamespaceListDescription(bool extractAll) + { + QCString result="Her er en liste over alle "; + if (!extractAll) result+="dokumenterede "; + result+="namespaces med korte beskrivelser:"; + return result; + } + + /*! used in the class documentation as a header before the list of all + * friends of a class + */ + virtual QCString trFriends() + { return "Friends"; } + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990405 +////////////////////////////////////////////////////////////////////////// + + /*! used in the class documentation as a header before the list of all + * related classes + */ + virtual QCString trRelatedFunctionDocumentation() + { return "Friends og relateret funktions-dokumentation"; } //?? + +////////////////////////////////////////////////////////////////////////// +// new since 0.49-990425 +////////////////////////////////////////////////////////////////////////// + + /*! used as the title of the HTML page of a class/struct/union */ + virtual QCString trCompoundReference(const char *clName, + ClassDef::CompoundType compType, + bool isTemplate) + { + QCString result=(QCString)clName+" "; + switch(compType) + { + case ClassDef::Class: result+=" Klasse-"; break; + case ClassDef::Struct: result+=" Struktur-"; break; + case ClassDef::Union: result+=" Union-"; break; + case ClassDef::Interface: result+=" Interface-"; break; + case ClassDef::Exception: result+=" Exception-"; break; + } + if (isTemplate) result+="template-"; + result+="reference"; + return result; + } + + /*! used as the title of the HTML page of a file */ + virtual QCString trFileReference(const char *fileName) + { + QCString result=fileName; + result+=" Fil-reference"; + return result; + } + + /*! used as the title of the HTML page of a namespace */ + virtual QCString trNamespaceReference(const char *namespaceName) + { + QCString result=namespaceName; + result+=" Namespace-reference"; + return result; + } + + virtual QCString trPublicMembers() + { return "Public Methods"; } + virtual QCString trPublicSlots() + { return "Public Slots"; } + virtual QCString trSignals() + { return "Signals"; } + virtual QCString trStaticPublicMembers() + { return "Static Public Methods"; } + virtual QCString trProtectedMembers() + { return "Protected Methods"; } + virtual QCString trProtectedSlots() + { return "Protected Slots"; } + virtual QCString trStaticProtectedMembers() + { return "Static Protected Methods"; } + virtual QCString trPrivateMembers() + { return "Private Methods"; } + virtual QCString trPrivateSlots() + { return "Private Slots"; } + virtual QCString trStaticPrivateMembers() + { return "Static Private Methods"; } + + /*! this function is used to produce a comma-separated list of items. + * use generateMarker(i) to indicate where item i should be put. + */ + virtual QCString trWriteList(int numEntries) + { + QCString result; + int i; + // the inherits list contain `numEntries' classes + for (i=0;i