Commit e4e78701 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Release-1.2.10-20010909

parent 1fb3a775
DOXYGEN Version 1.2.10 DOXYGEN Version 1.2.10-20010909
Please read the installation section of the manual for instructions. Please read the installation section of the manual for instructions.
-------- --------
Dimitri van Heesch (26 August 2001) Dimitri van Heesch (09 September 2001)
DOXYGEN Version 1.2.10 DOXYGEN Version 1.2.10_20010909
Please read INSTALL for compilation instructions. Please read INSTALL for compilation instructions.
...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. ...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy, Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (26 August 2001) Dimitri van Heesch (dimitri@stack.nl) (09 September 2001)
1.2.10 1.2.10-20010909
...@@ -36,7 +36,7 @@ INPUT = index.doc install.doc starting.doc docblocks.doc lists.doc \ ...@@ -36,7 +36,7 @@ INPUT = index.doc install.doc starting.doc docblocks.doc lists.doc \
doxygen_usage.doc doxytag_usage.doc doxysearch_usage.doc \ doxygen_usage.doc doxytag_usage.doc doxysearch_usage.doc \
doxywizard_usage.doc \ doxywizard_usage.doc \
installdox_usage.doc output.doc autolink.doc \ installdox_usage.doc output.doc autolink.doc \
config.doc commands.doc htmlcmds.doc language.doc config.doc commands.doc htmlcmds.doc language.doc arch.doc
FILE_PATTERNS = *.cpp *.h *.doc FILE_PATTERNS = *.cpp *.h *.doc
EXAMPLE_PATH = ../examples EXAMPLE_PATH = ../examples
RECURSIVE = NO RECURSIVE = NO
......
This diff is collapsed.
This diff is collapsed.
...@@ -166,6 +166,7 @@ followed by the descriptions of the tags grouped by category. ...@@ -166,6 +166,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_short_names SHORT_NAMES <li> \refitem cfg_short_names SHORT_NAMES
<li> \refitem cfg_show_include_files SHOW_INCLUDE_FILES <li> \refitem cfg_show_include_files SHOW_INCLUDE_FILES
<li> \refitem cfg_show_used_files SHOW_USED_FILES <li> \refitem cfg_show_used_files SHOW_USED_FILES
<li> \refitem cfg_skip_function_macros SKIP_FUNCTION_MACROS
<li> \refitem cfg_sort_member_docs SORT_MEMBER_DOCS <li> \refitem cfg_sort_member_docs SORT_MEMBER_DOCS
<li> \refitem cfg_source_browser SOURCE_BROWSER <li> \refitem cfg_source_browser SOURCE_BROWSER
<li> \refitem cfg_strip_code_comments STRIP_CODE_COMMENTS <li> \refitem cfg_strip_code_comments STRIP_CODE_COMMENTS
...@@ -1070,6 +1071,14 @@ EXTRA_PACKAGES = times ...@@ -1070,6 +1071,14 @@ EXTRA_PACKAGES = times
The macro definition that is found in the sources will be used. The macro definition that is found in the sources will be used.
Use the \c PREDEFINED tag if you want to use a different macro definition. Use the \c PREDEFINED tag if you want to use a different macro definition.
\anchor cfg_skip_function_macros
<dt>\c SKIP_FUNCTION_MACROS <dd>
\addindex SKIP_FUNCTION_MACROS
If the \c SKIP_FUNCTION_MACROS tag is set to \c YES (the default) then
doxygen's preprocessor will remove all function-like macros that are alone
on a line and do not end with a semicolon. Such function macros are typically
used for boiler-plate code, and will confuse the parser if not removed.
</dl> </dl>
\subsection config_extref External reference options \subsection config_extref External reference options
\anchor cfg_tagfiles \anchor cfg_tagfiles
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
\usepackage{a4wide} \usepackage{a4wide}
\usepackage{makeidx} \usepackage{makeidx}
\usepackage{fancyhdr} \usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{epsf} \usepackage{epsf}
\usepackage{doxygen} \usepackage{doxygen}
\usepackage{multicol} \usepackage{multicol}
...@@ -68,6 +69,8 @@ Written by Dimitri van Heesch\\[2ex] ...@@ -68,6 +69,8 @@ Written by Dimitri van Heesch\\[2ex]
\input{config} \input{config}
\input{commands} \input{commands}
\input{htmlcmds} \input{htmlcmds}
\part{Developers Manual}
\input{arch}
\input{langhowto} \input{langhowto}
\printindex \printindex
\end{document} \end{document}
...@@ -73,7 +73,7 @@ but is set-up to be highly portable. As a result, it runs on most ...@@ -73,7 +73,7 @@ but is set-up to be highly portable. As a result, it runs on most
other Unix flavors as well. Furthermore, an executable for other Unix flavors as well. Furthermore, an executable for
Windows 9x/NT is also available. Windows 9x/NT is also available.
This manual is divided into two parts, each of which is divided into several This manual is divided into three parts, each of which is divided into several
sections. sections.
The first part forms a user manual: The first part forms a user manual:
...@@ -117,11 +117,17 @@ The second part forms a reference manual: ...@@ -117,11 +117,17 @@ The second part forms a reference manual:
used within the documentation. used within the documentation.
<li>Section \ref htmlcmds shows an overview of the HTML commands that <li>Section \ref htmlcmds shows an overview of the HTML commands that
can be used within the documentation. can be used within the documentation.
</ul>
The third part provides information for developers:
<ul>
<li>Section \ref arch gives a global overview of how doxygen is internally
structured.
<li>Section \ref langhowto explains how to add support for new <li>Section \ref langhowto explains how to add support for new
output languages. output languages.
</ul> </ul>
<h2>Projects using doxygen</h2> <h2>Projects using doxygen</h2>
I have compiled a I have compiled a
......
...@@ -25,7 +25,7 @@ Doxygen has built-in support for multiple languages. This means ...@@ -25,7 +25,7 @@ Doxygen has built-in support for multiple languages. This means
that the text fragments that doxygen generates can be produced in that the text fragments that doxygen generates can be produced in
languages other than English (the default) at configuration time. languages other than English (the default) at configuration time.
Currently (version 1.2.9-20010819), 24 languages Currently (version 1.2.10), 24 languages
are supported (sorted alphabetically): are supported (sorted alphabetically):
Brazilian Portuguese, Chinese, Croatian, Czech, Danish, Brazilian Portuguese, Chinese, Croatian, Czech, Danish,
Dutch, English, Finnish, French, German, Dutch, English, Finnish, French, German,
......
Name: doxygen Name: doxygen
Version: 1.2.10 Version: 1.2.10_20010909
Summary: documentation system for C, C++ and IDL Summary: documentation system for C, C++ and IDL
Release: 4 Release: 4
Source: doxygen-%{version}.src.tar.gz Source: doxygen-%{version}.src.tar.gz
......
...@@ -2264,7 +2264,7 @@ bool ClassDef::isReference() const ...@@ -2264,7 +2264,7 @@ bool ClassDef::isReference() const
{ {
if (m_templateMaster) if (m_templateMaster)
{ {
return m_templateMaster->getReference(); return m_templateMaster->isReference();
} }
else else
{ {
......
...@@ -127,6 +127,7 @@ static int g_bodyCurlyCount; ...@@ -127,6 +127,7 @@ static int g_bodyCurlyCount;
static ClassDef * g_classVar; static ClassDef * g_classVar;
static QCString g_saveName; static QCString g_saveName;
static QCString g_saveType; static QCString g_saveType;
static int g_memCallContext;
/*! add class/namespace name s to the scope */ /*! add class/namespace name s to the scope */
static void pushScope(const char *s) static void pushScope(const char *s)
...@@ -196,6 +197,7 @@ static void startCodeLine() ...@@ -196,6 +197,7 @@ static void startCodeLine()
lineAnchor.sprintf("l%05d",g_yyLineNr); lineAnchor.sprintf("l%05d",g_yyLineNr);
Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr); Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
g_code->startLineNumber();
if (!g_includeCodeFragment && d && d->isLinkableInProject()) if (!g_includeCodeFragment && d && d->isLinkableInProject())
{ {
g_currentDefinition = d; g_currentDefinition = d;
...@@ -211,13 +213,12 @@ static void startCodeLine() ...@@ -211,13 +213,12 @@ static void startCodeLine()
g_code->writeCodeLink(d->getReference(),d->getOutputFileBase(), g_code->writeCodeLink(d->getReference(),d->getOutputFileBase(),
anchor,lineNumber); anchor,lineNumber);
g_code->endCodeAnchor(); g_code->endCodeAnchor();
g_code->codify(" ");
} }
else else
{ {
g_code->codify(lineNumber); g_code->codify(lineNumber);
g_code->codify(" ");
} }
g_code->endLineNumber();
} }
g_code->startCodeLine(); g_code->startCodeLine();
if (g_currentFontClass) if (g_currentFontClass)
...@@ -352,12 +353,14 @@ static void addParameter() ...@@ -352,12 +353,14 @@ static void addParameter()
{ {
g_cvd.name=g_parmName.copy().simplifyWhiteSpace(); g_cvd.name=g_parmName.copy().simplifyWhiteSpace();
g_cvd.type=g_parmType.copy().simplifyWhiteSpace(); g_cvd.type=g_parmType.copy().simplifyWhiteSpace();
//printf("searching for parameter `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data());
if (g_cvd.type.isEmpty()) if (g_cvd.type.isEmpty())
{ {
return; return;
} }
else else
{ {
if (g_cvd.type.left(7)=="struct ") g_cvd.type=g_cvd.type.right(g_cvd.type.length()-7);
int i; int i;
if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type])) if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type]))
{ {
...@@ -375,6 +378,10 @@ static void addParameter() ...@@ -375,6 +378,10 @@ static void addParameter()
g_codeParmList.append(new CodeVarDef(g_cvd)); g_codeParmList.append(new CodeVarDef(g_cvd));
} }
} }
else
{
//printf("parameter `%s' `%s' not found!\n",g_cvd.type.data(),g_cvd.name.data());
}
//printf("g_codeParmList.count()=%d\n",g_codeParmList.count()); //printf("g_codeParmList.count()=%d\n",g_codeParmList.count());
} }
} }
...@@ -440,6 +447,21 @@ static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen ...@@ -440,6 +447,21 @@ static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen
} }
else else
{ {
MemberName *mn;
if (cd==0 && (mn=Doxygen::functionNameDict[clName]))
{
if (mn->count()==1)
{
MemberDef *md=mn->getFirst();
Definition *d=md->getNamespaceDef();
if (d==0) d=md->getFileDef();
if (d && md->isLinkable())
{
writeMultiLineCodeLink(ol,d->getReference(),d->getOutputFileBase(),md->anchor(),clName);
return;
}
}
}
codifyLines(clName); codifyLines(clName);
if (clNameLen) *clNameLen=className.length()-1; if (clNameLen) *clNameLen=className.length()-1;
} }
...@@ -466,10 +488,12 @@ static ClassDef *stripClassName(const char *s) ...@@ -466,10 +488,12 @@ static ClassDef *stripClassName(const char *s)
} }
if (cd) if (cd)
{ {
//printf("stripClassName(%s)=%s\n",s,cd->name().data());
return cd; return cd;
} }
p=i+l; p=i+l;
} }
//printf("stripClassName(%s)=<null>\n",s);
return 0; return 0;
} }
...@@ -578,7 +602,10 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName, ...@@ -578,7 +602,10 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName,
//printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n", //printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n",
// varName,memName,g_classScope.data()); // varName,memName,g_classScope.data());
CodeVarDef *cvd=g_codeParmList.last(); CodeVarDef *cvd=g_codeParmList.last();
while (cvd && cvd->name!=varName) cvd=g_codeParmList.prev(); while (cvd && cvd->name!=varName)
{
cvd=g_codeParmList.prev();
}
if (!cvd) if (!cvd)
{ {
cvd=g_codeVarList.last(); cvd=g_codeVarList.last();
...@@ -813,6 +840,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -813,6 +840,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
%x MemberCall2 %x MemberCall2
%x SkipInits %x SkipInits
%x ClassName %x ClassName
%x ClassVar
%x Bases %x Bases
%x SkipSharp %x SkipSharp
%x ReadInclude %x ReadInclude
...@@ -899,12 +927,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -899,12 +927,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_insideBody=FALSE; g_insideBody=FALSE;
} }
} }
<ClassName>";" { <ClassName,ClassVar>";" {
g_code->codify(yytext); g_code->codify(yytext);
g_searchingForBody=FALSE; g_searchingForBody=FALSE;
BEGIN( Body ); BEGIN( Body );
} }
<ClassName>[*&]+ { <ClassName,ClassVar>[*&]+ {
addType(); addType();
g_code->codify(yytext); g_code->codify(yytext);
} }
...@@ -912,12 +940,19 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -912,12 +940,19 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_ccd.name=yytext; g_ccd.name=yytext;
addType(); addType();
generateClassLink(*g_code,yytext); generateClassLink(*g_code,yytext);
BEGIN( ClassVar );
} }
<ClassName>[ \t\n]*":"[ \t\n]* { <ClassVar>{ID} {
g_type = g_ccd.name.copy();
g_name = yytext;
addVariable();
g_code->codify(yytext);
}
<ClassName,ClassVar>[ \t\n]*":"[ \t\n]* {
codifyLines(yytext); codifyLines(yytext);
BEGIN( Bases ); BEGIN( Bases );
} }
<Bases,ClassName>[ \t]*"{"[ \t]* { <Bases,ClassName,ClassVar>[ \t]*"{"[ \t]* {
g_code->codify(yytext); g_code->codify(yytext);
g_curlyCount++; g_curlyCount++;
g_inClass=TRUE; g_inClass=TRUE;
...@@ -1038,7 +1073,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1038,7 +1073,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
addType(); addType();
g_name+=yytext; g_name+=yytext;
} }
<Body>{SCOPENAME}{B}*"<"[^\n\/\{\"\>]*">"/{B}* { // A<T> *pt; <Body>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{B}* { // A<T> *pt;
generateClassLink(*g_code,yytext); generateClassLink(*g_code,yytext);
addType(); addType();
g_name+=yytext; g_name+=yytext;
...@@ -1048,19 +1083,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1048,19 +1083,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
addType(); addType();
g_name+=yytext; g_name+=yytext;
} }
<Body>"("{B}*"*"{B}*{SCOPENAME}*{B}*")"/{B}* { // (*p)->func() <Body>"("{B}*("*"{B}*)*{SCOPENAME}*{B}*")"/{B}* { // (*p)->func()
QCString text=yytext; g_code->codify(yytext);
int s=0; int s=0;while (!isId(yytext[s])) s++;
while (s<yyleng && (text.at(s)=='(' || isspace(text.at(s)))) s++; int e=yyleng-1;while (!isId(yytext[e])) e--;
int e=yyleng-1; QCString varname = ((QCString)yytext).mid(s,e-s+1);
while (e>=0 && (text.at(e)==')' || isspace(yytext[e]))) e--; //QCString text=yytext;
QCString varname = text.mid(s+1,e-s); //QCString tmp=varname.copy();
QCString tmp=varname.copy(); //g_code->codify(text.left(s+1));
g_code->codify(text.left(s+1)); //generateClassLink(*g_code,tmp.data());
generateClassLink(*g_code,tmp.data()); //g_code->codify(text.right(yyleng-e-1));
g_code->codify(text.right(yyleng-e-1));
addType(); addType();
g_name+=varname; g_name=varname;
} }
<Body>{SCOPETNAME}/{B}*"(" { // a() or c::a() or t<A,B>::a() <Body>{SCOPETNAME}/{B}*"(" { // a() or c::a() or t<A,B>::a()
addType(); addType();
...@@ -1119,12 +1153,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1119,12 +1153,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
<Body>"this->" { g_code->codify(yytext); } <Body>"this->" { g_code->codify(yytext); }
<Body>"."|"->" { <Body>"."|"->" {
g_code->codify(yytext); g_code->codify(yytext);
g_memCallContext = YY_START;
BEGIN( MemberCall ); BEGIN( MemberCall );
} }
<MemberCall>{SCOPETNAME}/{B}*"(" { <MemberCall>{SCOPETNAME}/{B}*"(" {
if (!g_name.isEmpty()) if (!g_name.isEmpty())
{ {
generateMemberLink(*g_code,g_name,yytext); generateMemberLink(*g_code,g_name,yytext);
g_name=yytext;
} }
else if (g_classVar) else if (g_classVar)
{ {
...@@ -1133,20 +1169,52 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1133,20 +1169,52 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext); g_code->codify(yytext);
} }
g_classVar=0; g_classVar=0;
g_name.resize(0);
} }
else else
{ {
g_code->codify(yytext); g_code->codify(yytext);
g_name.resize(0);
} }
g_name.resize(0);g_type.resize(0); g_type.resize(0);
g_bracketCount=0; g_bracketCount=0;
BEGIN(FuncCall); if (g_memCallContext==Body)
{
BEGIN(FuncCall);
}
else
{
BEGIN(g_memCallContext);
}
}
<MemberCall>{SCOPENAME}/{B}* {
if (!g_name.isEmpty())
{
generateMemberLink(*g_code,g_name,yytext);
g_name=yytext;
}
else if (g_classVar)
{
if (!generateClassMemberLink(*g_code,g_classVar,yytext))
{
g_code->codify(yytext);
}
g_classVar=0;
g_name.resize(0);
}
else
{
g_code->codify(yytext);
g_name.resize(0);
}
g_type.resize(0);
BEGIN(g_memCallContext);
} }
<MemberCall>[^a-z_A-Z0-9(\n] { <MemberCall>[^a-z_A-Z0-9(\n] {
g_code->codify(yytext); g_code->codify(yytext);
g_type.resize(0); g_type.resize(0);
g_name.resize(0); g_name.resize(0);
BEGIN(Body); BEGIN(g_memCallContext);
} }
<Body>[,=;\[] { <Body>[,=;\[] {
g_code->codify(yytext); g_code->codify(yytext);
...@@ -1211,9 +1279,11 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1211,9 +1279,11 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
<MemberCall2,FuncCall>")" { <MemberCall2,FuncCall>")" {
g_code->codify(yytext); g_code->codify(yytext);
if (--g_bracketCount<=0) if (--g_bracketCount<=0)
g_name.resize(0);g_args.resize(0); {
g_parmType.resize(0);g_parmName.resize(0); g_name.resize(0);g_args.resize(0);
BEGIN( Body ); g_parmType.resize(0);g_parmName.resize(0);
BEGIN( Body );
}
} }
<MemberCall2,FuncCall>")"[ \t\n]*[;:] { <MemberCall2,FuncCall>")"[ \t\n]*[;:] {
codifyLines(yytext); codifyLines(yytext);
...@@ -1295,7 +1365,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1295,7 +1365,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
} }
<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") { <FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") {
g_code->codify(yytext); g_code->codify(yytext);
g_args=yytext; g_name=yytext;
BEGIN( MemberCall2 );
}
<FuncCall,MemberCall2>("("{B}*("*"{B}*)*[a-z_A-Z][a-z_A-Z0-9]*{B}*")"{B}*)/("."|"->") {
g_code->codify(yytext);
int s=0;while (!isId(yytext[s])) s++;
int e=yyleng-1;while (!isId(yytext[e])) e--;
g_name=((QCString)yytext).mid(s,e-s+1);
BEGIN( MemberCall2 ); BEGIN( MemberCall2 );
} }
<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") { <MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") {
...@@ -1308,8 +1385,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1308,8 +1385,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
} }
<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) { <MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) {
g_code->codify(yytext); g_code->codify(yytext);
g_args=yytext; g_name=yytext;
BEGIN( MemberCall2 );
} }
<MemberCall2>"->"|"." {
g_code->codify(yytext);
g_memCallContext = YY_START;
BEGIN( MemberCall );
}
<SkipComment>"//" { <SkipComment>"//" {
g_code->codify(yytext); g_code->codify(yytext);
} }
......
...@@ -1979,6 +1979,15 @@ void Config::create() ...@@ -1979,6 +1979,15 @@ void Config::create()
"Use the PREDEFINED tag if you want to use a different macro definition. \n" "Use the PREDEFINED tag if you want to use a different macro definition. \n"
); );
cl->addDependency("ENABLE_PREPROCESSING"); cl->addDependency("ENABLE_PREPROCESSING");
cb = addBool(
"SKIP_FUNCTION_MACROS",
"If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \n"
"doxygen's preprocessor will remove all function-like macros that are alone \n"
"on a line and do not end with a semicolon. Such function macros are typically \n"
"used for boiler-plate code, and will confuse the parser if not removed. \n",
TRUE
);
cb->addDependency("ENABLE_PREPROCESSING");
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
addInfo( "External","Configuration::addtions related to external references "); addInfo( "External","Configuration::addtions related to external references ");
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
......
...@@ -838,7 +838,7 @@ static void writeDotFile(const char *fileName, const char *captionText) ...@@ -838,7 +838,7 @@ static void writeDotFile(const char *fileName, const char *captionText)
static int yyread(char *buf,int max_size) static int yyread(char *buf,int max_size)
{ {
int c=0; int c=0;
while( c < max_size && inputString[inputPosition] ) while ( c < max_size && inputString[inputPosition] )
{ {
*buf = inputString[inputPosition++] ; *buf = inputString[inputPosition++] ;
//printf("%d (%c)\n",*buf,*buf); //printf("%d (%c)\n",*buf,*buf);
......
...@@ -428,6 +428,68 @@ void DotNode::write(QTextStream &t, ...@@ -428,6 +428,68 @@ void DotNode::write(QTextStream &t,
} }
} }
void DotNode::writeXML(QTextStream &t)
{
t << " <node id=\"" << m_number << "\">" << endl;
t << " <label>" << m_label << "</label>" << endl;
if (!m_url.isEmpty())
{
QCString url(m_url);
char *refPtr = url.data();
char *urlPtr = strchr(url.data(),'$');
if (urlPtr)
{
*urlPtr++='\0';
t << " <link id=\"" << urlPtr << "\"";
if (*refPtr!='\0')
{
t << " external=\"" << refPtr << "\"";
}
t << "/>" << endl;
}
}
if (m_children)
{
QListIterator<DotNode> nli(*m_children);
QListIterator<EdgeInfo> eli(*m_edgeInfo);
DotNode *childNode;
EdgeInfo *edgeInfo;
for (;(childNode=nli.current());++nli,++eli)
{
edgeInfo=eli.current();
t << " <childnode id=\"" << childNode->m_number << "\" relation=\"";
switch(edgeInfo->m_color)
{
case EdgeInfo::Blue: t << "public-inheritance"; break;
case EdgeInfo::Green: t << "protected-inheritance"; break;
case EdgeInfo::Red: t << "private-inheritance"; break;
case EdgeInfo::Purple: t << "usage"; break;
case EdgeInfo::Orange: t << "template-instance"; break;
case EdgeInfo::Grey: ASSERT(0); break;
}
t << "\">" << endl;
if (!edgeInfo->m_label.isEmpty())
{
int p=0;
int ni;
while ((ni=edgeInfo->m_label.find("\\n",p))!=-1)
{
t << " <edgelabel>"
<< edgeInfo->m_label.mid(p,ni-p)
<< "</edgelabel>" << endl;
p=ni+2;
}
t << " <edgelabel>"
<< edgeInfo->m_label.right(edgeInfo->m_label.length()-p)
<< "</edgelabel>" << endl;
}
t << " </childnode>" << endl;
}
}
t << " </node>" << endl;
}
void DotNode::clearWriteFlag() void DotNode::clearWriteFlag()
{ {
m_written=FALSE; m_written=FALSE;
...@@ -555,18 +617,6 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path) ...@@ -555,18 +617,6 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
{ {
QCString baseName; QCString baseName;
baseName.sprintf("inherit_graph_%d",count++); baseName.sprintf("inherit_graph_%d",count++);
//="inherit_graph_";
//QCString diskName=n->m_url.copy();
//int i=diskName.find('$');
//if (i!=-1)
//{
// diskName=diskName.right(diskName.length()-i-1);
//}
//else /* take the label name as the file name (and strip any template stuff) */
//{
// diskName=n->m_label;
//}
//baseName = convertNameToFile(baseName+diskName);
baseName = convertNameToFile(baseName); baseName = convertNameToFile(baseName);
QCString dotName=baseName+".dot"; QCString dotName=baseName+".dot";
QCString gifName=baseName+".gif"; QCString gifName=baseName+".gif";
...@@ -604,9 +654,10 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path) ...@@ -604,9 +654,10 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
out << "</table>" << endl; out << "</table>" << endl;
return; return;
} }
QCString mapLabel = convertNameToFile(n->m_label);
out << "<tr><td><img src=\"" << gifName << "\" border=\"0\" usemap=\"#" out << "<tr><td><img src=\"" << gifName << "\" border=\"0\" usemap=\"#"
<< n->m_label << "_map\"></td></tr>" << endl; << mapLabel << "_map\"></td></tr>" << endl;
out << "<map name=\"" << n->m_label << "_map\">" << endl; out << "<map name=\"" << mapLabel << "_map\">" << endl;
convertMapFile(out,mapName); convertMapFile(out,mapName);
out << "</map>" << endl; out << "</map>" << endl;
if (Config_getBool("DOT_CLEANUP")) thisDir.remove(dotName); if (Config_getBool("DOT_CLEANUP")) thisDir.remove(dotName);
...@@ -1181,8 +1232,9 @@ QCString DotClassGraph::writeGraph(QTextStream &out, ...@@ -1181,8 +1232,9 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
QDir::setCurrent(oldDir); QDir::setCurrent(oldDir);
return baseName; return baseName;
} }
QCString mapLabel = convertNameToFile(m_startNode->m_label+"_"+mapName);
out << "<p><center><img src=\"" << baseName << ".gif\" border=\"0\" usemap=\"#" out << "<p><center><img src=\"" << baseName << ".gif\" border=\"0\" usemap=\"#"
<< m_startNode->m_label << "_" << mapName << "\" alt=\""; << mapLabel << "\" alt=\"";
switch (m_graphType) switch (m_graphType)
{ {
case Implementation: case Implementation:
...@@ -1196,7 +1248,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out, ...@@ -1196,7 +1248,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
break; break;
} }
out << "\"></center>" << endl; out << "\"></center>" << endl;
out << "<map name=\"" << m_startNode->m_label << "_" << mapName << "\">" << endl; out << "<map name=\"" << mapLabel << "\">" << endl;
convertMapFile(out,baseName+".map"); convertMapFile(out,baseName+".map");
out << "</map>" << endl; out << "</map>" << endl;
thisDir.remove(baseName+".map"); thisDir.remove(baseName+".map");
...@@ -1249,6 +1301,18 @@ QCString DotClassGraph::writeGraph(QTextStream &out, ...@@ -1249,6 +1301,18 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void DotClassGraph::writeXML(QTextStream &t)
{
QDictIterator<DotNode> dni(*m_usedNodes);
DotNode *node;
for (;(node=dni.current());++dni)
{
node->writeXML(t);
}
}
//--------------------------------------------------------------------
int DotInclDepGraph::m_curNodeNumber; int DotInclDepGraph::m_curNodeNumber;
void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance) void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
......
...@@ -76,6 +76,7 @@ class DotNode ...@@ -76,6 +76,7 @@ class DotNode
int maxDistance=1000,bool backArrows=TRUE); int maxDistance=1000,bool backArrows=TRUE);
int m_subgraphId; int m_subgraphId;
void clearWriteFlag(); void clearWriteFlag();
void writeXML(QTextStream &t);
private: private:
void colorConnectedNodes(int curColor); void colorConnectedNodes(int curColor);
...@@ -86,7 +87,7 @@ class DotNode ...@@ -86,7 +87,7 @@ class DotNode
const DotNode *findDocNode() const; // only works for acyclic graphs! const DotNode *findDocNode() const; // only works for acyclic graphs!
int m_number; int m_number;
QCString m_label; //!< label text QCString m_label; //!< label text
QCString m_url; //!< url of the node (format: remove$local) QCString m_url; //!< url of the node (format: remote$local)
QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows) QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows)
QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows) QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows)
QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child
...@@ -123,6 +124,8 @@ class DotClassGraph ...@@ -123,6 +124,8 @@ class DotClassGraph
bool isTrivial() const; bool isTrivial() const;
QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path, QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path,
bool TBRank=TRUE,bool imageMap=TRUE); bool TBRank=TRUE,bool imageMap=TRUE);
void writeXML(QTextStream &t);
QCString diskName() const; QCString diskName() const;
private: private:
......
...@@ -1689,13 +1689,26 @@ void buildVarList(Entry *root) ...@@ -1689,13 +1689,26 @@ void buildVarList(Entry *root)
QCString type=root->type.stripWhiteSpace(); QCString type=root->type.stripWhiteSpace();
ClassDef *cd=0; ClassDef *cd=0;
if (root->name.findRev("::")!=-1) goto nextMember; if (root->name.findRev("::")!=-1)
{
if (root->type=="friend class" || root->type=="friend struct" ||
root->type=="friend union")
{
cd=getClass(scope);
if (cd)
{
addVariableToClass(root,cd,MemberDef::Friend,scope,
root->name,FALSE,0,0,Public);
}
}
goto nextMember;
/* skip this member, because it is a /* skip this member, because it is a
* static variable definition (always?), which will be * static variable definition (always?), which will be
* found in a class scope as well, but then we know the * found in a class scope as well, but then we know the
* correct protection level, so only then it will be * correct protection level, so only then it will be
* inserted in the correct list! * inserted in the correct list!
*/ */
}
if (type=="@") if (type=="@")
mtype=MemberDef::EnumValue; mtype=MemberDef::EnumValue;
...@@ -1708,6 +1721,7 @@ void buildVarList(Entry *root) ...@@ -1708,6 +1721,7 @@ void buildVarList(Entry *root)
else else
mtype=MemberDef::Variable; mtype=MemberDef::Variable;
QCString classScope=stripAnonymousNamespaceScope(scope); QCString classScope=stripAnonymousNamespaceScope(scope);
classScope=stripTemplateSpecifiersFromScope(classScope,FALSE); classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
QCString annScopePrefix=scope.left(scope.length()-classScope.length()); QCString annScopePrefix=scope.left(scope.length()-classScope.length());
...@@ -1780,7 +1794,7 @@ nextMember: ...@@ -1780,7 +1794,7 @@ nextMember:
// Searches the Entry tree for Function sections. // Searches the Entry tree for Function sections.
// If found they are stored in their class or in the global list. // If found they are stored in their class or in the global list.
static void buildMemberList(Entry *root) static void buildFunctionList(Entry *root)
{ {
if (root->section==Entry::FUNCTION_SEC) if (root->section==Entry::FUNCTION_SEC)
{ {
...@@ -2205,7 +2219,7 @@ static void buildMemberList(Entry *root) ...@@ -2205,7 +2219,7 @@ static void buildMemberList(Entry *root)
Entry *e; Entry *e;
for (;(e=eli.current());++eli) for (;(e=eli.current());++eli)
{ {
buildMemberList(e); buildFunctionList(e);
} }
} }
...@@ -2467,7 +2481,6 @@ static void findUsedClassesForClass(Entry *root, ...@@ -2467,7 +2481,6 @@ static void findUsedClassesForClass(Entry *root,
QDict<int> *templateNames=0 QDict<int> *templateNames=0
) )
{ {
//if (masterCd->visited) return;
masterCd->visited=TRUE; masterCd->visited=TRUE;
ArgumentList *formalArgs = masterCd->templateArguments(); ArgumentList *formalArgs = masterCd->templateArguments();
MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict()); MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict());
...@@ -2490,7 +2503,7 @@ static void findUsedClassesForClass(Entry *root, ...@@ -2490,7 +2503,7 @@ static void findUsedClassesForClass(Entry *root,
{ {
type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs); type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
} }
//printf("extractClassNameFromType(%s)\n",type.data()); //printf("findUsedClassesForClass(%s)=%s\n",masterCd->name().data(),type.data());
while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec)) while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec))
{ {
QCString typeName = resolveTypeDef(masterCd,usedClassName); QCString typeName = resolveTypeDef(masterCd,usedClassName);
...@@ -2577,6 +2590,20 @@ static void findUsedClassesForClass(Entry *root, ...@@ -2577,6 +2590,20 @@ static void findUsedClassesForClass(Entry *root,
templateNames=0; templateNames=0;
} }
} }
if (!found && !type.isEmpty()) // used class is not documented in any scope
{
ClassDef *usedCd = Doxygen::hiddenClasses.find(type);
if (usedCd==0)
{
Debug::print(Debug::Classes,0," New undocumented used class `%s'\n", type.data());
usedCd = new ClassDef(
masterCd->getDefFileName(),masterCd->getDefLine(),
type,ClassDef::Class);
Doxygen::hiddenClasses.inSort(type,usedCd);
}
if (isArtificial) usedCd->setClassIsArtificial();
instanceCd->addUsedClass(usedCd,md->name());
}
} }
} }
} }
...@@ -2897,9 +2924,9 @@ static bool findClassRelation( ...@@ -2897,9 +2924,9 @@ static bool findClassRelation(
} }
} }
bool isATemplateArgument = templateNames!=0 && templateNames->find(bi->name)!=0; bool isATemplateArgument = templateNames!=0 && templateNames->find(bi->name)!=0;
if (!isATemplateArgument && found) if (/*!isATemplateArgument &&*/ found)
{ {
Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",bi->name.data(),templSpec.data()); Debug::print(Debug::Classes,0," Documented class `%s' templSpec=%s\n",bi->name.data(),templSpec.data());
// add base class to this class // add base class to this class
// if templSpec is not empty then we should "instantiate" // if templSpec is not empty then we should "instantiate"
...@@ -2956,19 +2983,6 @@ static bool findClassRelation( ...@@ -2956,19 +2983,6 @@ static bool findClassRelation(
baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
// the undocumented base was found in this file // the undocumented base was found in this file
baseClass->insertUsedFile(root->fileName); baseClass->insertUsedFile(root->fileName);
// is this an inherited template argument?
//printf("%s->setIsTemplateBaseClass(%d)\n",baseClass->name().data(),isTemplBaseClass);
//if (isATemplateArgument)
//{
// baseClass->setIsTemplateBaseClass(*templateNames->find(bi->name));
//}
// add class to the list
//if (!isATemplateArgument)
//{
//}
//else
//{
//}
return TRUE; return TRUE;
} }
else else
...@@ -3370,8 +3384,6 @@ static void addTodoTestBugReferences() ...@@ -3370,8 +3384,6 @@ static void addTodoTestBugReferences()
addFileMemberTodoTestBugReferences(0); addFileMemberTodoTestBugReferences(0);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Copy the documentation in entry `root' to member definition `md' and // Copy the documentation in entry `root' to member definition `md' and
// set the function declaration of the member to `funcDecl'. If the boolean // set the function declaration of the member to `funcDecl'. If the boolean
...@@ -3828,18 +3840,6 @@ static void findMember(Entry *root, ...@@ -3828,18 +3840,6 @@ static void findMember(Entry *root,
} }
} while (!done); } while (!done);
if (isFriend)
{
if (funcDecl.left(6)=="class ")
{
funcDecl=funcDecl.right(funcDecl.length()-6);
}
else if (funcDecl.left(7)=="struct ")
{
funcDecl=funcDecl.right(funcDecl.length()-7);
}
}
// delete any ; from the function declaration // delete any ; from the function declaration
int sep; int sep;
while ((sep=funcDecl.find(';'))!=-1) while ((sep=funcDecl.find(';'))!=-1)
...@@ -3857,12 +3857,27 @@ static void findMember(Entry *root, ...@@ -3857,12 +3857,27 @@ static void findMember(Entry *root,
":: ","::" ":: ","::"
), ),
" ::","::" " ::","::"
); ).stripWhiteSpace();
// extract information from the declarations //printf("funcDecl=`%s'\n",funcDecl.data());
parseFuncDecl(funcDecl,scopeName,funcType,funcName, if (isFriend && funcDecl.left(6)=="class ")
{
//printf("friend class\n");
funcDecl=funcDecl.right(funcDecl.length()-6);
funcName = funcDecl.copy();
}
else if (isFriend && funcDecl.left(7)=="struct ")
{
funcDecl=funcDecl.right(funcDecl.length()-7);
funcName = funcDecl.copy();
}
else
{
// extract information from the declarations
parseFuncDecl(funcDecl,scopeName,funcType,funcName,
funcArgs,funcTempList,exceptions funcArgs,funcTempList,exceptions
); );
}
//printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n", //printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n",
// scopeName.data(),funcType.data(),funcName.data()); // scopeName.data(),funcType.data(),funcName.data());
...@@ -4473,8 +4488,17 @@ static void findMemberDocumentation(Entry *root) ...@@ -4473,8 +4488,17 @@ static void findMemberDocumentation(Entry *root)
// root->name.data(),root->args.data(),root->exception.data()); // root->name.data(),root->args.data(),root->exception.data());
//if (root->relates.length()) printf(" Relates %s\n",root->relates.data()); //if (root->relates.length()) printf(" Relates %s\n",root->relates.data());
//printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data()); //printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data());
if (root->type=="friend class" || root->type=="friend struct" ||
if (!root->type.isEmpty()) root->type=="friend union")
{
findMember(root,
root->type+" "+
root->name,
root->relates,
FALSE,FALSE);
}
else if (!root->type.isEmpty())
{ {
findMember(root, findMember(root,
root->type+" "+ root->type+" "+
...@@ -6098,15 +6122,20 @@ static void copyAndFilterFile(const char *fileName,BufStr &dest) ...@@ -6098,15 +6122,20 @@ static void copyAndFilterFile(const char *fileName,BufStr &dest)
pclose(f); pclose(f);
} }
// filter unwanted bytes from the resulting data // filter unwanted bytes from the resulting data
uchar *p=(uchar *)dest.data()+oldPos;
uchar conv[256]; uchar conv[256];
int i; int i;
for (i=0;i<256;i++) conv[i]=i; for (i=0;i<256;i++) conv[i]=i;
conv[0x06]=0x20; // replace the offending characters with spaces conv[0x06]=0x20; // replace the offending characters with spaces
conv[0x00]=0x20; conv[0x00]=0x20;
// remove any special markers from the input // remove any special markers from the input
uchar *p=(uchar *)dest.data()+oldPos;
for (i=0;i<size;i++,p++) *p=conv[*p]; for (i=0;i<size;i++,p++) *p=conv[*p];
// adjust pointer // and translate CR's
int newSize=filterCRLF(dest.data()+oldPos,size);
if (newSize!=size) // we removed chars
{
dest.resize(newSize); // resize the array
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -7054,7 +7083,7 @@ void parseInput() ...@@ -7054,7 +7083,7 @@ void parseInput()
buildVarList(root); buildVarList(root);
msg("Building member list...\n"); // using class info only ! msg("Building member list...\n"); // using class info only !
buildMemberList(root); buildFunctionList(root);
transferFunctionDocumentation(); transferFunctionDocumentation();
msg("Searching for friends...\n"); msg("Searching for friends...\n");
......
...@@ -220,6 +220,7 @@ QCString unhtmlify(const char *str) ...@@ -220,6 +220,7 @@ QCString unhtmlify(const char *str)
<Start>^"<li>" { <Start>^"<li>" {
BEGIN( SearchClassFile ); BEGIN( SearchClassFile );
} }
<Start>^"<td"[^\n]*"<h1 align=center>" | // Qt-3.x.x+
<Start>^"<h1 align=center>" { // Qt variant <Start>^"<h1 align=center>" { // Qt variant
BEGIN( ReadClassName ); BEGIN( ReadClassName );
} }
......
...@@ -216,7 +216,7 @@ class Entry ...@@ -216,7 +216,7 @@ class Entry
MEMBERGRP_SEC = 0x01300000, MEMBERGRP_SEC = 0x01300000,
USINGDECL_SEC = 0x01400000, USINGDECL_SEC = 0x01400000,
PACKAGE_SEC = 0x01500000, PACKAGE_SEC = 0x01500000,
PACKAGEDOC_SEC = 0x01600000, PACKAGEDOC_SEC = 0x01600000
}; };
enum MemberSpecifier enum MemberSpecifier
{ {
......
...@@ -831,7 +831,7 @@ void HtmlGenerator::endAlphabeticalIndexList() ...@@ -831,7 +831,7 @@ void HtmlGenerator::endAlphabeticalIndexList()
void HtmlGenerator::writeIndexHeading(const char *s) void HtmlGenerator::writeIndexHeading(const char *s)
{ {
t << "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td><div class=\"ah\">&nbsp;&nbsp;" << s t << "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td><div class=\"ah\">&nbsp;&nbsp;" << s
<< "&nbsp;&nbsp;</td</tr></table>"; << "&nbsp;&nbsp;</td></tr></table>";
} }
void HtmlGenerator::startImage(const char *name,const char *,bool hasCaption) void HtmlGenerator::startImage(const char *name,const char *,bool hasCaption)
...@@ -940,7 +940,7 @@ void HtmlGenerator::startParameterType(bool first) ...@@ -940,7 +940,7 @@ void HtmlGenerator::startParameterType(bool first)
if (first) if (first)
{ {
DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;) DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
t << " <td class=\"md\">"; t << " <td class=\"md\" nowrap>";
} }
else else
{ {
...@@ -948,14 +948,14 @@ void HtmlGenerator::startParameterType(bool first) ...@@ -948,14 +948,14 @@ void HtmlGenerator::startParameterType(bool first)
t << " <tr>" << endl; t << " <tr>" << endl;
t << " <td></td>" << endl; t << " <td></td>" << endl;
t << " <td></td>" << endl; t << " <td></td>" << endl;
t << " <td class=\"md\">"; t << " <td class=\"md\" nowrap>";
} }
} }
void HtmlGenerator::endParameterType() void HtmlGenerator::endParameterType()
{ {
DBG_HTML(t << "<!-- endParameterType -->" << endl;) DBG_HTML(t << "<!-- endParameterType -->" << endl;)
t << "</td>" << endl; t << "&nbsp;</td>" << endl;
} }
void HtmlGenerator::startParameterName(bool oneArgOnly) void HtmlGenerator::startParameterName(bool oneArgOnly)
......
...@@ -120,6 +120,8 @@ class HtmlGenerator : public OutputGenerator ...@@ -120,6 +120,8 @@ class HtmlGenerator : public OutputGenerator
void endCodeFragment() { t << "</pre></div>"; } void endCodeFragment() { t << "</pre></div>"; }
void startPreFragment() { t << "<pre>"; } void startPreFragment() { t << "<pre>"; }
void endPreFragment() { t << "</pre>"; } void endPreFragment() { t << "</pre>"; }
void startLineNumber() {}
void endLineNumber() { t << " "; }
void startCodeLine() { col=0; } void startCodeLine() { col=0; }
void endCodeLine() { codify("\n"); } void endCodeLine() { codify("\n"); }
//void writeBoldString(const char *text) //void writeBoldString(const char *text)
......
...@@ -1529,9 +1529,14 @@ void LatexGenerator::endMemberList() ...@@ -1529,9 +1529,14 @@ void LatexGenerator::endMemberList()
void LatexGenerator::startImage(const char *name,const char *size,bool hasCaption) void LatexGenerator::startImage(const char *name,const char *size,bool hasCaption)
{ {
if (hasCaption) if (hasCaption)
t << "\\begin{figure}[H]" << endl; {
t << "\\begin{figure}[h]" << endl;
t << "\\begin{center}" << endl;
}
else else
{
t << "\\mbox{"; t << "\\mbox{";
}
QCString gfxName = name; QCString gfxName = name;
if (gfxName.right(4)==".eps") gfxName.left(gfxName.length()-4); if (gfxName.right(4)==".eps") gfxName.left(gfxName.length()-4);
// "\\epsfig{file=" << name; // "\\epsfig{file=" << name;
...@@ -1539,9 +1544,13 @@ void LatexGenerator::startImage(const char *name,const char *size,bool hasCaptio ...@@ -1539,9 +1544,13 @@ void LatexGenerator::startImage(const char *name,const char *size,bool hasCaptio
if (size) t << "[" << size << "]"; if (size) t << "[" << size << "]";
t << "{" << gfxName << "}"; t << "{" << gfxName << "}";
if (hasCaption) if (hasCaption)
{
t << "\\caption{"; t << "\\caption{";
}
else else
{
t << "}" << endl; t << "}" << endl;
}
} }
void LatexGenerator::endImage(bool hasCaption) void LatexGenerator::endImage(bool hasCaption)
...@@ -1549,6 +1558,7 @@ void LatexGenerator::endImage(bool hasCaption) ...@@ -1549,6 +1558,7 @@ void LatexGenerator::endImage(bool hasCaption)
if (hasCaption) if (hasCaption)
{ {
t << "}" << endl; t << "}" << endl;
t << "\\end{center}" << endl;
t << "\\end{figure}" << endl; t << "\\end{figure}" << endl;
} }
} }
......
...@@ -118,6 +118,8 @@ class LatexGenerator : public OutputGenerator ...@@ -118,6 +118,8 @@ class LatexGenerator : public OutputGenerator
void endPreFragment() { t << "\\end{alltt}\\normalsize " << endl; void endPreFragment() { t << "\\end{alltt}\\normalsize " << endl;
insidePre=FALSE; insidePre=FALSE;
} }
void startLineNumber() {}
void endLineNumber() { t << " "; }
void startCodeLine() { col=0; } void startCodeLine() { col=0; }
void endCodeLine() { codify("\n"); } void endCodeLine() { codify("\n"); }
//void writeBoldString(const char *text) //void writeBoldString(const char *text)
......
...@@ -110,6 +110,8 @@ class ManGenerator : public OutputGenerator ...@@ -110,6 +110,8 @@ class ManGenerator : public OutputGenerator
void endCodeFragment(); void endCodeFragment();
void startPreFragment() { startCodeFragment(); } void startPreFragment() { startCodeFragment(); }
void endPreFragment() { endCodeFragment(); } void endPreFragment() { endCodeFragment(); }
void startLineNumber() {}
void endLineNumber() { t << " "; }
void startCodeLine() {} void startCodeLine() {}
void endCodeLine() { codify("\n"); col=0; } void endCodeLine() { codify("\n"); col=0; }
//void writeBoldString(const char *text) //void writeBoldString(const char *text)
......
...@@ -558,7 +558,8 @@ bool MemberDef::isBriefSectionVisible() const ...@@ -558,7 +558,8 @@ bool MemberDef::isBriefSectionVisible() const
// only include members is the are documented or // only include members is the are documented or
// HIDE_UNDOC_MEMBERS is NO in the config file // HIDE_UNDOC_MEMBERS is NO in the config file
bool visibleIfDocumented = (!Config_getBool("HIDE_UNDOC_MEMBERS") || bool visibleIfDocumented = (!Config_getBool("HIDE_UNDOC_MEMBERS") ||
hasDocumentation() hasDocumentation() ||
isDocumentedFriendClass()
); );
// hide members with no detailed description and brief descriptions // hide members with no detailed description and brief descriptions
...@@ -767,7 +768,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ...@@ -767,7 +768,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
if (!name().isEmpty() && name().at(0)!='@') if (!name().isEmpty() && name().at(0)!='@')
{ {
//printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,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 (isLinkable())
{ {
if (annMemb) if (annMemb)
{ {
...@@ -786,7 +787,14 @@ void MemberDef::writeDeclaration(OutputList &ol, ...@@ -786,7 +787,14 @@ void MemberDef::writeDeclaration(OutputList &ol,
writeLink(ol,cd,nd,fd,gd); writeLink(ol,cd,nd,fd,gd);
} }
} }
else // there is a brief member description and brief member else if (isDocumentedFriendClass())
// if the member is an undocumented friend declaration for some class,
// then maybe we can link to the class
{
writeLink(ol,getClass(name()),0,0,0);
}
else
// there is a brief member description and brief member
// descriptions are enabled or there is no detailed description. // descriptions are enabled or there is no detailed description.
{ {
if (annMemb) annMemb->annUsed=annUsed=TRUE; if (annMemb) annMemb->annUsed=annUsed=TRUE;
...@@ -1479,7 +1487,8 @@ void MemberDef::warnIfUndocumented() ...@@ -1479,7 +1487,8 @@ void MemberDef::warnIfUndocumented()
else else
t="file", d=fd; t="file", d=fd;
if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1) if (d && d->isLinkable() && !isLinkable() && !isDocumentedFriendClass()
&& name().find('@')==-1)
warn_undoc(m_defFileName,m_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()); name().data(),t,d->name().data());
} }
...@@ -1520,11 +1529,20 @@ void MemberDef::setEnumDecl(OutputList &ed) ...@@ -1520,11 +1529,20 @@ void MemberDef::setEnumDecl(OutputList &ed)
*enumDeclList+=ed; *enumDeclList+=ed;
} }
bool MemberDef::isDocumentedFriendClass() const
{
ClassDef *fcd=0;
return (isFriend() &&
(type=="friend class" || type=="friend struct" ||
type=="friend union") &&
(fcd=getClass(name())) && fcd->isLinkable());
}
bool MemberDef::hasDocumentation() const bool MemberDef::hasDocumentation() const
{ {
return Definition::hasDocumentation() || return Definition::hasDocumentation() ||
(mtype==Enumeration && docEnumValues) || // has enum values (mtype==Enumeration && docEnumValues) || // has enum values
(argList!=0 && argList->hasDocumentation()); (argList!=0 && argList->hasDocumentation()); // has doc arguments
} }
void MemberDef::setMemberGroup(MemberGroup *grp) void MemberDef::setMemberGroup(MemberGroup *grp)
......
...@@ -129,6 +129,7 @@ class MemberDef : public Definition ...@@ -129,6 +129,7 @@ class MemberDef : public Definition
bool isBriefSectionVisible() const; bool isBriefSectionVisible() const;
bool isDetailedSectionVisible(bool inGroup=FALSE) const; bool isDetailedSectionVisible(bool inGroup=FALSE) const;
bool isDetailedSectionLinkable() const; bool isDetailedSectionLinkable() const;
bool isDocumentedFriendClass() const;
// set functions // set functions
void setMemberType(MemberType t) { mtype=t; } void setMemberType(MemberType t) { mtype=t; }
......
...@@ -250,20 +250,20 @@ void MemberList::writePlainDeclarations(OutputList &ol, ...@@ -250,20 +250,20 @@ void MemberList::writePlainDeclarations(OutputList &ol,
bool fmdVisible = fmd->isBriefSectionVisible(); bool fmdVisible = fmd->isBriefSectionVisible();
while (fmd) while (fmd)
{ {
/* in html we start a new line after a number of items */
if (numVisibleEnumValues>enumValuesPerLine
&& (enumMemCount%enumValuesPerLine)==0
)
{
typeDecl.pushGeneratorState();
typeDecl.disableAllBut(OutputGenerator::Html);
typeDecl.lineBreak();
typeDecl.writeString("&nbsp;&nbsp;");
typeDecl.popGeneratorState();
}
if (fmdVisible) if (fmdVisible)
{ {
/* in html we start a new line after a number of items */
if (numVisibleEnumValues>enumValuesPerLine
&& (enumMemCount%enumValuesPerLine)==0
)
{
typeDecl.pushGeneratorState();
typeDecl.disableAllBut(OutputGenerator::Html);
typeDecl.lineBreak();
typeDecl.writeString("&nbsp;&nbsp;");
typeDecl.popGeneratorState();
}
if (fmd->hasDocumentation()) // enum value has docs if (fmd->hasDocumentation()) // enum value has docs
{ {
if (!Config_getString("GENERATE_TAGFILE").isEmpty()) if (!Config_getString("GENERATE_TAGFILE").isEmpty())
......
...@@ -248,6 +248,8 @@ class BaseOutputDocInterface ...@@ -248,6 +248,8 @@ class BaseOutputDocInterface
virtual void endPageRef(const char *,const char *) = 0; virtual void endPageRef(const char *,const char *) = 0;
virtual void startLineNumber() = 0;
virtual void endLineNumber() = 0;
virtual void startCodeLine() = 0; virtual void startCodeLine() = 0;
virtual void endCodeLine() = 0; virtual void endCodeLine() = 0;
virtual void startCodeAnchor(const char *label) = 0; virtual void startCodeAnchor(const char *label) = 0;
......
...@@ -206,8 +206,10 @@ class OutputList : public OutputDocInterface ...@@ -206,8 +206,10 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startCodeLine); } { forall(&OutputGenerator::startCodeLine); }
void endCodeLine() void endCodeLine()
{ forall(&OutputGenerator::endCodeLine); } { forall(&OutputGenerator::endCodeLine); }
//void writeBoldString(const char *text) void startLineNumber()
//{ forall(&OutputGenerator::writeBoldString,text); } { forall(&OutputGenerator::startLineNumber); }
void endLineNumber()
{ forall(&OutputGenerator::endLineNumber); }
void startEmphasis() void startEmphasis()
{ forall(&OutputGenerator::startEmphasis); } { forall(&OutputGenerator::startEmphasis); }
void endEmphasis() void endEmphasis()
......
...@@ -977,6 +977,22 @@ static void readIncludeFile(const QCString &inc) ...@@ -977,6 +977,22 @@ static void readIncludeFile(const QCString &inc)
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
static int yyread(char *buf,int max_size)
{
int len = fread( buf, 1, max_size, yyin );
if (len==0 && ferror( yyin ))
{
yy_fatal_error( "input in flex scanner failed" );
return len;
}
return filterCRLF(buf,len);
}
/* ----------------------------------------------------------------- */
%} %}
ID [a-z_A-Z][a-z_A-Z0-9]* ID [a-z_A-Z][a-z_A-Z0-9]*
...@@ -1018,30 +1034,39 @@ BN [ \t\r\n] ...@@ -1018,30 +1034,39 @@ BN [ \t\r\n]
<*>\x06 <*>\x06
<*>\x00 <*>\x00
<*>\r <*>\r
/*
<Start>^{B}*([^ \t#\n\/][^\n]*)?"\n" {
//printf("%s line %d: %s",g_yyFileName.data(),g_yyLineNr,yytext);
if (g_includeStack.isEmpty())
{
//preprocessedFile+=yytext;
//char *s=yytext,c;
//if (s) while ((c=*s++)) *dataPtr++=c;
g_outputBuf->addArray(yytext,yyleng);
}
g_yyLineNr++;
}
*/
<Start>^{B}*"#" { BEGIN(Command); } <Start>^{B}*"#" { BEGIN(Command); }
<Start>^{B}*/[^#] { <Start>^{B}*/[^#] {
outputArray(yytext,yyleng); outputArray(yytext,yyleng);
BEGIN(CopyLine); BEGIN(CopyLine);
} }
/* <Start>^{B}*[_A-Z][_A-Z0-9]*"("[^\)\n]*")"{B}*\n { // function like macro
<CopyLine>[^\n/]+ { static bool skipFuncMacros = Config_getBool("SKIP_FUNCTION_MACROS");
outputArray(yytext,yyleng); QCString name(yytext);
name=name.left(name.find('(')).stripWhiteSpace();
Define *def=0;
if (skipFuncMacros &&
!(
(g_includeStack.isEmpty() || g_curlyCount>0) &&
g_macroExpansion &&
(def=g_fileDefineDict->find(name)) &&
(!g_expandOnlyPredef || def->isPredefined)
)
)
{
outputChar('\n');
g_yyLineNr++;
}
else // don't skip
{
int i;
for (i=yyleng-1;i>=0;i--)
{
unput(yytext[i]);
}
BEGIN(CopyLine);
}
} }
*/
<CopyLine>"{" { // count brackets inside the main file <CopyLine>"{" { // count brackets inside the main file
if (g_includeStack.isEmpty()) if (g_includeStack.isEmpty())
g_curlyCount++; g_curlyCount++;
...@@ -1843,9 +1868,7 @@ void cleanupPreprocessor() ...@@ -1843,9 +1868,7 @@ void cleanupPreprocessor()
void preprocessFile(const char *fileName,BufStr &output) void preprocessFile(const char *fileName,BufStr &output)
{ {
//#if DUMP_OUTPUT
uint orgOffset=output.curPos(); uint orgOffset=output.curPos();
//#endif
g_macroExpansion = Config_getBool("MACRO_EXPANSION"); g_macroExpansion = Config_getBool("MACRO_EXPANSION");
g_expandOnlyPredef = Config_getBool("EXPAND_ONLY_PREDEF"); g_expandOnlyPredef = Config_getBool("EXPAND_ONLY_PREDEF");
......
...@@ -110,6 +110,8 @@ class RTFGenerator : public OutputGenerator ...@@ -110,6 +110,8 @@ class RTFGenerator : public OutputGenerator
void endCodeFragment(); void endCodeFragment();
void startPreFragment() { startCodeFragment(); } void startPreFragment() { startCodeFragment(); }
void endPreFragment() { endCodeFragment(); } void endPreFragment() { endCodeFragment(); }
void startLineNumber() {}
void endLineNumber() { t << " "; }
void startCodeLine() { col=0; } void startCodeLine() { col=0; }
void endCodeLine() { lineBreak(); } void endCodeLine() { lineBreak(); }
//void writeBoldString(const char *text) //void writeBoldString(const char *text)
......
...@@ -598,7 +598,6 @@ TITLE [tT][iI][tT][lL][eE] ...@@ -598,7 +598,6 @@ TITLE [tT][iI][tT][lL][eE]
} }
BEGIN( FindMembers ); BEGIN( FindMembers );
} }
<*>\x0d
<NextSemi>"{" { <NextSemi>"{" {
curlyCount=0; curlyCount=0;
needsSemi = TRUE; needsSemi = TRUE;
...@@ -733,7 +732,7 @@ TITLE [tT][iI][tT][lL][eE] ...@@ -733,7 +732,7 @@ TITLE [tT][iI][tT][lL][eE]
current->argList->clear(); current->argList->clear();
lineCount() ; lineCount() ;
} }
<FindMembers>{BN}+ { <FindMembers>{BN}{1,80} {
lineCount(); lineCount();
} }
<FindMembers>{B}*"package"{BN}+ { // Java package <FindMembers>{B}*"package"{BN}+ { // Java package
...@@ -1751,9 +1750,9 @@ TITLE [tT][iI][tT][lL][eE] ...@@ -1751,9 +1750,9 @@ TITLE [tT][iI][tT][lL][eE]
//if (!current->name.isEmpty() && current->name[0]!='@' && //if (!current->name.isEmpty() && current->name[0]!='@' &&
// current->parent->section & Entry::COMPOUND_MASK) // current->parent->section & Entry::COMPOUND_MASK)
// varEntry->type+=current->parent->name+"::"; // varEntry->type+=current->parent->name+"::";
//if (isTypedef) if (isTypedef)
//{ {
// varEntry->type.prepend("typedef "); varEntry->type.prepend("typedef ");
// //printf("current->name = %s %s\n",current->name.data(),msName.data()); // //printf("current->name = %s %s\n",current->name.data(),msName.data());
// if (!current->name.isEmpty() && current->name.at(0)!='@') // if (!current->name.isEmpty() && current->name.at(0)!='@')
// { // {
...@@ -1762,7 +1761,7 @@ TITLE [tT][iI][tT][lL][eE] ...@@ -1762,7 +1761,7 @@ TITLE [tT][iI][tT][lL][eE]
// if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name; // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name;
// Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope)); // Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope));
// } // }
//} }
varEntry->type+=current->name+msType; varEntry->type+=current->name+msType;
varEntry->fileName = yyFileName; varEntry->fileName = yyFileName;
varEntry->startLine = yyLineNr; varEntry->startLine = yyLineNr;
......
...@@ -534,7 +534,7 @@ class TranslatorEnglish : public Translator ...@@ -534,7 +534,7 @@ class TranslatorEnglish : public Translator
*/ */
virtual QCString trGeneratedAt(const char *date,const char *projName) virtual QCString trGeneratedAt(const char *date,const char *projName)
{ {
QCString result=(QCString)"Generated at "+date; QCString result=(QCString)"Generated on "+date;
if (projName) result+=(QCString)" for "+projName; if (projName) result+=(QCString)" for "+projName;
result+=(QCString)" by"; result+=(QCString)" by";
return result; return result;
......
...@@ -365,6 +365,7 @@ QCString resolveTypeDef(Definition *d,const QCString &name) ...@@ -365,6 +365,7 @@ QCString resolveTypeDef(Definition *d,const QCString &name)
//printf("resolveTypeDef(%s,%s)\n",d ? d->name().data() : "<none>",name.data()); //printf("resolveTypeDef(%s,%s)\n",d ? d->name().data() : "<none>",name.data());
QCString result; QCString result;
if (name.isEmpty()) return result; if (name.isEmpty()) return result;
Definition *mContext=d; Definition *mContext=d;
MemberDef *md=0; MemberDef *md=0;
while (mContext && md==0) while (mContext && md==0)
...@@ -409,26 +410,6 @@ QCString resolveTypeDef(Definition *d,const QCString &name) ...@@ -409,26 +410,6 @@ QCString resolveTypeDef(Definition *d,const QCString &name)
} }
return result; return result;
#if 0
QCString typeName;
if (!name.isEmpty())
{
TypedefInfo *ti = Doxygen::typedefDict[name];
if (ti)
{
int count=0;
typeName=ti->value;
TypedefInfo *newTi;
while ((newTi=Doxygen::typedefDict[typeName]) && count<10)
{
if (typeName==newTi->value) break; // prevent lock-up
typeName=newTi->value;
count++;
}
}
}
return typeName;
#endif
} }
/*! Get a class definition given its name. /*! Get a class definition given its name.
...@@ -472,16 +453,11 @@ ClassDef *getResolvedClass( ...@@ -472,16 +453,11 @@ ClassDef *getResolvedClass(
QCString *pTemplSpec QCString *pTemplSpec
) )
{ {
//printf("getResolvedClass(%s,%s)\n",scope ? scope->name().data() : "<none>", //printf("getResolvedClass(%s,%s)\n",scope ? scope->name().data() : "<none>", n);
// n);
QCString name = n; QCString name = n;
if (name.isEmpty()) return 0; if (name.isEmpty()) return 0;
if (scope==0) scope=Doxygen::globalScope; if (scope==0) scope=Doxygen::globalScope;
int i = name.findRev("::"); int i = name.findRev("::");
//QCString subst = 0;
//if (i!=-1) subst = Doxygen::typedefDict[name.right(name.length()-i-2)];
//if (subst==0) subst = Doxygen::typedefDict[name],i=-1;
//if (subst) // there is a typedef with this name
QCString subst; QCString subst;
if (i!=-1) if (i!=-1)
{ {
...@@ -491,11 +467,17 @@ ClassDef *getResolvedClass( ...@@ -491,11 +467,17 @@ ClassDef *getResolvedClass(
{ {
subst = resolveTypeDef(scope,name); subst = resolveTypeDef(scope,name);
} }
//printf(" typedef subst=`%s'\n",subst.data());
if (!subst.isEmpty()) if (!subst.isEmpty())
{ {
// strip * and & from n
int ip=subst.length()-1;
while (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ') ip--;
subst=subst.left(ip+1);
if (pIsTypeDef) *pIsTypeDef=TRUE; if (pIsTypeDef) *pIsTypeDef=TRUE;
//printf("getResolvedClass `%s'->`%s'\n",name.data(),subst->data()); //printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data());
if (subst==name) // avoid resolving typedef struct foo foo; if (subst==name) // avoid resolving typedef struct foo foo;
{ {
return Doxygen::classSDict.find(name); return Doxygen::classSDict.find(name);
...@@ -503,15 +485,24 @@ ClassDef *getResolvedClass( ...@@ -503,15 +485,24 @@ ClassDef *getResolvedClass(
int count=0; // recursion detection guard int count=0; // recursion detection guard
QCString newSubst; QCString newSubst;
QCString typeName = subst; QCString typeName = subst;
if (i!=-1) typeName.prepend(name.left(i)+"::"); if (i!=-1) typeName.prepend(name.left(i)+"::");
while (!(newSubst=resolveTypeDef(scope,typeName)).isEmpty() while (!(newSubst=resolveTypeDef(scope,typeName)).isEmpty()
&& count<10) && count<10)
{ {
if (typeName==newSubst) if (typeName==newSubst)
{ {
return Doxygen::classSDict.find(subst); // for breaking typedef struct A A; ClassDef *cd = Doxygen::classSDict.find(subst); // for breaking typedef struct A A;
//printf(" getClass: exit `%s' %p\n",subst.data(),cd);
return cd;
} }
subst=newSubst; subst=newSubst;
// strip * and & from n
int ip=subst.length()-1;
while (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ') ip--;
subst=subst.left(ip+1);
//printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data());
typeName=newSubst; typeName=newSubst;
if (i!=-1) typeName.prepend(name.left(i)+"::"); if (i!=-1) typeName.prepend(name.left(i)+"::");
count++; count++;
...@@ -523,9 +514,9 @@ ClassDef *getResolvedClass( ...@@ -523,9 +514,9 @@ ClassDef *getResolvedClass(
} }
else else
{ {
//printf("getClass: subst %s->%s\n",name.data(),typeName.data());
int i; int i;
ClassDef *cd = Doxygen::classSDict.find(typeName); ClassDef *cd = Doxygen::classSDict.find(typeName);
//printf(" getClass: subst %s->%s cd=%p\n",name.data(),typeName.data(),cd);
if (cd==0 && (i=typeName.find('<'))>0) // try unspecialized version as well if (cd==0 && (i=typeName.find('<'))>0) // try unspecialized version as well
{ {
if (pTemplSpec) *pTemplSpec = typeName.right(typeName.length()-i); if (pTemplSpec) *pTemplSpec = typeName.right(typeName.length()-i);
...@@ -899,8 +890,33 @@ void setAnchors(char id,MemberList *ml,int groupId) ...@@ -899,8 +890,33 @@ void setAnchors(char id,MemberList *ml,int groupId)
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// read a file with `name' to a string.
int filterCRLF(char *buf,int len)
{
char *ps=buf;
char *pd=buf;
char c;
int i;
for (i=0;i<len;i++)
{
c=*ps++;
if (c=='\r')
{
if (*ps=='\n') ps++; // DOS: CR+LF -> LF
*pd++='\n'; // MAC: CR -> LF
}
else
{
*pd++=c;
}
}
return len+pd-ps;
}
/*! reads a file with name \a name and returns it as a string. If \a filter
* is TRUE the file will be filtered by any user specified input filter.
* If \a name is "-" the string will be read from standard input.
*/
QCString fileToString(const char *name,bool filter) QCString fileToString(const char *name,bool filter)
{ {
if (name==0 || name[0]==0) return 0; if (name==0 || name[0]==0) return 0;
...@@ -921,7 +937,7 @@ QCString fileToString(const char *name,bool filter) ...@@ -921,7 +937,7 @@ QCString fileToString(const char *name,bool filter)
totalSize+=bSize; totalSize+=bSize;
contents.resize(totalSize+bSize); contents.resize(totalSize+bSize);
} }
totalSize+=size+2; totalSize = filterCRLF(contents.data(),totalSize+size)+2;
contents.resize(totalSize); contents.resize(totalSize);
contents.at(totalSize-2)='\n'; // to help the scanner contents.at(totalSize-2)='\n'; // to help the scanner
contents.at(totalSize-1)='\0'; contents.at(totalSize-1)='\0';
...@@ -951,6 +967,11 @@ QCString fileToString(const char *name,bool filter) ...@@ -951,6 +967,11 @@ QCString fileToString(const char *name,bool filter)
contents[fsize]='\n'; // to help the scanner contents[fsize]='\n'; // to help the scanner
contents[fsize+1]='\0'; contents[fsize+1]='\0';
f.close(); f.close();
int newSize = filterCRLF(contents.data(),fsize+2);
if (newSize!=fsize+2)
{
contents.resize(newSize);
}
return contents; return contents;
} }
} }
...@@ -972,7 +993,7 @@ QCString fileToString(const char *name,bool filter) ...@@ -972,7 +993,7 @@ QCString fileToString(const char *name,bool filter)
totalSize+=bSize; totalSize+=bSize;
contents.resize(totalSize+bSize); contents.resize(totalSize+bSize);
} }
totalSize+=size+2; totalSize = filterCRLF(contents.data(),totalSize+size)+2;
contents.resize(totalSize); contents.resize(totalSize);
contents.at(totalSize-2)='\n'; // to help the scanner contents.at(totalSize-2)='\n'; // to help the scanner
contents.at(totalSize-1)='\0'; contents.at(totalSize-1)='\0';
...@@ -3212,7 +3233,7 @@ QCString substituteTemplateArgumentsInString( ...@@ -3212,7 +3233,7 @@ QCString substituteTemplateArgumentsInString(
} }
else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty()) else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty())
{ {
result += formArg->defval; result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs);
found=TRUE; found=TRUE;
} }
} }
......
...@@ -164,6 +164,7 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, ...@@ -164,6 +164,7 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
QCString resolveTypeDef(Definition *d,const QCString &name); QCString resolveTypeDef(Definition *d,const QCString &name);
QCString mergeScopes(const QCString &leftScope,const QCString &rightScope); QCString mergeScopes(const QCString &leftScope,const QCString &rightScope);
int getScopeFragment(const QCString &s,int p,int *l); int getScopeFragment(const QCString &s,int p,int *l);
int filterCRLF(char *buf,int len);
#endif #endif
...@@ -28,12 +28,14 @@ ...@@ -28,12 +28,14 @@
#include "defargs.h" #include "defargs.h"
#include "outputgen.h" #include "outputgen.h"
#include "doc.h" #include "doc.h"
#include "dot.h"
#include "code.h"
#include <qdir.h> #include <qdir.h>
#include <qfile.h> #include <qfile.h>
#include <qtextstream.h> #include <qtextstream.h>
static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t) QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
{ {
switch (t) switch (t)
{ {
...@@ -62,15 +64,19 @@ static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t) ...@@ -62,15 +64,19 @@ static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
return "illegal"; return "illegal";
} }
static inline void writeXMLString(QTextStream &t,const char *s) inline void writeXMLString(QTextStream &t,const char *s)
{ {
t << convertToXML(s); t << convertToXML(s);
} }
static void writeXMLLink(QTextStream &t,const char *compoundId, void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
const char *anchorId,const char *text) const char *anchorId,const char *text)
{ {
t << "<ref idref=\"" << compoundId << "\""; t << "<ref idref=\"" << compoundId << "\"";
if (extRef)
{
t << " external=\"" << extRef << "\"";
}
if (anchorId) if (anchorId)
{ {
t << " anchor=\"" << anchorId << "\""; t << " anchor=\"" << anchorId << "\"";
...@@ -93,10 +99,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf ...@@ -93,10 +99,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf
const char *anchor,const char *text const char *anchor,const char *text
) const ) const
{ {
if (extRef==0) writeXMLLink(m_t,extRef,file,anchor,text);
{ writeXMLLink(m_t,file,anchor,text); }
else // external references are not supported for XML
{ writeXMLString(m_t,text); }
} }
private: private:
QTextStream &m_t; QTextStream &m_t;
...@@ -418,26 +421,12 @@ class XMLGenerator : public OutputDocInterface ...@@ -418,26 +421,12 @@ class XMLGenerator : public OutputDocInterface
void writeObjectLink(const char *ref,const char *file, void writeObjectLink(const char *ref,const char *file,
const char *anchor, const char *text) const char *anchor, const char *text)
{ {
if (ref) // TODO: add support for external references writeXMLLink(m_t,ref,file,anchor,text);
{
docify(text);
}
else
{
writeXMLLink(m_t,file,anchor,text);
}
} }
void writeCodeLink(const char *ref,const char *file, void writeCodeLink(const char *ref,const char *file,
const char *anchor,const char *text) const char *anchor,const char *text)
{ {
if (ref) // TODO: add support for external references writeXMLLink(m_t,ref,file,anchor,text);
{
docify(text);
}
else
{
writeXMLLink(m_t,file,anchor,text);
}
} }
void startHtmlLink(const char *url) void startHtmlLink(const char *url)
{ {
...@@ -628,14 +617,22 @@ class XMLGenerator : public OutputDocInterface ...@@ -628,14 +617,22 @@ class XMLGenerator : public OutputDocInterface
void endPageRef(const char *,const char *) void endPageRef(const char *,const char *)
{ {
} }
void startLineNumber()
{
m_t << "<linenumber>";
}
void endLineNumber()
{
m_t << "</linenumber>";
}
void startCodeLine() void startCodeLine()
{ {
startParMode(); startParMode();
m_t << "<linenumber>"; // non DocBook m_t << "<codeline>"; // non DocBook
} }
void endCodeLine() void endCodeLine()
{ {
m_t << "</linenumber>"; // non DocBook m_t << "</codeline>" << endl; // non DocBook
} }
void startCodeAnchor(const char *id) void startCodeAnchor(const char *id)
{ {
...@@ -740,6 +737,8 @@ class XMLGenerator : public OutputDocInterface ...@@ -740,6 +737,8 @@ class XMLGenerator : public OutputDocInterface
ValStack<bool> m_inParStack; ValStack<bool> m_inParStack;
ValStack<bool> m_inListStack; ValStack<bool> m_inListStack;
bool m_inParamList; bool m_inParamList;
friend void writeXMLCodeBlock(QTextStream &t,FileDef *fd);
}; };
void writeXMLDocBlock(QTextStream &t, void writeXMLDocBlock(QTextStream &t,
...@@ -762,6 +761,21 @@ void writeXMLDocBlock(QTextStream &t, ...@@ -762,6 +761,21 @@ void writeXMLDocBlock(QTextStream &t,
delete xmlGen; delete xmlGen;
} }
void writeXMLCodeBlock(QTextStream &t,FileDef *fd)
{
initParseCodeContext();
XMLGenerator *xmlGen = new XMLGenerator;
xmlGen->m_inParStack.push(TRUE);
parseCode(*xmlGen,
0,
fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
FALSE,
0,
fd);
t << xmlGen->getContents();
delete xmlGen;
}
void generateXMLForMember(MemberDef *md,QTextStream &t,Definition *def) void generateXMLForMember(MemberDef *md,QTextStream &t,Definition *def)
...@@ -952,19 +966,18 @@ void generateXMLClassSection(ClassDef *cd,QTextStream &t,MemberList *ml,const ch ...@@ -952,19 +966,18 @@ void generateXMLClassSection(ClassDef *cd,QTextStream &t,MemberList *ml,const ch
void generateXMLForClass(ClassDef *cd,QTextStream &t) void generateXMLForClass(ClassDef *cd,QTextStream &t)
{ {
// brief description // + brief description
// detailed description // + detailed description
// template arguments // - template arguments
// include files // - include files
// inheritance diagram // + inheritance diagram
// list of direct super classes // + list of direct super classes
// list of direct sub classes // + list of direct sub classes
// collaboration diagram // + collaboration diagram
// list of all members // - list of all members
// user defined member sections // + user defined member sections
// standard member sections // + standard member sections
// detailed documentation // + detailed member documentation
// detailed member documentation
if (cd->name().find('@')!=-1) return; // skip anonymous compounds. if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
if (cd->templateMaster()!=0) return; // skip generated template instances. if (cd->templateMaster()!=0) return; // skip generated template instances.
...@@ -1071,6 +1084,20 @@ void generateXMLForClass(ClassDef *cd,QTextStream &t) ...@@ -1071,6 +1084,20 @@ void generateXMLForClass(ClassDef *cd,QTextStream &t)
t << " <detaileddescription>" << endl; t << " <detaileddescription>" << endl;
writeXMLDocBlock(t,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->documentation()); writeXMLDocBlock(t,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->documentation());
t << " </detaileddescription>" << endl; t << " </detaileddescription>" << endl;
DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance);
if (!inheritanceGraph.isTrivial())
{
t << " <inheritancegraph>" << endl;
inheritanceGraph.writeXML(t);
t << " </inheritancegraph>" << endl;
}
DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation);
if (!collaborationGraph.isTrivial())
{
t << " <collaborationgraph>" << endl;
collaborationGraph.writeXML(t);
t << " </collaborationgraph>" << endl;
}
t << " </compounddef>" << endl; t << " </compounddef>" << endl;
} }
...@@ -1118,6 +1145,9 @@ void generateXMLForFile(FileDef *fd,QTextStream &t) ...@@ -1118,6 +1145,9 @@ void generateXMLForFile(FileDef *fd,QTextStream &t)
t << " <detaileddescription>" << endl; t << " <detaileddescription>" << endl;
writeXMLDocBlock(t,fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation()); writeXMLDocBlock(t,fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation());
t << " </detaileddescription>" << endl; t << " </detaileddescription>" << endl;
t << " <sourcecode>" << endl;
writeXMLCodeBlock(t,fd);
t << " </sourcecode>" << endl;
t << " </compounddef>" << endl; t << " </compounddef>" << endl;
} }
......
...@@ -11,7 +11,7 @@ TMAKE_CC = gcc ...@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS = TMAKE_CFLAGS =
TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF = TMAKE_CFLAGS_WARN_OFF =
TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_RELEASE = -O0
TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
......
...@@ -11,7 +11,7 @@ TMAKE_CC = gcc ...@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS = TMAKE_CFLAGS =
TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF = TMAKE_CFLAGS_WARN_OFF =
TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_RELEASE = -O0
TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
......
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