Commit 903cf7ca authored by Dimitri van Heesch's avatar Dimitri van Heesch

Release-1.2.3-20001119

parent 020742ed
DOXYGEN Version 1.2.3-20001106 DOXYGEN Version 1.2.3-20001118
Please read the installation section of the manual for instructions. Please read the installation section of the manual for instructions.
-------- --------
Dimitri van Heesch (06 November 2000) Dimitri van Heesch (18 November 2000)
DOXYGEN Version 1.2.3-20001106 DOXYGEN Version 1.2.3-20001118
Please read INSTALL for compilation instructions. Please read INSTALL for compilation instructions.
...@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at ...@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at
Enjoy, Enjoy,
Dimitri van Heesch (06 November 2000) Dimitri van Heesch (18 November 2000)
1.2.3-20001106 1.2.3-20001118
...@@ -713,6 +713,11 @@ int main(int argc,char * argv[]) ...@@ -713,6 +713,11 @@ int main(int argc,char * argv[])
while (!ctfile.atEnd()) while (!ctfile.atEnd())
{ {
ctfile.readLine(buf,maxLineLen-1); ctfile.readLine(buf,maxLineLen-1);
if (buf[l-2]--'\r') // remove the \r for the folks using Windows
{
buf[l-2]='\n';
buf[l-1]='\r';
}
if (QCString("#CONFIG Config\n" )==buf) FORALL(printConfig(t)) if (QCString("#CONFIG Config\n" )==buf) FORALL(printConfig(t))
else if (QCString("#CONFIG Static\n" )==buf) FORALL(printStatic(t)) else if (QCString("#CONFIG Static\n" )==buf) FORALL(printStatic(t))
else if (QCString("#CONFIG Rules\n" )==buf) FORALL(printRules(t)) else if (QCString("#CONFIG Rules\n" )==buf) FORALL(printRules(t))
......
...@@ -407,7 +407,7 @@ followed by the descriptions of the tags grouped by category. ...@@ -407,7 +407,7 @@ followed by the descriptions of the tags grouped by category.
\anchor cfg_enabled_sections \anchor cfg_enabled_sections
<dt>\c ENABLED_SECTIONS <dd> <dt>\c ENABLED_SECTIONS <dd>
\addindex ENABLED_SECTIONS \addindex ENABLED_SECTIONS
The \c ENABLE_SECTIONS tag can be used to enable conditional The \c ENABLED_SECTIONS tag can be used to enable conditional
documentation sections, marked by \ref cmdif "\\if" \<section-label\> ... documentation sections, marked by \ref cmdif "\\if" \<section-label\> ...
\ref cmdendif "\\endif" blocks. \ref cmdendif "\\endif" blocks.
......
Name: doxygen Name: doxygen
Version: 1.2.3-20001106 Version: 1.2.3-20001118
Summary: documentation system for C, C++ and IDL Summary: documentation system for C, C++ and IDL
Release: 1 Release: 1
Source0: doxygen-%{version}.src.tar.gz Source0: doxygen-%{version}.src.tar.gz
......
...@@ -973,9 +973,13 @@ void ClassDef::writeDocumentation(OutputList &ol) ...@@ -973,9 +973,13 @@ void ClassDef::writeDocumentation(OutputList &ol)
} }
// repeat brief description // repeat brief description
if (!briefDescription().isEmpty()) if (!briefDescription().isEmpty() && Config::repeatBriefFlag)
{ {
ol+=briefOutput; ol+=briefOutput;
}
if (!briefDescription().isEmpty() && Config::repeatBriefFlag &&
!documentation().isEmpty())
{
ol.newParagraph(); ol.newParagraph();
} }
// write documentation // write documentation
......
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#define YY_NEVER_INTERACTIVE 1 #define YY_NEVER_INTERACTIVE 1
#define SCOPEBLOCK (void *)1
#define INNERBLOCK (void *)2
/*! local class definition, used for classes that are defined /*! local class definition, used for classes that are defined
* inside code fragments. * inside code fragments.
*/ */
...@@ -104,6 +107,8 @@ static QCString g_parmType; ...@@ -104,6 +107,8 @@ static QCString g_parmType;
static QCString g_parmName; static QCString g_parmName;
static bool g_inClass; static bool g_inClass;
static QCString g_classScope; static QCString g_classScope;
static QCString g_realScope;
static QStack<void> g_scopeStack; // 1 if bracket starts a scope, 2 for internal blocks
static OutputList * g_code; static OutputList * g_code;
static CodeClassDef g_ccd; static CodeClassDef g_ccd;
static CodeVarDef g_cvd; static CodeVarDef g_cvd;
...@@ -123,6 +128,60 @@ static ClassDef * g_classVar; ...@@ -123,6 +128,60 @@ static ClassDef * g_classVar;
static QCString g_saveName; static QCString g_saveName;
static QCString g_saveType; static QCString g_saveType;
/*! add class/namespace name s to the scope */
static void pushScope(const char *s)
{
if (g_classScope.isEmpty())
{
g_classScope = s;
}
else
{
g_classScope += "::";
g_classScope += s;
}
//printf("pushScope() result: `%s'\n",g_classScope.data());
}
/*! remove the top class/namespace name from the scope */
static void popScope()
{
if (!g_classScope.isEmpty())
{
int i=g_classScope.findRev("::");
if (i==-1) // last name, strip all
{
g_classScope.resize(0);
}
else // strip name
{
g_classScope = g_classScope.left(i);
}
}
else
{
//err("Error: Too many end of scopes found!\n");
}
//printf("popScope() result: `%s'\n",g_classScope.data());
}
static void setClassScope(const QCString &name)
{
//printf("setClassScope(%s)\n",name.data());
QCString n=name;
n=n.simplifyWhiteSpace();
int ts=n.find('<'); // start of template
int te=n.findRev('>'); // end of template
//printf("ts=%d te=%d\n",ts,te);
if (ts!=-1 && te!=-1 && te>ts)
{
// remove template from scope
n=n.left(ts)+n.right(n.length()-te-1);
}
g_classScope = n;
//printf("--->New class scope `%s'\n",g_classScope.data());
}
/*! start a new line of code, inserting a line number if g_sourceFileDef /*! start a new line of code, inserting a line number if g_sourceFileDef
* is TRUE. If a definition starts at the current line, then the line * is TRUE. If a definition starts at the current line, then the line
* number is linked to the documentation of that definition. * number is linked to the documentation of that definition.
...@@ -144,6 +203,8 @@ static void startCodeLine() ...@@ -144,6 +203,8 @@ static void startCodeLine()
QCString anchor; QCString anchor;
g_insideBody = FALSE; g_insideBody = FALSE;
g_searchingForBody = TRUE; g_searchingForBody = TRUE;
g_realScope = d->name().copy();
//printf("Real scope: `%s'\n",g_realScope.data());
g_bodyCurlyCount = 0; g_bodyCurlyCount = 0;
if (g_currentMemberDef) anchor=g_currentMemberDef->anchor(); if (g_currentMemberDef) anchor=g_currentMemberDef->anchor();
g_code->startCodeAnchor(lineAnchor); g_code->startCodeAnchor(lineAnchor);
...@@ -256,27 +317,6 @@ static void addParmType() ...@@ -256,27 +317,6 @@ static void addParmType()
g_parmName.resize(0) ; g_parmName.resize(0) ;
} }
static void setClassScope(const QCString &name)
{
//printf("setClassScope(%s)\n",name.data());
QCString n=name;
n=n.simplifyWhiteSpace();
int ts=n.find('<'); // start of template
int te=n.findRev('>'); // end of template
//printf("ts=%d te=%d\n",ts,te);
if (ts!=-1 && te!=-1 && te>ts)
{
// remove template from scope
n=n.left(ts)+n.right(n.length()-te-1);
}
int index;
if ((index=n.findRev("::"))!=-1)
g_classScope=n.left(index);
else
g_classScope.resize(0);
//printf("--->New class scope `%s'\n",g_classScope.data());
}
static void addVariable() static void addVariable()
{ {
g_cvd.name=g_name.copy().simplifyWhiteSpace(); g_cvd.name=g_name.copy().simplifyWhiteSpace();
...@@ -698,6 +738,9 @@ static void startFontClass(const char *s) ...@@ -698,6 +738,9 @@ static void startFontClass(const char *s)
g_currentFontClass=s; g_currentFontClass=s;
} }
/* ----------------------------------------------------------------- /* -----------------------------------------------------------------
*/ */
#undef YY_INPUT #undef YY_INPUT
...@@ -753,7 +796,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -753,7 +796,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext); g_code->codify(yytext);
BEGIN( ReadInclude ); BEGIN( ReadInclude );
} }
<Body>("class"|"struct"|"union")[ \t\n]+ { <Body>("class"|"struct"|"union"|"namespace")[ \t\n]+ {
startFontClass("keyword"); startFontClass("keyword");
codifyLines(yytext); codifyLines(yytext);
endFontClass(); endFontClass();
...@@ -801,6 +844,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -801,6 +844,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext); g_code->codify(yytext);
} }
<Body>"{" { <Body>"{" {
g_scopeStack.push(INNERBLOCK);
if (g_searchingForBody) if (g_searchingForBody)
{ {
g_searchingForBody=FALSE; g_searchingForBody=FALSE;
...@@ -813,11 +857,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -813,11 +857,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_name.resize(0); g_name.resize(0);
} }
<Body>"}" { <Body>"}" {
if (g_scopeStack.pop()==SCOPEBLOCK) popScope();
g_code->codify(yytext); g_code->codify(yytext);
g_inClass=FALSE; g_inClass=FALSE;
if (--g_curlyCount<=0) if (--g_curlyCount<=0)
{ {
g_classScope.resize(0); //g_classScope.resize(0);
g_codeParmList.clear(); g_codeParmList.clear();
} }
if (--g_bodyCurlyCount<=0) if (--g_bodyCurlyCount<=0)
...@@ -855,12 +900,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -855,12 +900,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
if (g_insideBody) g_bodyCurlyCount++; if (g_insideBody) g_bodyCurlyCount++;
if (!g_ccd.name.isEmpty()) if (!g_ccd.name.isEmpty())
{ {
g_classScope=g_ccd.name.copy(); g_scopeStack.push(SCOPEBLOCK);
pushScope(g_ccd.name);
//g_classScope=g_ccd.name.copy();
CodeClassDef *cd=new CodeClassDef(g_ccd); CodeClassDef *cd=new CodeClassDef(g_ccd);
g_codeClassList.append(cd); g_codeClassList.append(cd);
g_codeClassDict.insert(cd->name,cd); g_codeClassDict.insert(cd->name,cd);
//printf("g_codeClassList.count()=%d\n",g_codeClassList.count()); //printf("g_codeClassList.count()=%d\n",g_codeClassList.count());
} }
else
{
g_scopeStack.push((void *)2);
}
BEGIN( Body ); BEGIN( Body );
} }
<Bases>"virtual"|"public"|"protected"|"private" { <Bases>"virtual"|"public"|"protected"|"private" {
...@@ -951,13 +1002,6 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -951,13 +1002,6 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext); g_code->codify(yytext);
g_name.resize(0);g_type.resize(0); g_name.resize(0);g_type.resize(0);
} }
/*
<Body>([a-z_A-Z~][a-z_A-Z0-9]*)/([ \t]*) {
generateClassLink(*g_code,yytext);
addType();
name+=yytext;
}
*/
<Body>{TYPEKW}/{B}* { <Body>{TYPEKW}/{B}* {
startFontClass("keywordtype"); startFontClass("keywordtype");
g_code->codify(yytext); g_code->codify(yytext);
...@@ -1159,7 +1203,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1159,7 +1203,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
<MemberCall2,FuncCall>")"({BN}"const"|"volatile")*{BN}*"{" { <MemberCall2,FuncCall>")"({BN}"const"|"volatile")*{BN}*"{" {
addParameter(); addParameter();
g_parmType.resize(0);g_parmName.resize(0); g_parmType.resize(0);g_parmName.resize(0);
if (g_name.find("::")!=-1) setClassScope(g_name); if (g_name.find("::")!=-1)
{
g_scopeStack.push(SCOPEBLOCK);
setClassScope(g_realScope);
}
else
{
g_scopeStack.push(INNERBLOCK);
}
g_code->codify(")"); g_code->codify(")");
startFontClass("keyword"); startFontClass("keyword");
yytext[yyleng-1]='\0'; yytext[yyleng-1]='\0';
...@@ -1190,7 +1242,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" ...@@ -1190,7 +1242,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_insideBody=TRUE; g_insideBody=TRUE;
} }
if (g_insideBody) g_bodyCurlyCount++; if (g_insideBody) g_bodyCurlyCount++;
if (g_name.find("::")!=-1) setClassScope(g_name); if (g_name.find("::")!=-1)
{
g_scopeStack.push(SCOPEBLOCK);
setClassScope(g_realScope);
}
else
{
g_scopeStack.push(INNERBLOCK);
}
g_type.resize(0); g_name.resize(0); g_type.resize(0); g_name.resize(0);
BEGIN( Body ); BEGIN( Body );
} }
...@@ -1520,6 +1580,7 @@ void parseCode(OutputList &ol,const char *className,const QCString &s, ...@@ -1520,6 +1580,7 @@ void parseCode(OutputList &ol,const char *className,const QCString &s,
g_sharpCount = 0; g_sharpCount = 0;
g_insideTemplate = FALSE; g_insideTemplate = FALSE;
g_classVar = 0; g_classVar = 0;
g_scopeStack.clear();
g_classScope = className; g_classScope = className;
g_exampleBlock = exBlock; g_exampleBlock = exBlock;
g_exampleName = exName; g_exampleName = exName;
......
...@@ -1243,7 +1243,6 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path, ...@@ -1243,7 +1243,6 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path,
err("Error: Problems running epstopdf. Check your TeX installation!\n"); err("Error: Problems running epstopdf. Check your TeX installation!\n");
return; return;
} }
printf("done\n");
} }
} }
......
...@@ -137,10 +137,51 @@ void clearAll() ...@@ -137,10 +137,51 @@ void clearAll()
delete mainPage; mainPage=0; delete mainPage; mainPage=0;
} }
//bool unrelatedFunctionsUsed; void statistics()
{
//ClassDef unrelatedClass("nothing",ClassDef::Class); fprintf(stderr,"--- inputNameDict stats ----\n");
// dummy class for unrelated functions inputNameDict->statistics();
fprintf(stderr,"--- includeNameDict stats ----\n");
includeNameDict->statistics();
fprintf(stderr,"--- exampleNameDict stats ----\n");
exampleNameDict->statistics();
fprintf(stderr,"--- imageNameDict stats ----\n");
imageNameDict->statistics();
fprintf(stderr,"--- classDict stats ----\n");
classDict.statistics();
fprintf(stderr,"--- namespaceDict stats ----\n");
namespaceDict.statistics();
fprintf(stderr,"--- memberNameDict stats ----\n");
memberNameDict.statistics();
fprintf(stderr,"--- functionNameDict stats ----\n");
functionNameDict.statistics();
fprintf(stderr,"--- sectionDict stats ----\n");
sectionDict.statistics();
fprintf(stderr,"--- excludeNameDict stats ----\n");
excludeNameDict.statistics();
fprintf(stderr,"--- aliasDict stats ----\n");
aliasDict.statistics();
fprintf(stderr,"--- typedefDict stats ----\n");
typedefDict.statistics();
fprintf(stderr,"--- namespaceAliasDict stats ----\n");
namespaceAliasDict.statistics();
fprintf(stderr,"--- groupDict stats ----\n");
groupDict.statistics();
fprintf(stderr,"--- formulaDict stats ----\n");
formulaDict.statistics();
fprintf(stderr,"--- formulaNameDict stats ----\n");
formulaNameDict.statistics();
fprintf(stderr,"--- tagDestinationDict stats ----\n");
tagDestinationDict.statistics();
fprintf(stderr,"--- compoundKeywordDict stats ----\n");
compoundKeywordDict.statistics();
fprintf(stderr,"--- expandAsDefinedDict stats ----\n");
expandAsDefinedDict.statistics();
fprintf(stderr,"--- memberHeaderDict stats ----\n");
memberHeaderDict.statistics();
fprintf(stderr,"--- memberDocDict stats ----\n");
memberDocDict.statistics();
}
int annotatedClasses; int annotatedClasses;
int hierarchyClasses; int hierarchyClasses;
...@@ -813,6 +854,8 @@ static void buildNamespaceList(Entry *root) ...@@ -813,6 +854,8 @@ static void buildNamespaceList(Entry *root)
// the empty string test is needed for extract all case // the empty string test is needed for extract all case
nd->setBriefDescription(root->brief); nd->setBriefDescription(root->brief);
nd->insertUsedFile(root->fileName); nd->insertUsedFile(root->fileName);
nd->setBodySegment(root->bodyLine,root->endBodyLine);
nd->setBodyDef(fd);
// add class to the list // add class to the list
namespaceList.inSort(nd); namespaceList.inSort(nd);
namespaceDict.insert(fullName,nd); namespaceDict.insert(fullName,nd);
...@@ -4190,6 +4233,7 @@ static void generateFileDocs() ...@@ -4190,6 +4233,7 @@ static void generateFileDocs()
static void addSourceReferences() static void addSourceReferences()
{ {
// add source references for class definitions
ClassListIterator cli(classList); ClassListIterator cli(classList);
ClassDef *cd=0; ClassDef *cd=0;
for (cli.toFirst();(cd=cli.current());++cli) for (cli.toFirst();(cd=cli.current());++cli)
...@@ -4200,6 +4244,19 @@ static void addSourceReferences() ...@@ -4200,6 +4244,19 @@ static void addSourceReferences()
fd->addSourceRef(cd->getStartBodyLine(),cd,0); fd->addSourceRef(cd->getStartBodyLine(),cd,0);
} }
} }
// add source references for namespace definitions
NamespaceListIterator nli(namespaceList);
NamespaceDef *nd=0;
for (nli.toFirst();(nd=nli.current());++nli)
{
FileDef *fd=nd->getBodyDef();
if (fd && nd->isLinkableInProject() && nd->getStartBodyLine()!=-1)
{
fd->addSourceRef(nd->getStartBodyLine(),nd,0);
}
}
// add source references for member names
MemberNameListIterator mnli(memberNameList); MemberNameListIterator mnli(memberNameList);
MemberName *mn=0; MemberName *mn=0;
for (mnli.toFirst();(mn=mnli.current());++mnli) for (mnli.toFirst();(mn=mnli.current());++mnli)
...@@ -4441,11 +4498,6 @@ static void findDefineDocumentation(Entry *root) ...@@ -4441,11 +4498,6 @@ static void findDefineDocumentation(Entry *root)
md->setMaxInitLines(root->initLines); md->setMaxInitLines(root->initLines);
if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
addMemberToGroups(root,md); addMemberToGroups(root,md);
//FileDef *fd=md->getFileDef();
//if (fd && root->mGrpId!=-1)
//{
// fd->addMemberToGroup(md,root->mGrpId);
//}
} }
md=mn->next(); md=mn->next();
} }
...@@ -4476,16 +4528,8 @@ static void findDefineDocumentation(Entry *root) ...@@ -4476,16 +4528,8 @@ static void findDefineDocumentation(Entry *root)
bool ambig; bool ambig;
md->setBodyDef(findFileDef(inputNameDict,root->fileName,ambig)); md->setBodyDef(findFileDef(inputNameDict,root->fileName,ambig));
md->addSectionsToDefinition(root->anchors); md->addSectionsToDefinition(root->anchors);
//if (root->mGrpId!=-1 && md->getMemberGroup()==0)
//{
// md->setMemberGroup(memberGroupDict[root->mGrpId]);
//}
if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
addMemberToGroups(root,md); addMemberToGroups(root,md);
//if (root->mGrpId!=-1)
//{
// fd->addMemberToGroup(md,root->mGrpId);
//}
} }
} }
md=mn->next(); md=mn->next();
...@@ -5979,6 +6023,8 @@ int main(int argc,char **argv) ...@@ -5979,6 +6023,8 @@ int main(int argc,char **argv)
if (Config::generateHtml) writeDoxFont(Config::htmlOutputDir); if (Config::generateHtml) writeDoxFont(Config::htmlOutputDir);
if (Config::generateRTF) writeDoxFont(Config::rtfOutputDir); if (Config::generateRTF) writeDoxFont(Config::rtfOutputDir);
//statistics();
// count the number of documented elements in the lists we have built. // count the number of documented elements in the lists we have built.
// If the result is 0 we do not generate the lists and omit the // If the result is 0 we do not generate the lists and omit the
// corresponding links in the index. // corresponding links in the index.
......
...@@ -318,11 +318,12 @@ void FileDef::writeDocumentation(OutputList &ol) ...@@ -318,11 +318,12 @@ void FileDef::writeDocumentation(OutputList &ol)
ol.startGroupHeader(); ol.startGroupHeader();
parseText(ol,theTranslator->trDetailedDescription()); parseText(ol,theTranslator->trDetailedDescription());
ol.endGroupHeader(); ol.endGroupHeader();
if (!briefDescription().isEmpty()) if (!briefDescription().isEmpty() && Config::repeatBriefFlag)
{ {
ol+=briefOutput; ol+=briefOutput;
} }
if (!briefDescription().isEmpty() && !documentation().isEmpty()) if (!briefDescription().isEmpty() && Config::repeatBriefFlag &&
!documentation().isEmpty())
{ {
ol.newParagraph(); ol.newParagraph();
} }
......
...@@ -478,6 +478,7 @@ void addGroupToGroups(Entry *root,GroupDef *subGroup) ...@@ -478,6 +478,7 @@ void addGroupToGroups(Entry *root,GroupDef *subGroup)
} }
} }
/*! Add a member to all groups it is contained in */
void addMemberToGroups(Entry *root,MemberDef *md) void addMemberToGroups(Entry *root,MemberDef *md)
{ {
QListIterator<QCString> sli(*root->groups); QListIterator<QCString> sli(*root->groups);
......
...@@ -407,11 +407,11 @@ void LatexGenerator::writeStyleSheetFile(QFile &f) ...@@ -407,11 +407,11 @@ void LatexGenerator::writeStyleSheetFile(QFile &f)
writeDefaultStyleSheetPart1(t); writeDefaultStyleSheetPart1(t);
t << "Generated at " << dateToString(TRUE); t << "Generated at " << dateToString(TRUE);
if (Config::projectName.isEmpty()) t << " for " << Config::projectName << " "; if (Config::projectName.isEmpty()) t << " for " << Config::projectName << " ";
t << "by doxygen written by Dimitri van Heesch \\copyright{} 1997-2000"; t << "by doxygen written by Dimitri van Heesch \\copyright~1997-2000";
writeDefaultStyleSheetPart2(t); writeDefaultStyleSheetPart2(t);
t << "Generated at " << dateToString(TRUE); t << "Generated at " << dateToString(TRUE);
if (Config::projectName.isEmpty()) t << " for " << Config::projectName << " "; if (Config::projectName.isEmpty()) t << " for " << Config::projectName << " ";
t << "by doxygen written by Dimitri van Heesch \\copyright{} 1997-2000"; t << "by doxygen written by Dimitri van Heesch \\copyright~1997-2000";
writeDefaultStyleSheetPart3(t); writeDefaultStyleSheetPart3(t);
} }
...@@ -778,14 +778,14 @@ void LatexGenerator::writeStyleInfo(int part) ...@@ -778,14 +778,14 @@ void LatexGenerator::writeStyleInfo(int part)
break; break;
case 2: case 2:
{ {
t << " Dimitri van Heesch \\copyright{} 1997-2000"; t << " Dimitri van Heesch \\copyright~1997-2000";
t << "}]{}\n"; t << "}]{}\n";
writeDefaultStyleSheetPart2(t); writeDefaultStyleSheetPart2(t);
} }
break; break;
case 4: case 4:
{ {
t << " Dimitri van Heesch \\copyright{} 1997-2000"; t << " Dimitri van Heesch \\copyright~1997-2000";
writeDefaultStyleSheetPart3(t); writeDefaultStyleSheetPart3(t);
endPlainFile(); endPlainFile();
} }
......
...@@ -1538,21 +1538,24 @@ void MemberDef::generateXML(QTextStream &t,Definition *def) ...@@ -1538,21 +1538,24 @@ void MemberDef::generateXML(QTextStream &t,Definition *def)
else if (xmlType==enum_t) // enum else if (xmlType==enum_t) // enum
{ {
t << " <enumvaluelist>" << endl; t << " <enumvaluelist>" << endl;
MemberListIterator emli(*enumFields); if (enumFields)
MemberDef *emd;
for (emli.toFirst();(emd=emli.current());++emli)
{ {
t << " <enumvalue>" << endl; MemberListIterator emli(*enumFields);
t << " <name>"; MemberDef *emd;
writeXMLString(t,emd->name()); for (emli.toFirst();(emd=emli.current());++emli)
t << "</name>" << endl;
if (!emd->init.isEmpty())
{ {
t << " <initializer>"; t << " <enumvalue>" << endl;
writeXMLString(t,emd->init); t << " <name>";
t << "</initializer>" << endl; writeXMLString(t,emd->name());
t << "</name>" << endl;
if (!emd->init.isEmpty())
{
t << " <initializer>";
writeXMLString(t,emd->init);
t << "</initializer>" << endl;
}
t << " </enumvalue>" << endl;
} }
t << " </enumvalue>" << endl;
} }
t << " </enumvaluelist>" << endl; t << " </enumvaluelist>" << endl;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "filedef.h" #include "filedef.h"
#include "language.h" #include "language.h"
#include "scanner.h" #include "scanner.h"
#include "groupdef.h"
//static QCString idToName(int id) //static QCString idToName(int id)
//{ //{
...@@ -58,8 +59,9 @@ void MemberGroup::insertMember(MemberDef *md) ...@@ -58,8 +59,9 @@ void MemberGroup::insertMember(MemberDef *md)
// memberList->first() ? memberList->first()->getSectionList() : 0, // memberList->first() ? memberList->first()->getSectionList() : 0,
// memberList->count(), // memberList->count(),
// md->getSectionList()); // md->getSectionList());
MemberDef *firstMd = memberList->first();
if (inSameSection && memberList->count()>0 && if (inSameSection && memberList->count()>0 &&
memberList->first()->getSectionList()!=md->getSectionList()) firstMd->getSectionList()!=md->getSectionList())
{ {
inSameSection=FALSE; inSameSection=FALSE;
} }
...@@ -68,6 +70,14 @@ void MemberGroup::insertMember(MemberDef *md) ...@@ -68,6 +70,14 @@ void MemberGroup::insertMember(MemberDef *md)
inDeclSection = md->getSectionList(); inDeclSection = md->getSectionList();
} }
memberList->append(md); memberList->append(md);
// copy the group of the first member in the memberGroup
GroupDef *gd;
if (firstMd && (gd=firstMd->getGroupDef()))
{
md->setGroupDef(gd);
gd->insertMember(md);
}
} }
......
...@@ -251,9 +251,13 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ...@@ -251,9 +251,13 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
parseText(ol,theTranslator->trDetailedDescription()); parseText(ol,theTranslator->trDetailedDescription());
ol.endGroupHeader(); ol.endGroupHeader();
ol.startTextBlock(); ol.startTextBlock();
if (!briefDescription().isEmpty()) if (!briefDescription().isEmpty() && Config::repeatBriefFlag)
{ {
ol+=briefOutput; ol+=briefOutput;
}
if (!briefDescription().isEmpty() && Config::repeatBriefFlag &&
!documentation().isEmpty())
{
ol.newParagraph(); ol.newParagraph();
} }
if (!documentation().isEmpty()) if (!documentation().isEmpty())
......
...@@ -278,16 +278,19 @@ static QCString stringize(const QCString &s) ...@@ -278,16 +278,19 @@ static QCString stringize(const QCString &s)
*/ */
static void processConcatOperators(QCString &expr) static void processConcatOperators(QCString &expr)
{ {
//printf("processConcatOperators: in=`%s'\n",expr.data());
QRegExp r("[ \\t\\n]*##[ \\t\\n]*"); QRegExp r("[ \\t\\n]*##[ \\t\\n]*");
int l,n,i=0; int l,n,i=0;
if (expr.isEmpty()) return; if (expr.isEmpty()) return;
while ((n=r.match(expr,i,&l))!=-1) while ((n=r.match(expr,i,&l))!=-1)
{ {
//printf("Match: `%s'\n",expr.data()+i);
if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-') if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-')
{ {
// remove no-rescan marker after ID // remove no-rescan marker after ID
l+=2; l+=2;
} }
//printf("found `%s'\n",expr.mid(n,l).data());
// remove the ## operator and the surrounding whitespace // remove the ## operator and the surrounding whitespace
expr=expr.left(n)+expr.right(expr.length()-n-l); expr=expr.left(n)+expr.right(expr.length()-n-l);
int k=n-1; int k=n-1;
...@@ -298,14 +301,15 @@ static void processConcatOperators(QCString &expr) ...@@ -298,14 +301,15 @@ static void processConcatOperators(QCString &expr)
expr=expr.left(k-1)+expr.right(expr.length()-k-1); expr=expr.left(k-1)+expr.right(expr.length()-k-1);
n-=2; n-=2;
} }
i=n+l; i=n;
} }
//printf("processConcatOperators: out=`%s'\n",expr.data());
} }
/*! replaces the function macro \a def whose argument list starts at /*! replaces the function macro \a def whose argument list starts at
* \a pos in expression \a expr. * \a pos in expression \a expr.
* Notice that this routine may scan beyond the \a expr string if needed. * Notice that this routine may scan beyond the \a expr string if needed.
* The characters from the input file will be read. * In that case the characters will be read from the input file.
* The replacement string will be returned in \a result and the * The replacement string will be returned in \a result and the
* length of the (unexpanded) argument list is stored in \a len. * length of the (unexpanded) argument list is stored in \a len.
*/ */
...@@ -338,7 +342,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int ...@@ -338,7 +342,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
int argCount=0; int argCount=0;
bool done=FALSE; bool done=FALSE;
// FASE 1: read the macro arguments // PHASE 1: read the macro arguments
if (def->nargs==0) if (def->nargs==0)
{ {
while ((cc=getNextChar(expr,rest,j))!=EOF) while ((cc=getNextChar(expr,rest,j))!=EOF)
...@@ -442,7 +446,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int ...@@ -442,7 +446,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
} }
} }
// FASE 2: apply the macro function // PHASE 2: apply the macro function
if (argCount==def->nargs || if (argCount==def->nargs ||
(argCount>def->nargs && def->varArgs)) // matching parameters lists (argCount>def->nargs && def->varArgs)) // matching parameters lists
{ {
...@@ -486,7 +490,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int ...@@ -486,7 +490,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
while (l<(int)d.length() && d.at(l)==' ') l++; while (l<(int)d.length() && d.at(l)==' ') l++;
if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE; if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE;
} }
//printf("request key %s result %s\n",key.data(),args[key]->data()); //printf("request key %s result %s\n",key.data(),argTable[key]->data());
if (key.length()>1 && (subst=argTable[key])) if (key.length()>1 && (subst=argTable[key]))
{ {
QCString substArg=*subst; QCString substArg=*subst;
...@@ -817,12 +821,12 @@ void addDefine() ...@@ -817,12 +821,12 @@ void addDefine()
//if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine());
} }
static void outputChar(char c) static inline void outputChar(char c)
{ {
if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addChar(c); if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addChar(c);
} }
static void outputArray(const char *a,int len) static inline void outputArray(const char *a,int len)
{ {
if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addArray(a,len); if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addArray(a,len);
} }
...@@ -1007,7 +1011,7 @@ BN [ \t\r\n] ...@@ -1007,7 +1011,7 @@ BN [ \t\r\n]
<CopyLine>{ID}/{BN}*"(" { <CopyLine>{ID}/{BN}*"(" {
Define *def=0; Define *def=0;
//printf("Search for define %s\n",yytext); //printf("Search for define %s\n",yytext);
if (g_includeStack.isEmpty() && if ((g_includeStack.isEmpty() || g_curlyCount>0) &&
Config::macroExpansionFlag && Config::macroExpansionFlag &&
/* (expandDefine=fileDefineCache->findDefine(g_yyFileName,yytext)) */ /* (expandDefine=fileDefineCache->findDefine(g_yyFileName,yytext)) */
(def=g_fileDefineDict->find(yytext)) && (def=g_fileDefineDict->find(yytext)) &&
...@@ -1037,7 +1041,7 @@ BN [ \t\r\n] ...@@ -1037,7 +1041,7 @@ BN [ \t\r\n]
<CopyLine>{ID} { <CopyLine>{ID} {
Define *def=0; Define *def=0;
//printf("Search for define %s\n",yytext); //printf("Search for define %s\n",yytext);
if (g_includeStack.isEmpty() && if ((g_includeStack.isEmpty() || g_curlyCount>0) &&
Config::macroExpansionFlag && Config::macroExpansionFlag &&
(def=g_fileDefineDict->find(yytext)) && (def=g_fileDefineDict->find(yytext)) &&
def->nargs==-1 && def->nargs==-1 &&
...@@ -1557,7 +1561,7 @@ BN [ \t\r\n] ...@@ -1557,7 +1561,7 @@ BN [ \t\r\n]
outputChar('\n'); outputChar('\n');
Define *def=0; Define *def=0;
//printf("Define name=`%s' text=`%s' litTexti=`%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data()); //printf("Define name=`%s' text=`%s' litTexti=`%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data());
if (g_includeStack.isEmpty()) if (g_includeStack.isEmpty() || g_curlyCount>0)
{ {
addDefine(); addDefine();
} }
......
...@@ -87,6 +87,7 @@ static int roundCount = 0 ; ...@@ -87,6 +87,7 @@ static int roundCount = 0 ;
static int curlyCount = 0 ; static int curlyCount = 0 ;
static int squareCount = 0 ; static int squareCount = 0 ;
static int ifCount = 0 ; static int ifCount = 0 ;
static int padCount = 0 ;
static int todoStartContext = 0; static int todoStartContext = 0;
static QCString todoString = 0; static QCString todoString = 0;
static int testStartContext = 0; static int testStartContext = 0;
...@@ -1267,6 +1268,11 @@ TITLE [tT][iI][tT][lL][eE] ...@@ -1267,6 +1268,11 @@ TITLE [tT][iI][tT][lL][eE]
*pCopyCurlyString+=*yytext; *pCopyCurlyString+=*yytext;
} }
<FindMembers>":" { <FindMembers>":" {
if (current->type.isEmpty()) // bit pad field
{
addType(current);
current->name.sprintf("__pad%d__",padCount++);
}
BEGIN(BitFields); BEGIN(BitFields);
current->bitfields+=":"; current->bitfields+=":";
} }
...@@ -3485,6 +3491,7 @@ static void parseCompounds(Entry *rt) ...@@ -3485,6 +3491,7 @@ static void parseCompounds(Entry *rt)
//printf("-- %s ---------\n%s\n---------------\n", //printf("-- %s ---------\n%s\n---------------\n",
// ce->name.data(),ce->program.data()); // ce->name.data(),ce->program.data());
// init scanner state // init scanner state
padCount=0;
inputString = ce->program; inputString = ce->program;
inputPosition = 0; inputPosition = 0;
scanYYrestart( scanYYin ) ; scanYYrestart( scanYYin ) ;
......
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
* Initial Italian Translation by Ahmed Aldo Faisal * Initial Italian Translation by Ahmed Aldo Faisal
* Revised and completed by Alessandro Falappa (June 1999) * Revised and completed by Alessandro Falappa (June 1999)
* Updates: * Updates:
* 2000/08: translated new items used since version 1.1.3, 1.1.4, 1.1.5 and 1.2.0 * 2000/11: modified slightly the translation in trLegendDocs() function,
* 2000/03: translated new items used since version 1.0 and 1.1.0 * translated new items used since version 1.2.1 and 1.2.2
* 1999/19: entirely rewritten the translation to correct small variations due * 2000/08: translated new items used since version 1.1.3, 1.1.4, 1.1.5 and 1.2.0
* to feature additions and to conform to the layout of the latest * 2000/03: translated new items used since version 1.0 and 1.1.0
* commented translator.h for the english language * 1999/19: entirely rewritten the translation to correct small variations due
* 1999/09: corrected some small typos in the "new since 0.49-990425" section * to feature additions and to conform to the layout of the latest
* added the "new since 0.49-990728" section * commented translator.h for the english language
* 1999/09: corrected some small typos in the "new since 0.49-990425" section
* added the "new since 0.49-990728" section
* *
* Permission to use, copy, modify, and distribute this software and its * Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby * documentation under the terms of the GNU General Public License is hereby
...@@ -91,7 +93,7 @@ class TranslatorItalian : public Translator ...@@ -91,7 +93,7 @@ class TranslatorItalian : public Translator
*/ */
QCString trGeneratedAutomatically(const char *s) QCString trGeneratedAutomatically(const char *s)
{ {
QCString result="Generato automaticamente da Doxygen"; QCString result="Generato automaticamente da Doxygen";
if (s) result+=(QCString)" per "+s; if (s) result+=(QCString)" per "+s;
result+=" a partire dal codice sorgente."; result+=" a partire dal codice sorgente.";
return result; return result;
...@@ -162,8 +164,8 @@ class TranslatorItalian : public Translator ...@@ -162,8 +164,8 @@ class TranslatorItalian : public Translator
/*! This is an introduction to the class hierarchy. */ /*! This is an introduction to the class hierarchy. */
QCString trClassHierarchyDescription() QCString trClassHierarchyDescription()
{ {
return "Questa lista di ereditarietà è ordinata " return "Questa lista di ereditarietà è ordinata "
"approssimativamente, ma non completamente, in ordine alfabetico:"; "approssimativamente, ma non completamente, in ordine alfabetico:";
} }
/*! This is an introduction to the list with all files. */ /*! This is an introduction to the list with all files. */
...@@ -171,7 +173,7 @@ class TranslatorItalian : public Translator ...@@ -171,7 +173,7 @@ class TranslatorItalian : public Translator
{ {
QCString result="Questa è una lista "; QCString result="Questa è una lista ";
if (!extractAll) result+="dei files documentati "; if (!extractAll) result+="dei files documentati ";
else result+="di tutti i files "; else result+="di tutti i files ";
result+="con una loro breve descrizione:"; result+="con una loro breve descrizione:";
return result; return result;
} }
...@@ -186,7 +188,7 @@ class TranslatorItalian : public Translator ...@@ -186,7 +188,7 @@ class TranslatorItalian : public Translator
{ {
QCString result="Questa è una lista "; QCString result="Questa è una lista ";
if (!extractAll) result+="dei membri documentati, "; if (!extractAll) result+="dei membri documentati, ";
else result+="di tutti i membri "; else result+="di tutti i membri ";
result+="con collegamenti "; result+="con collegamenti ";
if (extractAll) result+="alla documentazione della classe di ciascun membro:"; if (extractAll) result+="alla documentazione della classe di ciascun membro:";
else result+="alla documentazione delle classi a cui appartengono:"; else result+="alla documentazione delle classi a cui appartengono:";
...@@ -198,7 +200,7 @@ class TranslatorItalian : public Translator ...@@ -198,7 +200,7 @@ class TranslatorItalian : public Translator
{ {
QCString result="Questa è una lista "; QCString result="Questa è una lista ";
if (!extractAll) result+="dei membri dei files documentati, "; if (!extractAll) result+="dei membri dei files documentati, ";
else result+="di tutti i membri dei files "; else result+="di tutti i membri dei files ";
result+="con collegamenti "; result+="con collegamenti ";
if (extractAll) result+="alla documentazione del file di ciascun membro:"; if (extractAll) result+="alla documentazione del file di ciascun membro:";
else result+="alla documentazione dei files a cui appartengono:"; else result+="alla documentazione dei files a cui appartengono:";
...@@ -476,7 +478,7 @@ class TranslatorItalian : public Translator ...@@ -476,7 +478,7 @@ class TranslatorItalian : public Translator
{ {
QCString result="Questa è la lista "; QCString result="Questa è la lista ";
if (!extractAll) result+="dei namespaces documentati, "; if (!extractAll) result+="dei namespaces documentati, ";
else result+="di tutti i namespaces "; else result+="di tutti i namespaces ";
result+="con una loro breve descrizione:"; result+="con una loro breve descrizione:";
return result; return result;
} }
...@@ -627,7 +629,7 @@ class TranslatorItalian : public Translator ...@@ -627,7 +629,7 @@ class TranslatorItalian : public Translator
{ {
QCString result="Questa è la lista "; QCString result="Questa è la lista ";
if (!extractAll) result+="dei membri dei namespaces documentati, "; if (!extractAll) result+="dei membri dei namespaces documentati, ";
else result+="di tutti i membri dei namespaces "; else result+="di tutti i membri dei namespaces ";
result+="con collegamenti "; result+="con collegamenti ";
if (extractAll) if (extractAll)
result+="alla documentazione del namespace per ciascun membro:"; result+="alla documentazione del namespace per ciascun membro:";
...@@ -679,7 +681,7 @@ class TranslatorItalian : public Translator ...@@ -679,7 +681,7 @@ class TranslatorItalian : public Translator
} }
result+=" è stata generata a partire "; result+=" è stata generata a partire ";
if (single) result+="dal seguente file:"; if (single) result+="dal seguente file:";
else result+="dai seguenti files:"; else result+="dai seguenti files:";
return result; return result;
} }
...@@ -906,21 +908,21 @@ class TranslatorItalian : public Translator ...@@ -906,21 +908,21 @@ class TranslatorItalian : public Translator
"Questa pagina spiega come interpretare i grafi generati da doxygen.<p>\n" "Questa pagina spiega come interpretare i grafi generati da doxygen.<p>\n"
"Considerate l'esempio seguente:\n" "Considerate l'esempio seguente:\n"
"\\code\n" "\\code\n"
"/*! Invisible class because of truncation */\n" "/*! Classe invisibile per troncamento */\n"
"class Invisible { };\n\n" "class Invisible { };\n\n"
"/*! Truncated class, inheritance relation is hidden */\n" "/*! Classe troncata, la relazione di ereditarietà e nascosta */\n"
"class Truncated : public Invisible { };\n\n" "class Truncated : public Invisible { };\n\n"
"/* Class not documented with doxygen comments */\n" "/* Classe non documentata con i commenti speciali di doxygen*/\n"
"class Undocumented { };\n\n" "class Undocumented { };\n\n"
"/*! Class that is inherited using public inheritance */\n" "/*! Classe che utilizza una ereditarietà pubblica */\n"
"class PublicBase : public Truncated { };\n\n" "class PublicBase : public Truncated { };\n\n"
"/*! Class that is inherited using protected inheritance */\n" "/*! Classe che utilizza una ereditarietà protetta*/\n"
"class ProtectedBase { };\n\n" "class ProtectedBase { };\n\n"
"/*! Class that is inherited using private inheritance */\n" "/*! Classe che utilizza una ereditarietà privata*/\n"
"class PrivateBase { };\n\n" "class PrivateBase { };\n\n"
"/*! Class that is used by the Inherited class */\n" "/*! Classe utilizzata dalla classe Inherited */\n"
"class Used { };\n\n" "class Used { };\n\n"
"/*! Super class that inherits a number of other classes */\n" "/*! Classe che eredita da varie classi*/\n"
"class Inherited : public PublicBase,\n" "class Inherited : public PublicBase,\n"
" protected ProtectedBase,\n" " protected ProtectedBase,\n"
" private PrivateBase,\n" " private PrivateBase,\n"
...@@ -970,6 +972,32 @@ class TranslatorItalian : public Translator ...@@ -970,6 +972,32 @@ class TranslatorItalian : public Translator
{ {
return "Lista dei test"; return "Lista dei test";
} }
//////////////////////////////////////////////////////////////////////////
// new since 1.2.1
//////////////////////////////////////////////////////////////////////////
/*! Used as a section header for KDE-2 IDL methods */
virtual QCString trDCOPMethods()
{
return "Metodi DCOP";
}
//////////////////////////////////////////////////////////////////////////
// new since 1.2.2
//////////////////////////////////////////////////////////////////////////
/*! Used as a section header for IDL properties */
virtual QCString trProperties()
{
return "Proprietà";
}
/*! Used as a section header for IDL property documentation */
virtual QCString trPropertyDocumentation()
{
return "Documentazione delle Proprietà";
}
}; };
#endif #endif
...@@ -796,6 +796,31 @@ class TranslatorRussian : public Translator ...@@ -796,6 +796,31 @@ class TranslatorRussian : public Translator
{ {
return " "; return " ";
} }
//////////////////////////////////////////////////////////////////////////
// new since 1.2.1
//////////////////////////////////////////////////////////////////////////
/*! Used as a section header for KDE-2 IDL methods */
virtual QCString trDCOPMethods()
{
return " DCOP";
}
//////////////////////////////////////////////////////////////////////////
// new since 1.2.2
//////////////////////////////////////////////////////////////////////////
/*! Used as a section header for IDL properties */
virtual QCString trProperties()
{
return "";
}
/*! Used as a section header for IDL property documentation */
virtual QCString trPropertyDocumentation()
{
return " ";
}
}; };
......
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