Commit 4a50fc78 authored by dimitri's avatar dimitri

Release-1.3.9.1-20041129

parent 0625007c
DOXYGEN Version 1.3.9.1-20041114
DOXYGEN Version 1.3.9.1-20041129
Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions.
--------
Dimitri van Heesch (14 November 2004)
Dimitri van Heesch (29 November 2004)
DOXYGEN Version 1.3.9.1_20041114
DOXYGEN Version 1.3.9.1_20041129
Please read INSTALL for compilation instructions.
......@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (14 November 2004)
Dimitri van Heesch (dimitri@stack.nl) (29 November 2004)
1.3.9.1-20041114
1.3.9.1-20041129
......@@ -131,6 +131,7 @@ documentation:
\refitem cmdretval \\retval
\refitem cmdsa \\sa
\refitem cmdsection \\section
\refitem cmdsee \\see
\refitem cmdshowinitializer \\showinitializer
\refitem cmdsince \\since
\refitem cmdskip \\skip
......@@ -1150,6 +1151,12 @@ void memcpy(void *dest, const void *src, size_t n);
\sa section \ref autolink "autolink" for information on how to create links
to objects.
<hr>
\section cmdsee \see { references }
\addindex \\see
Equivalent to \ref cmdsa "\\sa". Introduced for compatibility with Javadoc.
<hr>
\section cmdsince \since { text }
......
......@@ -205,6 +205,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_warn_if_doc_error WARN_IF_DOC_ERROR
\refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
\refitem cfg_warn_logfile WARN_LOGFILE
\refitem cfg_warn_no_paramdoc WARN_NO_PARAMDOC
\refitem cfg_warnings WARNINGS
\refitem cfg_xml_dtd XML_DTD
\refitem cfg_xml_output XML_OUTPUT
......@@ -673,6 +674,14 @@ function's detailed documentation block.
parameters in a documented function, or documenting parameters that
don't exist or using markup commands wrongly.
\anchor cfg_warn_no_paramdoc
<dt>\c WARN_NO_PARAMDOC
This \c WARN_NO_PARAMDOC option can be abled to get warnings for
functions that are documented, but have no documentation for their parameters
or return value. If set to \c NO (the default) doxygen will only warn about
wrong or incomplete parameter documentation, but not about the absence of
documentation.
\anchor cfg_warn_format
<dt>\c WARN_FORMAT <dd>
\addindex WARN_FORMAT
......
Summary: A documentation system for C/C++.
Name: doxygen
Version: 1.3.9.1_20041114
Version: 1.3.9.1_20041129
Release: 1
Epoch: 1
Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
......
......@@ -947,6 +947,10 @@ void ClassDef::writeDocumentation(OutputList &ol)
m_tempArgs != 0);
startFile(ol,getOutputFileBase(),name(),pageTitle);
if (getOuterScope()!=Doxygen::globalScope)
{
writeNavigationPath(ol);
}
startTitle(ol,getOutputFileBase());
ol.parseText(pageTitle);
addGroupListToTitle(ol,this);
......@@ -1343,6 +1347,10 @@ void ClassDef::writeDocumentation(OutputList &ol)
theTranslator->trRelatedFunctions(),
theTranslator->trRelatedSubscript()
);
// nested classes
m_innerClasses->writeDeclaration(ol,0,0,TRUE);
ol.endMemberSections();
// write detailed description
......
......@@ -60,7 +60,8 @@ ClassListIterator::ClassListIterator(const ClassList &cllist) :
{
}
void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter,const char *header)
void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter,
const char *header,bool localNames)
{
if (count()>0)
{
......@@ -102,15 +103,15 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f
}
ol.startMemberItem(FALSE);
QCString tmp = cd->compoundTypeString();
QCString cname = cd->displayName();
//if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
//{
// cname = substitute(cd->className(),"::",".");
//}
//else
//{
// cname = cd->className();
//}
QCString cname;
if (localNames)
{
cname = cd->localName();
}
else
{
cname = cd->displayName();
}
ol.writeString(tmp);
ol.writeString(" ");
ol.insertMemberAlign();
......
......@@ -53,7 +53,7 @@ class ClassSDict : public SDict<ClassDef>
~ClassSDict() {}
int compareItems(GCI item1,GCI item2);
void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0,
const char *header=0);
const char *header=0,bool localNames=FALSE);
};
#endif
......@@ -24,6 +24,7 @@
#include <qstack.h>
#include <qregexp.h>
#include <qtextstream.h>
#include "bufstr.h"
#include "debug.h"
......@@ -31,6 +32,10 @@
#include "config.h"
#include "doxygen.h"
#define ADDCHAR(c) g_outBuf->addChar(c)
#define ADDARRAY(a,s) g_outBuf->addArray(a,s)
struct CondCtx
{
CondCtx(int line,QCString id,bool b)
......@@ -60,18 +65,18 @@ static void replaceCommentMarker(const char *s,int len)
// copy blanks
while ((c=*p) && (c==' ' || c=='\t' || c=='\n'))
{
g_outBuf->addChar(c);
ADDCHAR(c);
g_lineNr += c=='\n';
p++;
}
// replace start of comment marker by spaces
while ((c=*p) && (c=='/' || c=='!' || c=='#'))
{
g_outBuf->addChar(' ');
ADDCHAR(' ');
p++;
if (*p=='<') // comment-after-item marker
{
g_outBuf->addChar(' ');
ADDCHAR(' ');
p++;
}
if (c=='!') // end after first !
......@@ -80,7 +85,7 @@ static void replaceCommentMarker(const char *s,int len)
}
}
// copy comment line to output
g_outBuf->addArray(p,len-(p-s));
ADDARRAY(p,len-(p-s));
}
static inline int computeIndent(const char *s)
......@@ -107,14 +112,14 @@ static inline void copyToOutput(const char *s,int len)
{
if (s[i]=='\n')
{
g_outBuf->addChar('\n');
ADDCHAR('\n');
g_lineNr++;
}
}
}
else
{
g_outBuf->addArray(s,len);
ADDARRAY(s,len);
static int tabSize=Config_getInt("TAB_SIZE");
for (i=0;i<len;i++)
{
......@@ -392,8 +397,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
if (YY_START==CComment && oldSkip && !g_skip)
{
//printf("** Adding start of comment!\n");
g_outBuf->addChar('/');
g_outBuf->addChar('*');
ADDCHAR('/');
ADDCHAR('*');
}
}
<CondLine>[a-z_A-Z][a-z_A-Z0-9.\-]* {
......@@ -402,8 +407,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
if (g_condCtx==CComment && !oldSkip && g_skip)
{
//printf("** Adding terminator for comment!\n");
g_outBuf->addChar('*');
g_outBuf->addChar('/');
ADDCHAR('*');
ADDCHAR('/');
}
BEGIN(g_condCtx);
}
......@@ -483,6 +488,7 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
}
if (Debug::isFlagSet(Debug::CommentCnv))
{
g_outBuf->at(g_outBuf->curPos())='\0';
msg("-------------\n%s\n-------------\n",g_outBuf->data());
}
}
......
......@@ -1856,6 +1856,14 @@ void Config::create()
"don't exist or using markup commands wrongly. \n",
TRUE
);
cb = addBool( "WARN_NO_PARAMDOC",
"This WARN_NO_PARAMDOC option can be abled to get warnings for \n"
"functions that are documented, but have no documentation for their parameters \n"
"or return value. If set to NO (the default) doxygen will only warn about \n"
"wrong or incomplete parameter documentation, but not about the absence of \n"
"documentation.\n",
FALSE
);
cs = addString(
"WARN_FORMAT",
"The WARN_FORMAT tag determines the format of the warning messages that \n"
......
......@@ -753,3 +753,42 @@ QCString Definition::convertNameToFile(const char *name,bool allowDots) const
}
}
void Definition::writePathFragment(OutputList &ol) const
{
if (m_outerScope && m_outerScope!=Doxygen::globalScope)
{
m_outerScope->writePathFragment(ol);
ol.writeString("&nbsp;");
if (m_outerScope->definitionType()==Definition::TypeClass ||
m_outerScope->definitionType()==Definition::TypeNamespace)
{
if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
{
ol.writeString(".");
}
else
{
ol.writeString("::");
}
}
else
{
ol.writeString("/");
}
ol.writeString("&nbsp;");
}
ol.writeObjectLink(getReference(),getOutputFileBase(),0,m_localName);
}
void Definition::writeNavigationPath(OutputList &ol) const
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
ol.writeString("<div class=\"nav\">\n");
writePathFragment(ol);
ol.writeString("</div>\n");
ol.popGeneratorState();
}
......@@ -193,6 +193,9 @@ class Definition
GroupList *partOfGroups() const { return m_partOfGroups; }
QCString convertNameToFile(const char *name,bool allowDots=FALSE) const;
void writePathFragment(OutputList &ol) const;
void writeNavigationPath(OutputList &ol) const;
protected:
int m_startBodyLine; // line number of the start of the definition
int m_endBodyLine; // line number of the end of the definition
......
......@@ -41,6 +41,16 @@ DirDef::~DirDef()
{
}
bool DirDef::isLinkableInProject() const
{
return !isReference() && Config_getBool("SHOW_DIRECTORIES");
}
bool DirDef::isLinkable() const
{
return isReference() || isLinkableInProject();
}
void DirDef::addSubDir(DirDef *subdir)
{
m_subdirs.inSort(subdir);
......@@ -213,6 +223,18 @@ void DirDef::writeDocumentation(OutputList &ol)
ol.writeString(fd->name());
ol.endBold();
}
if (fd->generateSourceFile())
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
ol.docify(" ");
ol.startTextLink(fd->includeName(),0);
ol.docify("[");
ol.parseText(theTranslator->trCode());
ol.docify("]");
ol.endTextLink();
ol.popGeneratorState();
}
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
{
Doxygen::tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl;
......@@ -247,6 +269,7 @@ void DirDef::writeDocumentation(OutputList &ol)
ol.popGeneratorState();
}
#if 0
void DirDef::writePathFragment(OutputList &ol) const
{
if (m_parent)
......@@ -268,6 +291,7 @@ void DirDef::writeNavigationPath(OutputList &ol)
ol.popGeneratorState();
}
#endif
void DirDef::setLevel()
{
......@@ -407,6 +431,7 @@ UsedDir::~UsedDir()
{
}
void UsedDir::addFileDep(FileDef *srcFd,FileDef *dstFd)
{
m_filePairs.inSort(srcFd->getOutputFileBase()+dstFd->getOutputFileBase(),
......
......@@ -51,8 +51,8 @@ class DirDef : public Definition
// accessors
virtual DefType definitionType() { return TypeDir; }
virtual QCString getOutputFileBase() const;
virtual bool isLinkableInProject() const { return !isReference() && hasDocumentation(); }
virtual bool isLinkable() const { return isReference() || isLinkableInProject(); }
virtual bool isLinkableInProject() const;
virtual bool isLinkable() const;
QCString displayName() const { return m_dispName; }
QCString shortName() const { return m_shortName; }
void addSubDir(DirDef *subdir);
......@@ -70,9 +70,9 @@ class DirDef : public Definition
// generate output
void writeDetailedDocumentation(OutputList &ol);
void writeDocumentation(OutputList &ol);
void writeNavigationPath(OutputList &ol);
void writeDepGraph(QTextStream &t);
void writePathFragment(OutputList &ol) const;
//void writePathFragment(OutputList &ol) const;
//void writeNavigationPath(OutputList &ol);
static DirDef *mergeDirectoryInTree(const QCString &path);
bool visited;
......
......@@ -62,6 +62,7 @@ static const char *sectionLevelToName[] =
// global variables during a call to validatingParseDoc
static bool g_hasParamCommand;
static bool g_hasReturnCommand;
static MemberDef * g_memberDef;
static QDict<void> g_paramsFound;
static bool g_isExample;
......@@ -317,11 +318,9 @@ static void checkUndocumentedParams()
}
if (found)
{
QString scope=g_memberDef->getScopeString();
if (!scope.isEmpty()) scope+="::"; else scope="";
QString errMsg=(QString)
QString errMsg=
"Warning: The following parameters of "+
scope + QString(g_memberDef->name()) +
QString(g_memberDef->qualifiedName()) +
QString(argListToString(al)) +
" are not documented:\n";
for (ali.toFirst();(a=ali.current());++ali)
......@@ -338,6 +337,69 @@ static void checkUndocumentedParams()
}
}
/*! Check if a member has documentation for its parameter and or return
* type, if applicable.
*/
static void checkNoDocumentedParams()
{
if (g_memberDef && Config_getBool("WARN_NO_PARAMDOC"))
{
ArgumentList *al= g_memberDef->argumentList();
ArgumentList *declAl = g_memberDef->declArgumentList();
QString returnType = g_memberDef->typeString();
if (!g_hasParamCommand && // no @param command
al && // but the member has a parameter list
al->count()>0 // with at least one parameter (that is not void)
)
{
ArgumentListIterator ali(*al);
Argument *a;
bool allDoc=TRUE;
for (ali.toFirst();(a=ali.current()) && allDoc;++ali)
{
allDoc = !a->docs.isEmpty();
printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data());
}
if (!allDoc)
{
if (declAl) // try declaration arguments as well
{
allDoc=TRUE;
ArgumentListIterator ali(*declAl);
Argument *a;
for (ali.toFirst();(a=ali.current()) && allDoc;++ali)
{
allDoc = !a->docs.isEmpty();
printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data());
}
}
if (!allDoc)
{
QString errMsg =
"Warning: the parameters of member "+
QString(g_memberDef->qualifiedName())+
QString(argListToString(al))+
" are not documented.";
warn_doc_error(g_memberDef->docFile(),g_memberDef->docLine(),errMsg);
}
}
}
if (!g_hasReturnCommand && // no @return or @retval commands
!returnType.isEmpty() && // non empty
returnType!="void" // end non void return type
)
{
QString errMsg =
"Warning: the return type or values of member "+
QString(g_memberDef->qualifiedName())+
QString(argListToString(al))+
" are not documented.";
warn_doc_error(g_memberDef->docFile(),g_memberDef->docLine(),errMsg);
}
}
}
//---------------------------------------------------------------------------
/*! Strips known html and tex extensions from \a text. */
......@@ -3227,7 +3289,7 @@ int DocParamList::parse(const QString &cmdName)
}
else if (m_type==DocParamSect::RetVal)
{
//g_hasParamCommand=TRUE;
g_hasReturnCommand=TRUE;
checkArgumentName(g_token->name,FALSE);
}
m_params.append(g_token->name);
......@@ -3696,6 +3758,7 @@ int DocPara::handleCommand(const QString &cmdName)
break;
case CMD_RETURN:
retval = handleSimpleSection(DocSimpleSect::Return);
g_hasReturnCommand=TRUE;
break;
case CMD_AUTHOR:
retval = handleSimpleSection(DocSimpleSect::Author);
......@@ -4890,7 +4953,7 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
Definition *ctx,MemberDef *md,
const char *input,bool indexWords,
bool isExample, const char *exampleName,
bool singleLine)
bool singleLine,bool isParam)
{
//printf("validatingParseDoc(%s,%s)\n",ctx?ctx->name().data():"<none>",
......@@ -5003,6 +5066,7 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
g_isExample = isExample;
g_exampleName = exampleName;
g_hasParamCommand = FALSE;
g_hasReturnCommand = FALSE;
g_paramsFound.setAutoDelete(FALSE);
g_paramsFound.clear();
g_sectionDict = 0; //sections;
......@@ -5022,7 +5086,11 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
delete v;
}
checkUndocumentedParams();
if (!isParam)
{
checkUndocumentedParams();
checkNoDocumentedParams();
}
delete g_token;
......@@ -5055,6 +5123,7 @@ DocNode *validatingParseText(const char *input)
g_isExample = FALSE;
g_exampleName = "";
g_hasParamCommand = FALSE;
g_hasReturnCommand = FALSE;
g_paramsFound.setAutoDelete(FALSE);
g_paramsFound.clear();
g_searchUrl="";
......
......@@ -53,6 +53,7 @@ void initDocParser();
* @param exampleName Base name of the example file (0 if isExample is FALSE).
* @param singleLine Output should be presented on a single line, so without
* starting a new paragraph at the end.
* @param isParam TRUE if the documentation is for a parameter.
* @returns Root node of the abstract syntax tree. Ownership of the
* pointer is handed over to the caller.
*/
......@@ -60,7 +61,7 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
Definition *context, MemberDef *md,
const char *input,bool indexWords,
bool isExample,const char *exampleName=0,
bool singleLine=FALSE);
bool singleLine=FALSE,bool isParam=FALSE);
/*! Main entry point for parsing simple text fragments. These
* fragments are limited to words, whitespace and symbols.
......
......@@ -511,6 +511,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
}
}
#if 0
static bool addNamespace(Entry *root,ClassDef *cd)
{
// see if this class is defined inside a namespace
......@@ -539,6 +540,7 @@ static bool addNamespace(Entry *root,ClassDef *cd)
}
return FALSE;
}
#endif
static Definition *findScope(Entry *root,int level=0)
{
......@@ -698,7 +700,7 @@ static void addClassToContext(Entry *root)
{
addIncludeFile(cd,fd,root);
}
addNamespace(root,cd);
//addNamespace(root,cd);
if (fd && (root->section & Entry::COMPOUND_MASK))
{
//printf(">> Inserting class `%s' in file `%s' (root->fileName=`%s')\n",
......@@ -793,7 +795,7 @@ static void addClassToContext(Entry *root)
cd->setRefItems(root->sli);
// see if the class is found inside a namespace
bool found=addNamespace(root,cd);
//bool found=addNamespace(root,cd);
cd->setFileDef(fd);
if (cd->hasDocumentation())
......@@ -801,6 +803,7 @@ static void addClassToContext(Entry *root)
addIncludeFile(cd,fd,root);
}
#if 0
// namespace is part of the class name
if (!found && !namespaceName.isEmpty())
{
......@@ -824,6 +827,7 @@ static void addClassToContext(Entry *root)
// );
fd->insertClass(cd);
}
#endif
// the empty string test is needed for extract all case
cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
......@@ -1720,7 +1724,7 @@ static MemberDef *addVariableToFile(
*/
static int findFunctionPtr(const QCString &type,int *pLength=0)
{
static const QRegExp re("([^)]*");
static const QRegExp re("([^)]\\*");
int i=-1,l;
if (!type.isEmpty() && // return type is non-empty
(i=re.match(type,0,&l))!=-1 && // contains a (*
......@@ -1901,6 +1905,7 @@ static void buildVarList(Entry *root)
{
root->type=root->type.left(root->type.length()-1);
root->args.prepend(")");
printf("root->type=%s root->args=%s\n",root->type.data(),root->args.data());
}
}
}
......@@ -4722,10 +4727,43 @@ static void findMember(Entry *root,
className.data(),namespaceName.data()
);
// TODO: match loop for all possible scopes
//#define NEWMATCH
#ifdef NEWMATCH
bool matching=
md->isVariable() || md->isTypedef() || // needed for function pointers
(md->argumentList()==0 && root->argList->count()==0) ||
matchArguments2(
md->getClassDef(),md->getFileDef(),argList,
cd,fd,root->argList,
TRUE);
bool ambig;
FileDef *fd=findFileDef(Doxygen::inputNameDict,root->fileName,ambig);
Debug::print(Debug::FindMembers,0,
"6. match results of matchArguments2 = %d\n",matching);
if (substDone) // found a new argument list
{
if (matching) // replace member's argument list
{
md->setDefinitionTemplateParameterLists(root->tArgLists);
md->setArgumentList(argList);
}
else // no match -> delete argument list
{
delete argList;
}
}
if (matching)
{
//printf("addMemberDocs root->inLine=%d md->isInline()=%d\n",
// root->inLine,md->isInline());
addMemberDocs(root,md,funcDecl,0,overloaded,0/* TODO */);
count++;
memFound=TRUE;
}
#else // old matching routine
// TODO: match loop for all possible scopes
// list of namespaces using in the file/namespace that this
// member definition is part of
......@@ -4829,6 +4867,7 @@ static void findMember(Entry *root,
}
delete cl;
delete nl;
#endif
}
}
if (count==0 && root->parent && root->parent->section==Entry::OBJCIMPL_SEC)
......@@ -7294,6 +7333,55 @@ static void copyStyleSheet()
}
}
#ifdef USE_TMP_FILE
static void readFiles(const QCString &tmpFile)
{
QFile outFile(tmpFile);
if (outFile.open(IO_WriteOnly))
{
QTextStream out(&outFile);
QCString *s=inputFiles.first();
while (s)
{
QCString fileName=*s;
//bool multiLineIsBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF");
out << (char)6;
out << fileName;
out << (char)6;
out << '\n';
QFileInfo fi(fileName);
BufStr preBuf(fi.size()+4096);
BufStr *bufPtr = &preBuf;
if (Config_getBool("ENABLE_PREPROCESSING"))
{
msg("Preprocessing %s...\n",s->data());
preprocessFile(fileName,*bufPtr);
}
else
{
msg("Reading %s...\n",s->data());
copyAndFilterFile(fileName,*bufPtr);
}
bufPtr->addChar('\n'); /* to prevent problems under Windows ? */
BufStr convBuf(bufPtr->curPos()+1024);
convertCppComments(&preBuf,&convBuf,fileName);
out.writeRawBytes(convBuf.data(),convBuf.curPos());
s=inputFiles.next();
//printf("-------> adding new line\n");
}
}
}
#else
//----------------------------------------------------------------------------
// Reads a file to a string.
// The name of the file is written in front of the file's contents and
......@@ -7342,6 +7430,7 @@ static void readFiles(BufStr &output)
}
output.addChar(0);
}
#endif
//----------------------------------------------------------------------------
// Read all files matching at least one pattern in `patList' in the
......@@ -8230,27 +8319,6 @@ void parseInput()
s=tagFileList.next();
}
/**************************************************************************
* Read Input Files *
**************************************************************************/
BufStr input(inputSize+1); // Add one byte extra for \0 termination
// read and preprocess all input files
readFiles(input);
if (input.isEmpty())
{
err("No input read, no output generated!\n");
delete root;
cleanUpDoxygen();
exit(1);
}
else
{
msg("Read %d bytes\n",input.curPos());
}
/**************************************************************************
* Check/create output directorties *
**************************************************************************/
......@@ -8386,17 +8454,69 @@ void parseInput()
readFormulaRepository();
}
root->program=input;
/**************************************************************************
* Gather information *
* Read Input Files *
**************************************************************************/
#ifdef USE_TMP_FILE
QCString tmpName = Config_getString("OUTPUT_DIRECTORY")+
"/doxygen_scratchfile.tmp";
// read and preprocess all input files
readFiles(tmpName);
QFileInfo fi(tmpName);
if (fi.size()==0)
{
err("No input read, no output generated!\n");
delete root;
cleanUpDoxygen();
exit(1);
}
else
{
msg("Read %d bytes\n",fi.size());
}
msg("Parsing input...\n");
parseMain(root,tmpName); // build a tree of entries
// remove temp file
QDir().remove(tmpName);
#else // use memory to store intermediate results
BufStr input(inputSize+1); // Add one byte extra for \0 termination
// read and preprocess all input files
readFiles(input);
if (input.isEmpty())
{
err("No input read, no output generated!\n");
delete root;
cleanUpDoxygen();
exit(1);
}
else
{
msg("Read %d bytes\n",input.curPos());
}
root->program=input;
msg("Parsing input...\n");
parseMain(root); // build a tree of entries
msg("Freeing input...\n");
input.resize(0);
#endif
/**************************************************************************
* Gather information *
**************************************************************************/
msg("Building group list...\n");
buildGroupList(root);
......
......@@ -123,4 +123,7 @@ void readConfiguration(int argc, char **argv);
void parseInput();
void generateOutput();
#undef USE_TMP_FILE
//#define USE_TMP_FILE
#endif
......@@ -38,11 +38,11 @@ GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t,
const char *refFileName) : Definition(df,dl,na)
{
fileList = new FileList;
classSDict = new ClassSDict(257);
classSDict = new ClassSDict(17);
groupList = new GroupList;
namespaceList = new NamespaceList;
pageDict = new PageSDict(257);
exampleDict = new PageSDict(257);
namespaceSDict = new NamespaceSDict(17);
pageDict = new PageSDict(17);
exampleDict = new PageSDict(17);
dirList = new DirList;
allMemberList = new MemberList;
allMemberNameInfoSDict = new MemberNameInfoSDict(17);
......@@ -81,7 +81,7 @@ GroupDef::~GroupDef()
delete fileList;
delete classSDict;
delete groupList;
delete namespaceList;
delete namespaceSDict;
delete pageDict;
delete exampleDict;
delete allMemberList;
......@@ -152,9 +152,9 @@ void GroupDef::addClass(const ClassDef *cd)
void GroupDef::addNamespace(const NamespaceDef *def)
{
if (Config_getBool("SORT_BRIEF_DOCS"))
namespaceList->inSort(def);
namespaceSDict->inSort(def->name(),def);
else
namespaceList->append(def);
namespaceSDict->append(def->name(),def);
}
void GroupDef::addDir(const DirDef *def)
......@@ -414,7 +414,7 @@ int GroupDef::countMembers() const
{
return fileList->count()+
classSDict->count()+
namespaceList->count()+
namespaceSDict->count()+
groupList->count()+
allMemberList->count()+
pageDict->count()+
......@@ -547,35 +547,7 @@ void GroupDef::writeDocumentation(OutputList &ol)
}
// write list of namespaces
if (namespaceList->count()>0)
{
ol.startMemberHeader();
ol.parseText(theTranslator->trNamespaces());
ol.endMemberHeader();
ol.startMemberList();
NamespaceDef *nd=namespaceList->first();
while (nd)
{
ol.startMemberItem(0);
ol.docify("namespace ");
ol.insertMemberAlign();
ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,nd->name());
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
{
Doxygen::tagFile << " <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl;
}
ol.endMemberItem();
if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
{
ol.startMemberDescription();
ol.parseDoc(briefFile(),briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE);
ol.endMemberDescription();
ol.newParagraph();
}
nd=namespaceList->next();
}
ol.endMemberList();
}
namespaceSDict->writeDeclaration(ol);
// write list of groups
if (groupList->count()>0)
......@@ -640,7 +612,6 @@ void GroupDef::writeDocumentation(OutputList &ol)
ol.endMemberList();
}
// write list of classes
classSDict->writeDeclaration(ol);
......
......@@ -32,7 +32,7 @@ class ClassDef;
class NamespaceDef;
class GroupList;
class OutputList;
class NamespaceList;
class NamespaceSDict;
class MemberGroupSDict;
class MemberNameInfoSDict;
class PageSDict;
......@@ -108,7 +108,7 @@ class GroupDef : public Definition
FileList * getFiles() const { return fileList; }
ClassSDict * getClasses() const { return classSDict; }
NamespaceList * getNamespaces() const { return namespaceList; }
NamespaceSDict * getNamespaces() const { return namespaceSDict; }
GroupList * getSubGroups() const { return groupList; }
PageSDict * getPages() const { return pageDict; }
DirList * getDirs() const { return dirList; }
......@@ -117,16 +117,16 @@ class GroupDef : public Definition
void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const);
private:
QCString title; // title of the group
bool titleSet; // true if title is not the same as the name
QCString fileName; // base name of the generated file
FileList *fileList; // list of files 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.
PageSDict *pageDict; // list of pages in the group
PageSDict *exampleDict; // list of examples in the group
DirList *dirList; // list of directories in the group
QCString title; // title of the group
bool titleSet; // true if title is not the same as the name
QCString fileName; // base name of the generated file
FileList *fileList; // list of files in the group
ClassSDict *classSDict; // list of classes in the group
NamespaceSDict *namespaceSDict; // list of namespaces in the group
GroupList *groupList; // list of sub groups.
PageSDict *pageDict; // list of pages in the group
PageSDict *exampleDict; // list of examples in the group
DirList *dirList; // list of directories in the group
MemberList *allMemberList;
MemberNameInfoSDict *allMemberNameInfoSDict;
......
......@@ -46,8 +46,18 @@ static const char *defaultStyleSheet =
"BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {\n"
" font-family: Geneva, Arial, Helvetica, sans-serif;\n"
"}\n"
"BODY {\n"
" font-size: 90%;\n"
"}\n"
"H1 {\n"
" text-align: center;\n"
" font-size: 160%;\n"
"}\n"
"H2 {\n"
" font-size: 120%;\n"
"}\n"
"H3 {\n"
" font-size: 110%;\n"
"}\n"
"CAPTION { font-weight: bold }\n"
"DIV.qindex {\n"
......@@ -134,7 +144,7 @@ static const char *defaultStyleSheet =
" margin-bottom: 6px;\n"
" font-weight: bold;\n"
"}\n"
"DIV.groupText { margin-left: 16px; font-style: italic; font-size: 14px }\n"
"DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }\n"
"BODY {\n"
" background: white;\n"
" color: black;\n"
......@@ -189,7 +199,7 @@ static const char *defaultStyleSheet =
"}\n"
".mdescLeft {\n"
" padding: 0px 8px 4px 8px;\n"
" font-size: 12px;\n"
" font-size: 80%;\n"
" font-style: italic;\n"
" background-color: #FAFAFA;\n"
" border-top: 1px none #E0E0E0;\n"
......@@ -200,7 +210,7 @@ static const char *defaultStyleSheet =
"}\n"
".mdescRight {\n"
" padding: 0px 8px 4px 8px;\n"
" font-size: 12px;\n"
" font-size: 80%;\n"
" font-style: italic;\n"
" background-color: #FAFAFA;\n"
" border-top: 1px none #E0E0E0;\n"
......@@ -225,7 +235,7 @@ static const char *defaultStyleSheet =
" border-bottom-style: none;\n"
" border-left-style: none;\n"
" background-color: #FAFAFA;\n"
" font-size: 12px;\n"
" font-size: 80%;\n"
"}\n"
".memItemRight {\n"
" padding: 1px 8px 0px 8px;\n"
......@@ -243,7 +253,7 @@ static const char *defaultStyleSheet =
" border-bottom-style: none;\n"
" border-left-style: none;\n"
" background-color: #FAFAFA;\n"
" font-size: 13px;\n"
" font-size: 80%;\n"
"}\n"
".memTemplItemLeft {\n"
" padding: 1px 0px 0px 8px;\n"
......@@ -261,7 +271,7 @@ static const char *defaultStyleSheet =
" border-bottom-style: none;\n"
" border-left-style: none;\n"
" background-color: #FAFAFA;\n"
" font-size: 12px;\n"
" font-size: 80%;\n"
"}\n"
".memTemplItemRight {\n"
" padding: 1px 8px 0px 8px;\n"
......@@ -279,7 +289,7 @@ static const char *defaultStyleSheet =
" border-bottom-style: none;\n"
" border-left-style: none;\n"
" background-color: #FAFAFA;\n"
" font-size: 13px;\n"
" font-size: 80%;\n"
"}\n"
".memTemplParams {\n"
" padding: 1px 0px 0px 8px;\n"
......@@ -298,7 +308,7 @@ static const char *defaultStyleSheet =
" border-left-style: none;\n"
" color: #606060;\n"
" background-color: #FAFAFA;\n"
" font-size: 12px;\n"
" font-size: 80%;\n"
"}\n"
".search { color: #003399;\n"
" font-weight: bold;\n"
......@@ -326,9 +336,14 @@ static const char *defaultStyleSheet =
"}\n"
"TH.dirtab { background: #eeeeff;\n"
" font-weight: bold;\n"
"}\n"
"HR { height: 1px;\n"
" border: none;\n"
" border-top: 1px solid black;\n"
"}\n";
static QCString g_header;
static QCString g_footer;
......
......@@ -2539,7 +2539,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
numSubItems += gd->docFuncMembers.count();
numSubItems += gd->docVarMembers.count();
numSubItems += gd->docProtoMembers.count();
numSubItems += gd->namespaceList->count();
numSubItems += gd->namespaceSDict->count();
numSubItems += gd->classSDict->count();
numSubItems += gd->fileList->count();
numSubItems += gd->exampleDict->count();
......@@ -2676,8 +2676,8 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
}
// write namespaces
NamespaceList *namespaceList=gd->namespaceList;
if (namespaceList->count()>0)
NamespaceSDict *namespaceSDict=gd->namespaceSDict;
if (namespaceSDict->count()>0)
{
if (htmlHelp)
{
......@@ -2692,8 +2692,9 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
ftvHelp->incContentsDepth();
}
NamespaceDef *nsd=namespaceList->first();
while (nsd)
NamespaceSDict::Iterator ni(*namespaceSDict);
NamespaceDef *nsd;
for (ni.toFirst();(nsd=ni.current());++ni)
{
if (htmlHelp)
{
......@@ -2703,7 +2704,6 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
{
ftvHelp->addContentsItem(FALSE, nsd->getReference(), nsd->getOutputFileBase(), 0, convertToHtml(nsd->name()));
}
nsd=namespaceList->next();
}
if (htmlHelp) htmlHelp->decContentsDepth();
if (ftvHelp) ftvHelp->decContentsDepth();
......
......@@ -1378,7 +1378,7 @@ void LatexGenerator::writeNonBreakableSpace(int)
m_indent++;
}
else
t << "\\ ";
t << "~";
}
void LatexGenerator::startMemberList()
......
......@@ -1582,7 +1582,16 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
ol.docify(a->name);
ol.endDescTableTitle();
ol.startDescTableData();
ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,a->docs+"\n",TRUE,FALSE);
ol.parseDoc(docFile(),docLine(),
getOuterScope()?getOuterScope():container,
this,
a->docs+"\n", // docStr
TRUE, // indexWords
FALSE, // isExample
0, // exampleName
FALSE, // singleLine
TRUE // isParam
);
ol.endDescTableData();
}
}
......
......@@ -44,7 +44,7 @@ NamespaceDef::NamespaceDef(const char *df,int dl,
}
classSDict = new ClassSDict(17);
namespaceSDict = new NamespaceSDict(17);
m_innerCompounds = new SDict<Definition>(257);
m_innerCompounds = new SDict<Definition>(17);
usingDirList = 0;
usingDeclList = 0;
setReference(lref);
......@@ -283,6 +283,10 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
pageTitle = theTranslator->trNamespaceReference(displayName());
}
startFile(ol,getOutputFileBase(),name(),pageTitle);
if (getOuterScope()!=Doxygen::globalScope)
{
writeNavigationPath(ol);
}
startTitle(ol,getOutputFileBase());
ol.parseText(pageTitle);
addGroupListToTitle(ol,this);
......@@ -330,7 +334,9 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
ol.endTextBlock();
ol.startMemberSections();
classSDict->writeDeclaration(ol);
classSDict->writeDeclaration(ol,0,0,TRUE);
namespaceSDict->writeDeclaration(ol,TRUE);
/* write user defined member groups */
MemberGroupSDict::Iterator mgli(*memberGroupSDict);
......@@ -508,3 +514,59 @@ void NamespaceDef::combineUsingRelations()
}
}
void NamespaceSDict::writeDeclaration(OutputList &ol,bool localName)
{
if (count()==0) return;
// write list of namespaces
ol.startMemberHeader();
bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
if (javaOpt)
{
ol.parseText(theTranslator->trPackages());
}
else
{
ol.parseText(theTranslator->trNamespaces());
}
ol.endMemberHeader();
ol.startMemberList();
SDict<NamespaceDef>::Iterator ni(*this);
NamespaceDef *nd;
for (ni.toFirst();(nd=ni.current());++ni)
{
ol.startMemberItem(0);
if (javaOpt)
{
ol.docify("package ");
}
else
{
ol.docify("namespace ");
}
ol.insertMemberAlign();
QCString name;
if (localName)
{
name = nd->localName();
}
else
{
name = nd->displayName();
}
ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,name);
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
{
Doxygen::tagFile << " <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl;
}
ol.endMemberItem();
if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
{
ol.startMemberDescription();
ol.parseDoc(nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE);
ol.endMemberDescription();
ol.newParagraph();
}
}
ol.endMemberList();
}
......@@ -163,6 +163,7 @@ class NamespaceSDict : public SDict<NamespaceDef>
((NamespaceDef *)item2)->name()
);
}
void writeDeclaration(OutputList &ol,bool localName=FALSE);
};
......
......@@ -133,7 +133,7 @@ void OutputList::parseDoc(const char *fileName,int startLine,
Definition *ctx,MemberDef * md,
const QCString &docStr,bool indexWords,
bool isExample,const char *exampleName,
bool singleLine)
bool singleLine,bool isParam)
{
int count=0;
if (docStr.isEmpty()) return;
......@@ -151,13 +151,13 @@ void OutputList::parseDoc(const char *fileName,int startLine,
{
root = validatingParseDoc(fileName,startLine,
ctx,md,docStr,indexWords,isExample,exampleName,
singleLine);
singleLine,isParam);
}
else
{
root = validatingParseDoc(fileName,startLine,
ctx,md,docStr+"\n",indexWords,isExample,exampleName,
singleLine);
singleLine,isParam);
}
og=outputs->first();
......
......@@ -64,7 +64,7 @@ class OutputList : public OutputDocInterface
void parseDoc(const char *fileName,int startLine,
Definition *ctx,MemberDef *md,const QCString &docStr,
bool indexWords,bool isExample,const char *exampleName=0,
bool singleLine=FALSE);
bool singleLine=FALSE,bool isParam=FALSE);
void parseText(const QCString &textStr);
......
......@@ -1900,11 +1900,11 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
m_output.closeList();
}
NamespaceList *nl = gd->getNamespaces();
NamespaceSDict *nl = gd->getNamespaces();
if (nl)
{
m_output.openList("namespaces");
NamespaceListIterator nli(*nl);
NamespaceSDict::Iterator nli(*nl);
NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
m_output.openHash()
......
......@@ -24,5 +24,6 @@ class OutputList;
class Entry;
extern void parseMain(Entry *);
extern void parseMain(Entry *,const char *fileName);
#endif
......@@ -30,6 +30,7 @@
#include <qstack.h>
#include <qregexp.h>
#include <unistd.h>
#include <qfile.h>
#include "scanner.h"
#include "entry.h"
......@@ -54,6 +55,7 @@
*/
static const char * inputString;
static int inputPosition;
static QFile inputFile;
static int lastContext;
static int lastCContext;
static int lastDocContext;
......@@ -169,6 +171,7 @@ static QCString g_skipBlockName;
static QCString oldStyleArgType;
static QCString docBackup;
static QCString briefBackup;
static bool g_inputFromFile;
//-----------------------------------------------------------------------------
......@@ -644,11 +647,21 @@ static void addKnRArgInfo(const QCString &type,const QCString &name,
static int yyread(char *buf,int max_size)
{
int c=0;
while( c < max_size && inputString[inputPosition] )
#ifdef USE_TMP_FILE
if (g_inputFromFile)
{
c = inputFile.readBlock(buf,max_size);
if (c==-1) yy_fatal_error("input in flex scanner failed");
}
else
#endif
{
while( c < max_size && inputString[inputPosition] )
{
*buf = inputString[inputPosition++] ;
//printf("%d (%c)\n",*buf,*buf);
c++; buf++;
}
}
return c;
}
......@@ -5925,6 +5938,7 @@ static void newDocState()
static void parseCompounds(Entry *rt)
{
//printf("parseCompounds(%s)\n",rt->name.data());
g_inputFromFile = FALSE;
EntryListIterator eli(*rt->sublist);
Entry *ce;
for (;(ce=eli.current());++eli)
......@@ -6019,10 +6033,55 @@ static void parseCompounds(Entry *rt)
}
//----------------------------------------------------------------------------
#ifdef USE_TMP_FILE
void parseMain(Entry *rt,const char *fileName)
{
initParser();
g_inputFromFile = TRUE;
anonCount = 0;
depthIf = 0;
protection = Public;
mtype = Method;
gstat = FALSE;
virt = Normal;
current_root = rt;
global_root = rt;
inputFile.setName(fileName);
if (inputFile.open(IO_ReadOnly))
{
current = new Entry;
inputPosition = 0;
scanYYrestart( scanYYin );
BEGIN( FindMembers );
scanYYlex();
if (YY_START==Comment)
{
warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
}
forceEndGroup();
if (depthIf>0)
{
warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
}
rt->program.resize(0);
delete current; current=0;
parseCompounds(rt);
inputFile.close();
}
}
#else
void parseMain(Entry *rt)
{
initParser();
g_inputFromFile = FALSE;
anonCount = 0;
depthIf = 0;
protection = Public;
......@@ -6054,6 +6113,10 @@ void parseMain(Entry *rt)
parseCompounds(rt);
}
#endif
//----------------------------------------------------------------------------
#if !defined(YY_FLEX_SUBMINOR_VERSION)
//----------------------------------------------------------------------------
extern "C" { // some bogus code to keep the compiler happy
......
......@@ -59,6 +59,14 @@ const uint SDict_primes[] =
5516827,
8826919,
14123059,
23538433,
39230771,
65384537,
108974231,
181623707,
302706181,
504510283,
840850487,
0xffffffff
};
#endif
......
......@@ -522,7 +522,7 @@ class TranslatorGerman : public Translator
* of documentation blocks for typedefs
*/
virtual QCString trTypedefDocumentation()
{ return "Dokumentation der benutzerdefinerten Typen"; }
{ return "Dokumentation der benutzerdefinierten Typen"; }
/*! This is used in the documentation of a file/namespace before the list
* of documentation blocks for enumeration types
......@@ -1662,7 +1662,7 @@ class TranslatorGerman : public Translator
* directory is passed via \a dirName.
*/
virtual QCString trDirReference(const char *dirName)
{ QCString result=dirName; result+=" Verzeichnisreferenz"; return result; }
{ QCString result=dirName; result+="-Verzeichnisreferenz"; return result; }
/*! This returns the word directory with or without starting capital
* (\a first_capital) and in sigular or plural form (\a singular).
......
......@@ -2602,6 +2602,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *a
{
QCString type = arg->type;
QCString name = arg->name;
printf("extractCanonicalType(type=%s,name=%s)\n",type.data(),name.data());
if ((type=="const" || type=="volatile") && !name.isEmpty())
{ // name is part of type => correct
type+=" ";
......@@ -2623,27 +2624,37 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *a
else if (type.left(5)=="enum ") type=type.right(type.length()-5);
else if (type.left(9)=="typename ") type=type.right(type.length()-9);
static QRegExp id("[a-z_A-Z][a-z_A-Z0-9]*");
static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*");
QCString canType;
int i,p=0,l;
while ((i=id.match(type,p,&l))) // foreach identifier in the type
while ((i=id.match(type,p,&l))!=-1) // foreach identifier in the type
{
canType += type.mid(p,i-p);
QCString word = type.mid(i,l);
ClassDef *cd = getResolvedClass(d,fs,word);
printf("word %s => %s\n",word.data(),cd?cd->qualifiedName().data():"<none>");
if (cd)
{
canType+=cd->qualifiedName();
}
else
{
canType+=word;
QCString resolvedType = resolveTypeDef(d,word);
if (resolvedType.isEmpty())
{
canType+=word;
}
else
{
canType+=resolvedType;
}
}
p=i+l;
}
canType += type.right(type.length()-p);
printf("result = %s\n",canType.data());
return removeRedundantWhiteSpace(canType);
}
......
......@@ -133,6 +133,10 @@ bool matchArguments(ArgumentList *,ArgumentList *,
const char *cl=0,const char *ns=0,bool checkCV=TRUE,
NamespaceSDict *usingNamespaces=0,
SDict<Definition> *usingClasses=0);
bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
bool checkCV
);
void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE);
QCString substituteClassNames(const QCString &s);
QCString substitute(const char *s,const char *src,const char *dst);
......
......@@ -1402,10 +1402,10 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
<< "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
}
}
NamespaceList *nl = gd->getNamespaces();
NamespaceSDict *nl = gd->getNamespaces();
if (nl)
{
NamespaceListIterator nli(*nl);
NamespaceSDict::Iterator nli(*nl);
NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment