diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2008-09-28 18:54:57 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2008-09-28 18:54:57 (GMT) |
commit | 631bd3426f23c6a69b8a19156b25387ceba007d4 (patch) | |
tree | 49bbfc50150f8734b5b10c2f0ea81182413c8bb7 /src | |
parent | 9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7 (diff) | |
download | Doxygen-631bd3426f23c6a69b8a19156b25387ceba007d4.zip Doxygen-631bd3426f23c6a69b8a19156b25387ceba007d4.tar.gz Doxygen-631bd3426f23c6a69b8a19156b25387ceba007d4.tar.bz2 |
Release-1.5.7
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 2 | ||||
-rw-r--r-- | src/code.l | 118 | ||||
-rw-r--r-- | src/commentcnv.l | 46 | ||||
-rw-r--r-- | src/commentscan.l | 7 | ||||
-rw-r--r-- | src/config.l | 138 | ||||
-rw-r--r-- | src/doxygen.cpp | 172 | ||||
-rw-r--r-- | src/doxygen.css | 1 | ||||
-rw-r--r-- | src/doxygen_css.h | 1 | ||||
-rw-r--r-- | src/filedef.cpp | 13 | ||||
-rw-r--r-- | src/groupdef.cpp | 2 | ||||
-rw-r--r-- | src/htmlgen.cpp | 11 | ||||
-rw-r--r-- | src/htmlgen.h | 2 | ||||
-rw-r--r-- | src/indexlog.cpp | 152 | ||||
-rw-r--r-- | src/indexlog.h | 57 | ||||
-rw-r--r-- | src/latexgen.cpp | 12 | ||||
-rw-r--r-- | src/latexgen.h | 2 | ||||
-rw-r--r-- | src/libdoxygen.pro.in | 13 | ||||
-rw-r--r-- | src/mangen.h | 2 | ||||
-rw-r--r-- | src/memberlist.cpp | 2 | ||||
-rw-r--r-- | src/namespacedef.cpp | 8 | ||||
-rw-r--r-- | src/outputgen.h | 2 | ||||
-rw-r--r-- | src/outputlist.h | 4 | ||||
-rw-r--r-- | src/qhp.cpp | 267 | ||||
-rw-r--r-- | src/qhp.h | 65 | ||||
-rw-r--r-- | src/qhpxmlwriter.cpp | 151 | ||||
-rw-r--r-- | src/qhpxmlwriter.h | 63 | ||||
-rw-r--r-- | src/rtfgen.cpp | 2 | ||||
-rw-r--r-- | src/rtfgen.h | 2 | ||||
-rw-r--r-- | src/util.cpp | 4 | ||||
-rw-r--r-- | src/vhdldocgen.cpp | 108 | ||||
-rw-r--r-- | src/vhdldocgen.h | 24 | ||||
-rw-r--r-- | src/vhdlscanner.l | 175 |
32 files changed, 1319 insertions, 309 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 2362928..910a305 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -3336,7 +3336,7 @@ void ClassDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,co { if (optimizeVhdl) // use specific declarations function { - VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this); + VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0); } else // ise generic declaration function { @@ -1042,64 +1042,70 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, } } -static bool generateClassMemberLink(CodeOutputInterface &ol,ClassDef *mcd,const char *memName) +static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const char *memName) { - if (mcd) + // extract class definition of the return type in order to resolve + // a->b()->c() like call chains + + //printf("type=`%s' args=`%s' class=%s\n", + // xmd->typeString(),xmd->argsString(), + // xmd->getClassDef()->name().data()); + + if (g_exampleBlock) { - MemberDef *xmd = mcd->getMemberByName(memName); - //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",mcd->name().data(),memName,xmd); - if (xmd) + QCString anchor; + anchor.sprintf("a%d",g_anchorCount); + //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(), + // g_exampleFile.data()); + if (xmd->addExample(anchor,g_exampleName,g_exampleFile)) { - // extract class definition of the return type in order to resolve - // a->b()->c() like call chains - - //printf("type=`%s' args=`%s' class=%s\n", - // xmd->typeString(),xmd->argsString(), - // xmd->getClassDef()->name().data()); + ol.writeCodeAnchor(anchor); + g_anchorCount++; + } + } - if (g_exampleBlock) - { - QCString anchor; - anchor.sprintf("a%d",g_anchorCount); - //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(), - // g_exampleFile.data()); - if (xmd->addExample(anchor,g_exampleName,g_exampleFile)) - { - ol.writeCodeAnchor(anchor); - g_anchorCount++; - } - } + ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString())); + //fprintf(stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass); + g_theCallContext.setClass(typeClass); - ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString())); - //fprintf(stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass); - g_theCallContext.setClass(typeClass); + Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? + xmd->getBodyDef() : xmd->getOuterScope(); + if (xmd->getGroupDef()) xd = xmd->getGroupDef(); + if (xd) + { - Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? - xmd->getBodyDef() : xmd->getOuterScope(); - if (xmd->getGroupDef()) xd = xmd->getGroupDef(); - if (xd) - { + //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody); - //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody); + if (xmd->templateMaster()) xmd = xmd->templateMaster(); - if (xmd->templateMaster()) xmd = xmd->templateMaster(); + // add usage reference + if (g_currentDefinition && g_currentMemberDef && + /*xmd!=g_currentMemberDef &&*/ g_insideBody) + { + addDocCrossReference(g_currentMemberDef,xmd); + } - // add usage reference - if (g_currentDefinition && g_currentMemberDef && - /*xmd!=g_currentMemberDef &&*/ g_insideBody) - { - addDocCrossReference(g_currentMemberDef,xmd); - } + // write the actual link + ol.linkableSymbol(g_yyLineNr,xmd->name(),xmd, + g_currentMemberDef ? g_currentMemberDef : g_currentDefinition); + writeMultiLineCodeLink(ol,xmd->getReference(), + xmd->getOutputFileBase(),xmd->anchor(),memName,xmd->briefDescriptionAsTooltip()); + addToSearchIndex(memName); + return TRUE; + } - // write the actual link - ol.linkableSymbol(g_yyLineNr,xmd->name(),xmd, - g_currentMemberDef ? g_currentMemberDef : g_currentDefinition); - writeMultiLineCodeLink(ol,xmd->getReference(), - xmd->getOutputFileBase(),xmd->anchor(),memName,xmd->briefDescriptionAsTooltip()); - addToSearchIndex(memName); - return TRUE; - } + return FALSE; +} +static bool generateClassMemberLink(CodeOutputInterface &ol,ClassDef *mcd,const char *memName) +{ + if (mcd) + { + MemberDef *xmd = mcd->getMemberByName(memName); + //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",mcd->name().data(),memName,xmd); + if (xmd) + { + return generateClassMemberLink(ol,xmd,memName); } } @@ -1209,6 +1215,20 @@ static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName, static void generateFunctionLink(CodeOutputInterface &ol,char *funcName) { + if (g_currentMemberDef && g_currentMemberDef->getClassDef() && + funcName==g_currentMemberDef->localName() && + g_currentMemberDef->getDefLine()==g_yyLineNr && + generateClassMemberLink(ol,g_currentMemberDef,funcName) + ) + { + // special case where funcName is the name of a method that is also + // defined on this line. In this case we can directly link to + // g_currentMemberDef, which is not only faster, but + // in case of overloaded methods, this will make sure that we link to + // the correct method, and thereby get the correct reimplemented relations. + // See also bug 549022. + return; + } //CodeClassDef *ccd=0; ClassDef *ccd=0; QCString locScope=g_classScope; @@ -1672,9 +1692,9 @@ SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID}) SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*"::"{BN}*)+ -KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw") +KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize") KEYWORD ("add"|"asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"set"|"sizeof"|"static"|"struct"|"__super"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|{KEYWORD_OBJC}) -FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while") +FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while"|"@try"|"@catch"|"@finally") TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string") CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast") CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) diff --git a/src/commentcnv.l b/src/commentcnv.l index b772868..9a8d4f3 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -31,6 +31,7 @@ #include "message.h" #include "config.h" #include "doxygen.h" +#include "util.h" #define ADDCHAR(c) g_outBuf->addChar(c) @@ -64,7 +65,7 @@ static bool g_inSpecialComment; static QCString g_aliasString; static int g_blockCount; static int g_lastBlockContext; -static bool g_PythonDocString; +static bool g_pythonDocString; static SrcLangExt g_lang; @@ -123,6 +124,7 @@ static inline void copyToOutput(const char *s,int len) if (s[i]=='\n') { ADDCHAR('\n'); + //fprintf(stderr,"---> skip %d\n",g_lineNr); g_lineNr++; } } @@ -135,7 +137,9 @@ static inline void copyToOutput(const char *s,int len) { switch (s[i]) { - case '\n': g_col=0; g_lineNr++; break; + case '\n': g_col=0; + //fprintf(stderr,"---> copy %d\n",g_lineNr); + g_lineNr++; break; case '\t': g_col+=tabSize-(g_col%tabSize); break; default: g_col++; break; } @@ -271,7 +275,7 @@ void replaceComment(int offset); %% -<Scan>[^"'\/\n\\#\\-]* { /* eat anything that is not " / or \n */ +<Scan>[^"'!\/\n\\#\\-]* { /* eat anything that is not " / or \n */ copyToOutput(yytext,yyleng); } <Scan>"\"\"\""! { /* start of python long comment */ @@ -281,7 +285,18 @@ void replaceComment(int offset); } else { - g_PythonDocString = TRUE; + g_pythonDocString = TRUE; + copyToOutput(yytext,yyleng); + BEGIN(CComment); + } + } +<Scan>"!>" { + if (g_lang!=SrcLangExt_F90) + { + REJECT; + } + else + { copyToOutput(yytext,yyleng); BEGIN(CComment); } @@ -438,7 +453,7 @@ void replaceComment(int offset); copyToOutput(yytext,yyleng); } -<CComment>[^\\@*\n]* { /* anything that is not a '*' or command */ +<CComment>[^\\!@*\n]* { /* anything that is not a '*' or command */ copyToOutput(yytext,yyleng); } <CComment>"*"+[^*/\\@\n]* { /* stars without slashes */ @@ -451,7 +466,7 @@ void replaceComment(int offset); } else { - g_PythonDocString = FALSE; + g_pythonDocString = FALSE; copyToOutput(yytext,yyleng); BEGIN(Scan); } @@ -471,7 +486,7 @@ void replaceComment(int offset); } } <CComment>"\n"/[ \t]*[^#] { /* end of Python comment */ - if (g_lang!=SrcLangExt_Python || g_PythonDocString) + if (g_lang!=SrcLangExt_Python || g_pythonDocString) { REJECT; } @@ -492,6 +507,17 @@ void replaceComment(int offset); BEGIN(Scan); } } +<CComment>"\n"/[ \t]*[^!] { /* end of Fortran comment */ + if (g_lang!=SrcLangExt_F90) + { + REJECT; + } + else + { + copyToOutput(yytext,yyleng); + BEGIN(Scan); + } + } <CComment>. { copyToOutput(yytext,yyleng); } @@ -582,7 +608,7 @@ void replaceComment(int offset); BEGIN(g_condCtx); } <CondLine>[ \t]* -<CComment,ReadLine>[\\@]"cond"[ \t\r]*\n | +<CComment,ReadLine>[\\@]"cond"[ \t\r]*/\n | <CondLine>. { // forgot section id? if (YY_START!=CondLine) g_condCtx=YY_START; bool oldSkip=g_skip; @@ -678,8 +704,8 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) g_skip = FALSE; g_fileName = fileName; g_lang = getLanguageFromFileName(fileName); - g_PythonDocString = FALSE; - g_lineNr = 0; + g_pythonDocString = FALSE; + g_lineNr = 1; g_condStack.clear(); g_condStack.setAutoDelete(TRUE); BEGIN(Scan); diff --git a/src/commentscan.l b/src/commentscan.l index 1500f49..8c8aa2e 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -207,7 +207,7 @@ static DocCmdMap docCmdMap[] = { "author", 0, TRUE }, { "authors", 0, TRUE }, { "copydoc", 0, TRUE }, - { "copybrief", 0, TRUE }, + { "copybrief", 0, FALSE }, { "copydetails", 0, TRUE }, { "date", 0, TRUE }, { "dotfile", 0, TRUE }, @@ -974,6 +974,11 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <Comment>{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment formulaText="\\begin"; formulaEnv=&yytext[2]; + if (formulaEnv.at(formulaEnv.length()-1)=='{') + { + // remove trailing open brace + formulaEnv=formulaEnv.left(formulaEnv.length()-1); + } formulaText+=formulaEnv; formulaNewLines=0; BEGIN(ReadFormulaLong); diff --git a/src/config.l b/src/config.l index 6790c76..2023417 100644 --- a/src/config.l +++ b/src/config.l @@ -1260,13 +1260,51 @@ void Config::check() config_err("Warning: No output formats selected! Set at least one of the main GENERATE_* options to YES.\n"); } - // you can't generate HTMLHELP without HTML enabled! + // check HTMLHELP creation requirements if (!Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP")) { config_err("Warning: GENERATE_HTMLHELP=YES requires GENERATE_HTML=YES.\n"); } + // check QHP creation requirements + if (Config_getBool("GENERATE_QHP")) + { + if (!Config_getBool("GENERATE_HTML")) + { + config_err("Warning: GENERATE_QHP=YES requires GENERATE_HTML=YES.\n"); + } + + if (Config_getString("QHP_NAMESPACE").isEmpty()) + { + config_err("Warning: GENERATE_QHP=YES requires QHP_NAMESPACE to be set.\n"); + } + + if (Config_getString("QHP_VIRTUAL_FOLDER").isEmpty()) + { + config_err("Warning: GENERATE_QHP=YES requires QHP_VIRTUAL_FOLDER to be set.\n"); + } + } + + // check QCH creation requirements + if (!Config_getString("QHG_LOCATION").isEmpty() && + !Config_getBool("GENERATE_QHP")) + { + config_err("Warning: Specifying QHG_LOCATION requires GENERATE_QHP=YES.\n"); + } + if (!Config_getString("QCH_FILE").isEmpty() && + Config_getString("QHG_LOCATION").isEmpty()) + { + config_err("Warning: Specifying QCH_FILE requires QHG_LOCATION to be set.\n"); + } + + // check INDEXLOG creation requirements + if (!Config_getBool("GENERATE_HTML") && + Config_getBool("GENERATE_INDEXLOG")) + { + config_err("Warning: GENERATE_INDEXLOG=YES requires GENERATE_HTML=YES.\n"); + } + if (Config_getBool("HAVE_DOT")) { QCString curFontPath = Config_getString("DOT_FONTPATH"); @@ -2371,14 +2409,20 @@ void Config::create() ); cb->addDependency("GENERATE_HTML"); cb = addBool( - "GENERATE_HTMLHELP", - "If the GENERATE_HTMLHELP tag is set to YES, additional index files \n" - "will be generated that can be used as input for tools like the \n" - "Microsoft HTML help workshop to generate a compiled HTML help file (.chm) \n" - "of the generated HTML documentation. \n", + "HTML_DYNAMIC_SECTIONS", + "If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n" + "documentation will contain sections that can be hidden and shown after the \n" + "page has loaded. For this to work a browser that supports \n" + "JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox \n" + "Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). \n", FALSE ); cb->addDependency("GENERATE_HTML"); + + ///////////////////////////////////////////////////////// + // Docsets ////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + cb = addBool( "GENERATE_DOCSET", "If the GENERATE_DOCSET tag is set to YES, additional index files \n" "will be generated that can be used as input for Apple's Xcode 3 \n" @@ -2412,13 +2456,16 @@ void Config::create() cs->setDefaultValue("org.doxygen.Project"); cs->addDependency("GENERATE_DOCSET"); + ///////////////////////////////////////////////////////// + // HTMLHELP ///////////////////////////////////////////// + ///////////////////////////////////////////////////////// + cb = addBool( - "HTML_DYNAMIC_SECTIONS", - "If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n" - "documentation will contain sections that can be hidden and shown after the \n" - "page has loaded. For this to work a browser that supports \n" - "JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox \n" - "Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). \n", + "GENERATE_HTMLHELP", + "If the GENERATE_HTMLHELP tag is set to YES, additional index files \n" + "will be generated that can be used as input for tools like the \n" + "Microsoft HTML help workshop to generate a compiled HTML help file (.chm) \n" + "of the generated HTML documentation. \n", FALSE ); cb->addDependency("GENERATE_HTML"); @@ -2440,6 +2487,7 @@ void Config::create() ); cs->setWidgetType(ConfigString::File); cs->addDependency("GENERATE_HTML"); +#if 0 cs = addString( "QTHELP_FILE", "If the GENERATE_HTMLHELP tag is set to YES, the QTHELP_FILE tag can \n" @@ -2465,6 +2513,10 @@ void Config::create() ); cs->setWidgetType(ConfigString::File); cs->addDependency("GENERATE_HTML"); +#endif + addObsolete("QTHELP_FILE"); + addObsolete("QTHELP_CONFIG"); + addObsolete("DOXYGEN2QTHELP_LOC"); cb = addBool( "GENERATE_CHI", "If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \n" @@ -2495,6 +2547,58 @@ void Config::create() FALSE ); cb->addDependency("GENERATE_HTML"); + + ///////////////////////////////////////////////////////// + // QT HELP ////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + cb = addBool( + "GENERATE_QHP", + "If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER \n" + "are set, an additional index file will be generated that can be used as input for \n" + "Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated \n" + "HTML documentation. \n", + FALSE + ); + cb->addDependency("GENERATE_HTML"); + cs = addString( + "QCH_FILE", + "If the QHG_LOCATION tag is specified, the QCH_FILE tag can \n" + "be used to specify the file name of the resulting .qch file. \n" + "The path specified is relative to the HTML output folder. \n" + ); + cs->setWidgetType(ConfigString::File); + cs->addDependency("GENERATE_QHP"); + cs = addString( + "QHP_NAMESPACE", + "The QHP_NAMESPACE tag specifies the namespace to use when generating \n" + "Qt Help Project output. For more information please see \n" + "<a href=\"http://doc.trolltech.com/qthelpproject.html#namespace\">Qt Help Project / Namespace</a>. \n" + ); + cs->setDefaultValue("org.doxygen.Project"); + cs->addDependency("GENERATE_QHP"); + cs = addString( + "QHP_VIRTUAL_FOLDER", + "The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating \n" + "Qt Help Project output. For more information please see \n" + "<a href=\"http://doc.trolltech.com/qthelpproject.html#virtual-folders\">Qt Help Project / Virtual Folders</a>. \n" + ); + cs->setDefaultValue("doc"); + cs->addDependency("GENERATE_QHP"); + cs = addString( + "QHG_LOCATION", + "If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can \n" + "be used to specify the location of Qt's qhelpgenerator. \n" + "If non-empty doxygen will try to run qhelpgenerator on the generated \n" + ".qhp file .\n" + ); + cs->setWidgetType(ConfigString::File); + cs->addDependency("GENERATE_QHP"); + + ///////////////////////////////////////////////////////// + // MISC ///////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + cb = addBool( "DISABLE_INDEX", "The DISABLE_INDEX tag can be used to turn on/off the condensed index at \n" @@ -2551,6 +2655,16 @@ void Config::create() 8,50,10 ); ci->addDependency("GENERATE_HTML"); +#if 0 + cb = addBool( + "GENERATE_INDEXLOG", + "If the GENERATE_INDEXLOG tag is set to YES, an additional log file \n" + "will be generated that can be used to create new index formats using XSLT \n" + "instead of writing C++ code. \n", + FALSE + ); + cb->addDependency("GENERATE_HTML"); +#endif //----------------------------------------------------------------------------------------------- addInfo( "LaTeX","configuration options related to the LaTeX output"); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index e8a045f..ee72020 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -53,6 +53,8 @@ #include "language.h" #include "debug.h" #include "htmlhelp.h" +#include "qhp.h" +#include "indexlog.h" #include "ftvhelp.h" #include "defargs.h" #include "rtfgen.h" @@ -1311,8 +1313,10 @@ static void resolveClassNestingRelations() /// create the scope artificially // anyway, so we can at least relate scopes properly. Definition *d = buildScopeFromQualifiedName(name,name.contains("::")); - if (d!=cd) // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; } + if (d!=cd && !cd->getDefFileName().isEmpty()) + // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; } // for this case doxygen assumes the exitance of a namespace N::N in which C is to be found! + // also avoid warning for stuff imported via a tagfile. { d->addInnerCompound(cd); cd->setOuterScope(d); @@ -8042,11 +8046,13 @@ static void generateNamespaceDocs() // for each namespace... for (;(nd=nli.current());++nli) { + if (nd->isLinkableInProject()) { msg("Generating docs for namespace %s\n",nd->name().data()); nd->writeDocumentation(*outputList); } + // for each class in the namespace... ClassSDict::Iterator cli(*nd->getClassSDict()); for ( ; cli.current() ; ++cli ) @@ -9409,6 +9415,47 @@ static void exitDoxygen() } } +static QCString createOutputDirectory(const QCString &baseDirName, + const char *formatDirOption, + const char *defaultDirName) +{ + // Note the & on the next line, we modify the formatDirOption! + QCString &formatDirName = Config_getString(formatDirOption); + if (formatDirName.isEmpty()) + { + formatDirName = baseDirName + defaultDirName; + } + else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':')) + { + formatDirName.prepend(baseDirName+'/'); + } + QDir formatDir(formatDirName); + if (!formatDir.exists() && !formatDir.mkdir(formatDirName)) + { + err("Could not create output directory %s\n", formatDirName.data()); + cleanUpDoxygen(); + exit(1); + } + return formatDirName; +} + +static QCString getQchFileName() +{ + QCString const & qchFile = Config_getString("QCH_FILE"); + if (!qchFile.isEmpty()) + { + return qchFile; + } + + QCString const & projectName = Config_getString("PROJECT_NAME"); + QCString const & versionText = Config_getString("PROJECT_NUMBER"); + + return QCString("../qch/") + + (projectName.isEmpty() ? QCString("index") : projectName) + + (versionText.isEmpty() ? QCString("") : QCString("-") + versionText) + + QCString(".qch"); +} + void parseInput() { atexit(exitDoxygen); @@ -9529,95 +9576,31 @@ void parseInput() * Check/create output directorties * **************************************************************************/ - QCString &htmlOutput = Config_getString("HTML_OUTPUT"); + QCString htmlOutput; bool &generateHtml = Config_getBool("GENERATE_HTML"); - if (htmlOutput.isEmpty() && generateHtml) - { - htmlOutput=outputDirectory+"/html"; - } - else if (htmlOutput && htmlOutput[0]!='/' && htmlOutput[1]!=':') - { - htmlOutput.prepend(outputDirectory+'/'); - } - QDir htmlDir(htmlOutput); - if (generateHtml && !htmlDir.exists() && !htmlDir.mkdir(htmlOutput)) - { - err("Could not create output directory %s\n",htmlOutput.data()); - cleanUpDoxygen(); - exit(1); - } + if (generateHtml) + htmlOutput = createOutputDirectory(outputDirectory,"HTML_OUTPUT","/html"); - QCString &xmlOutput = Config_getString("XML_OUTPUT"); + QCString xmlOutput; bool &generateXml = Config_getBool("GENERATE_XML"); - if (xmlOutput.isEmpty() && generateXml) - { - xmlOutput=outputDirectory+"/xml"; - } - else if (xmlOutput && xmlOutput[0]!='/' && xmlOutput[1]!=':') - { - xmlOutput.prepend(outputDirectory+'/'); - } - QDir xmlDir(xmlOutput); - if (generateXml && !xmlDir.exists() && !xmlDir.mkdir(xmlOutput)) - { - err("Could not create output directory %s\n",xmlOutput.data()); - cleanUpDoxygen(); - exit(1); - } - - QCString &latexOutput = Config_getString("LATEX_OUTPUT"); + if (generateXml) + xmlOutput = createOutputDirectory(outputDirectory,"XML_OUTPUT","/xml"); + + QCString latexOutput; bool &generateLatex = Config_getBool("GENERATE_LATEX"); - if (latexOutput.isEmpty() && generateLatex) - { - latexOutput=outputDirectory+"/latex"; - } - else if (latexOutput && latexOutput[0]!='/' && latexOutput[1]!=':') - { - latexOutput.prepend(outputDirectory+'/'); - } - QDir latexDir(latexOutput); - if (generateLatex && !latexDir.exists() && !latexDir.mkdir(latexOutput)) - { - err("Could not create output directory %s\n",latexOutput.data()); - cleanUpDoxygen(); - exit(1); - } - - QCString &rtfOutput = Config_getString("RTF_OUTPUT"); + if (generateLatex) + latexOutput = createOutputDirectory(outputDirectory,"LATEX_OUTPUT","/latex"); + + QCString rtfOutput; bool &generateRtf = Config_getBool("GENERATE_RTF"); - if (rtfOutput.isEmpty() && generateRtf) - { - rtfOutput=outputDirectory+"/rtf"; - } - else if (rtfOutput && rtfOutput[0]!='/' && rtfOutput[1]!=':') - { - rtfOutput.prepend(outputDirectory+'/'); - } - QDir rtfDir(rtfOutput); - if (generateRtf && !rtfDir.exists() && !rtfDir.mkdir(rtfOutput)) - { - err("Could not create output directory %s\n",rtfOutput.data()); - cleanUpDoxygen(); - exit(1); - } + if (generateRtf) + rtfOutput = createOutputDirectory(outputDirectory,"RTF_OUTPUT","/rtf"); - QCString &manOutput = Config_getString("MAN_OUTPUT"); + QCString manOutput; bool &generateMan = Config_getBool("GENERATE_MAN"); - if (manOutput.isEmpty() && generateMan) - { - manOutput=outputDirectory+"/man"; - } - else if (manOutput && manOutput[0]!='/' && manOutput[1]!=':') - { - manOutput.prepend(outputDirectory+'/'); - } - QDir manDir(manOutput); - if (generateMan && !manDir.exists() && !manDir.mkdir(manOutput)) - { - err("Could not create output directory %s\n",manOutput.data()); - cleanUpDoxygen(); - exit(1); - } + if (generateMan) + manOutput = createOutputDirectory(outputDirectory,"MAN_OUTPUT","/man"); + /************************************************************************** * Handle layout file * **************************************************************************/ @@ -10060,6 +10043,10 @@ void generateOutput() outputList->add(new HtmlGenerator); HtmlGenerator::init(); if (Config_getBool("GENERATE_HTMLHELP")) Doxygen::indexList.addIndex(new HtmlHelp); + if (Config_getBool("GENERATE_QHP")) Doxygen::indexList.addIndex(new Qhp); +#if 0 + if (Config_getBool("GENERATE_INDEXLOG")) Doxygen::indexList.addIndex(new IndexLog); +#endif if (usingTreeIndex()) Doxygen::indexList.addIndex(new FTVHelp); if (Config_getBool("GENERATE_DOCSET")) Doxygen::indexList.addIndex(new DocSets); Doxygen::indexList.initialize(); @@ -10274,6 +10261,7 @@ void generateOutput() } QDir::setCurrent(oldDir); } +#if 0 if ( Config_getBool("GENERATE_HTMLHELP") && !Config_getString("DOXYGEN2QTHELP_LOC").isEmpty() && !Config_getString("QTHELP_CONFIG").isEmpty()) @@ -10292,6 +10280,24 @@ void generateOutput() } QDir::setCurrent(oldDir); } +#endif + if ( Config_getBool("GENERATE_HTML") && + Config_getBool("GENERATE_QHP") && + !Config_getString("QHG_LOCATION").isEmpty()) + { + msg("Running qhelpgenerator...\n"); + QCString const qhpFileName = Qhp::getQhpFileName(); + QCString const qchFileName = getQchFileName(); + + QCString const args = QCString().sprintf("%s -o %s", qhpFileName.data(), qchFileName.data()); + QString const oldDir = QDir::currentDirPath(); + QDir::setCurrent(Config_getString("HTML_OUTPUT")); + if (portable_system(Config_getString("QHG_LOCATION"), args.data(), FALSE)) + { + err("Error: failed to run qhelpgenerator on index.qhp\n"); + } + QDir::setCurrent(oldDir); + } if (Config_getBool("SEARCHENGINE")) { msg("Generating search index\n"); diff --git a/src/doxygen.css b/src/doxygen.css index c8356a2..9c847c6 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -136,7 +136,6 @@ td.indexkey { td.indexvalue { background-color: #e8eef2; -// font-style: italic; border: 1px solid #CCCCCC; padding: 2px 10px; margin: 2px 0px; diff --git a/src/doxygen_css.h b/src/doxygen_css.h index d9d381e..2507096 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -136,7 +136,6 @@ "\n" "td.indexvalue {\n" " background-color: #e8eef2;\n" -"// font-style: italic;\n" " border: 1px solid #CCCCCC;\n" " padding: 2px 10px;\n" " margin: 2px 0px;\n" diff --git a/src/filedef.cpp b/src/filedef.cpp index e323dd5..d17f796 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -1553,8 +1553,19 @@ MemberList *FileDef::getMemberList(MemberList::ListType lt) const void FileDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title) { + static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); MemberList * ml = getMemberList(lt); - if (ml) ml->writeDeclarations(ol,0,0,this,0,title,0); + if (ml) + { + if (optVhdl) // use specific declarations function + { + VhdlDocGen::writeVhdlDeclarations(ml,ol,0,0,this); + } + else + { + ml->writeDeclarations(ol,0,0,this,0,title,0); + } + } } void FileDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title) diff --git a/src/groupdef.cpp b/src/groupdef.cpp index b0fd61d..746c6a7 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -1365,7 +1365,7 @@ void GroupDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,co MemberList * ml = getMemberList(lt); if (optimizeVhdl && ml) { - VhdlDocGen::writeVhdlDeclarations(ml,ol,this,0); + VhdlDocGen::writeVhdlDeclarations(ml,ol,this,0,0); return; } if (ml) diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 500651b..5e4437a 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -2400,4 +2400,15 @@ void HtmlGenerator::endConstraintList() t << "</div>" << endl; } +void HtmlGenerator::lineBreak(const char *style) +{ + if (style) + { + t << "<br class=\"" << style << "\">" << endl; + } + else + { + t << "<br>" << endl; + } +} diff --git a/src/htmlgen.h b/src/htmlgen.h index 9e012c8..32ef613 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -138,7 +138,7 @@ class HtmlGenerator : public OutputGenerator void endDescription() { t << endl << "</dl>" << endl; } void startDescItem() { t << "<dt>"; } void endDescItem() { t << "<dd>"; } - void lineBreak() { t << "<br>" << endl; } + void lineBreak(const char *style); void writeChar(char c); void startMemberDoc(const char *,const char *,const char *,const char *); void endMemberDoc(bool); diff --git a/src/indexlog.cpp b/src/indexlog.cpp new file mode 100644 index 0000000..5fb67f5 --- /dev/null +++ b/src/indexlog.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#include "indexlog.h" +#include "message.h" +#include "config.h" + +#include <qstring.h> +#include <qfile.h> + + +IndexLog::IndexLog() +{ +} + +IndexLog::~IndexLog() +{ +} + +void IndexLog::initialize() +{ + char const * const attributes[] = + { "xmlns", + "http://doxygen.org/xmlns/indexlog/1/0/", + NULL + }; + m_out.open("log", attributes); + + openMethodCall("initialize"); + closeMethodCall(); +} + +void IndexLog::finalize() +{ + openMethodCall("finalize"); + closeMethodCall(); + m_out.close("log"); + QCString fileName = Config_getString("HTML_OUTPUT")+"/index.log.xml"; + QFile file(fileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n", fileName.data()); + exit(1); + } + m_out.dumpTo(file); + file.flush(); + file.close(); +} + +void IndexLog::incContentsDepth() +{ + openMethodCall("incContentsDepth"); + closeMethodCall(); +} + +void IndexLog::decContentsDepth() +{ + openMethodCall("decContentsDepth"); + closeMethodCall(); +} + +void IndexLog::addContentsItem(bool isDir, char const * name, + char const * ref, char const * file, + char const * anchor) +{ + openMethodCall("addContentsItem"); + addBoolParameter("isDir", isDir); + addStringParameter("name", name); + addStringParameter("ref", ref); + addStringParameter("file", file); + addStringParameter("anchor", anchor); + closeMethodCall(); +} + +void IndexLog::addIndexItem(char const * level1, char const * level2, + char const * contRef, char const * memRef, + char const * anchor, const MemberDef * md) +{ + openMethodCall("addIndexItem"); + addStringParameter("level1", level1); + addStringParameter("level2", level2); + addStringParameter("contRef", contRef); + addStringParameter("memRef", memRef); + addStringParameter("anchor", anchor); + addMemberDefParameter("md", md); + closeMethodCall(); +} + +void IndexLog::addIndexFile(char const * name) +{ + openMethodCall("addIndexFile"); + addStringParameter("name", name); + closeMethodCall(); +} + +void IndexLog::openMethodCall(char const * methodName) +{ + m_out.setCompressionEnabled(true); + m_out.open("call"); + m_out.openCloseContent("method", methodName); +} + +void IndexLog::addPrimitiveParameter(char const * parameterName, + char const * value) +{ + m_out.open("param"); + m_out.openCloseContent("name", parameterName); + if (value != NULL) + { + m_out.openCloseContent("value", value); + } + m_out.close("param"); +} + +void IndexLog::addBoolParameter(char const * parameterName, bool value) +{ + addPrimitiveParameter(parameterName, value ? "true" : "false"); +} + +void IndexLog::addStringParameter(char const * parameterName, + char const * value) +{ + addPrimitiveParameter(parameterName, value); +} + +void IndexLog::addMemberDefParameter(char const * parameterName, + const MemberDef * /*value*/) +{ + m_out.open("param"); + m_out.openCloseContent("name", parameterName); + m_out.close("param"); +} + +void IndexLog::closeMethodCall() +{ + m_out.setCompressionEnabled(false); + m_out.close("call"); +} + diff --git a/src/indexlog.h b/src/indexlog.h new file mode 100644 index 0000000..6875971 --- /dev/null +++ b/src/indexlog.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#ifndef INDEXLOG_H +#define INDEXLOG_H + +#include "index.h" +#include "qhpxmlwriter.h" + +class IndexLog : public IndexIntf +{ + public: + IndexLog(); + ~IndexLog(); + + // BEGIN IndexIntf + void initialize(); + void finalize(); + void incContentsDepth(); + void decContentsDepth(); + void addContentsItem(bool isDir, const char *name, const char *ref, + const char *file, const char *anchor); + void addIndexItem(const char *level1, const char *level2, + const char *contRef, const char *memRef, + const char *anchor, const MemberDef * md); + void addIndexFile(const char *name); + // END IndexIntf + + private: + void openMethodCall(char const * methodName); + void addPrimitiveParameter(char const * parameterName, + char const * value); + void addBoolParameter(char const * parameterName, bool value); + void addStringParameter(char const * parameterName, + char const * value); + void addMemberDefParameter(char const * parameterName, + const MemberDef * value); + void closeMethodCall(); + + QhpXmlWriter m_out; +}; + +#endif // INDEXLOG_H + diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 7dd48f9..8a70405 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -1145,9 +1145,9 @@ void LatexGenerator::startMemberDoc(const char *clname, // escapeMakeIndexChars(this,t,memname); // t << "]"; //} - t << "["; + t << "[{"; escapeMakeIndexChars(title); - t << "]"; + t << "}]"; t << "{\\setlength{\\rightskip}{0pt plus 5cm}"; disableLinks=TRUE; } @@ -1661,8 +1661,8 @@ void LatexGenerator::escapeLabelName(const char *s) switch (c) { case '%': t << "\\%"; break; - case '|': t << "\\tt{\"|}"; break; - case '!': t << "\"!"; break; + //case '|': t << "\\tt{\"|}"; break; + //case '!': t << "\"!"; break; default: str[0]=c; docify(str); break; } } @@ -1678,10 +1678,10 @@ void LatexGenerator::escapeMakeIndexChars(const char *s) { switch (c) { - case '!': t << "\"!"; break; + //case '!': t << "\"!"; break; case '"': t << "\"\""; break; case '@': t << "\"@"; break; - case '|': t << "\\tt{\"|}"; break; + //case '|': t << "\\tt{\"|}"; break; case '[': t << "["; break; case ']': t << "]"; break; default: str[0]=c; docify(str); break; diff --git a/src/latexgen.h b/src/latexgen.h index b5fad84..a30f5bf 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -133,7 +133,7 @@ class LatexGenerator : public OutputGenerator void endDescription(); void startDescItem(); void endDescItem(); - void lineBreak() { t << "\\par\n"; } + void lineBreak(const char *style=0) { (void)style; t << "\\par\n"; } void startMemberDoc(const char *,const char *,const char *,const char *); void endMemberDoc(bool); void startDoxyAnchor(const char *,const char *,const char *,const char *,const char *); diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index c32b29f..2fb672e 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -54,6 +54,7 @@ HEADERS = bufstr.h \ htmldocvisitor.h \ htmlgen.h \ htmlhelp.h \ + indexlog.h \ image.h \ index.h \ index_xsd.h \ @@ -87,6 +88,8 @@ HEADERS = bufstr.h \ pyscanner.h \ fortrancode.h \ fortranscanner.h \ + qhp.h \ + qhpxmlwriter.h \ qtbc.h \ reflist.h \ rtfdocvisitor.h \ @@ -143,6 +146,7 @@ HEADERS = bufstr.h \ vhdlscanner.h \ xmldocvisitor.h \ xmlgen.h + SOURCES = ce_lex.cpp \ ce_parse.cpp \ classdef.cpp \ @@ -150,6 +154,7 @@ SOURCES = ce_lex.cpp \ cmdmapper.cpp \ code.cpp \ commentcnv.cpp \ + commentscan.cpp \ cppvalue.cpp \ debug.cpp \ defgen.cpp \ @@ -169,11 +174,14 @@ SOURCES = ce_lex.cpp \ filename.cpp \ formula.cpp \ ftvhelp.cpp \ + fortrancode.cpp \ + fortranscanner.cpp \ groupdef.cpp \ htags.cpp \ htmldocvisitor.cpp \ htmlgen.cpp \ htmlhelp.cpp \ + indexlog.cpp \ image.cpp \ index.cpp \ instdox.cpp \ @@ -201,8 +209,8 @@ SOURCES = ce_lex.cpp \ pre.cpp \ pycode.cpp \ pyscanner.cpp \ - fortrancode.cpp \ - fortranscanner.cpp \ + qhp.cpp \ + qhpxmlwriter.cpp \ reflist.cpp \ rtfdocvisitor.cpp \ rtfgen.cpp \ @@ -220,7 +228,6 @@ SOURCES = ce_lex.cpp \ vhdlscanner.cpp \ xmldocvisitor.cpp \ xmlgen.cpp \ - commentscan.cpp win32:TMAKE_CXXFLAGS += -DQT_NODLL win32-msvc:TMAKE_CXXFLAGS += -Zm200 diff --git a/src/mangen.h b/src/mangen.h index 3b0f85c..8dbe7b8 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -129,7 +129,7 @@ class ManGenerator : public OutputGenerator void endDescription() {} void startDescItem(); void endDescItem(); - void lineBreak() { t << "\n.br" << endl; } + void lineBreak(const char *) { t << "\n.br" << endl; } void writeChar(char c); void startMemberDoc(const char *,const char *,const char *,const char *); void endMemberDoc(bool); diff --git a/src/memberlist.cpp b/src/memberlist.cpp index e2ffedb..ff3a7a1 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -353,7 +353,7 @@ void MemberList::writeDeclarations(OutputList &ol, // 2. This might need to be repeated below for memberGroupLists if (optimizeVhdl) // use specific declarations function { - VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd); + VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd,0); } else { diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index a396257..ceebc6d 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -397,13 +397,14 @@ void NamespaceDef::writeDocumentation(OutputList &ol) Doxygen::searchIndex->addWord(localName(),TRUE); } - if (!Config_getString("GENERATE_TAGFILE").isEmpty()) + bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty(); + if (generateTagFile) { Doxygen::tagFile << " <compound kind=\"namespace\">" << endl; Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; } - + //---------------------------------------- start flexible part ------------------------------- #define NEW_LAYOUT @@ -552,8 +553,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) endFile(ol); - - if (!Config_getString("GENERATE_TAGFILE").isEmpty()) + if (generateTagFile) { writeDocAnchorsToTagFile(); Doxygen::tagFile << " </compound>" << endl; diff --git a/src/outputgen.h b/src/outputgen.h index 9dbe5dc..99248f0 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -235,7 +235,7 @@ class BaseOutputDocInterface : public CodeOutputInterface virtual void startSection(const char *,const char *,SectionInfo::SectionType) = 0; virtual void endSection(const char *,SectionInfo::SectionType) = 0; - virtual void lineBreak() = 0; + virtual void lineBreak(const char *style) = 0; virtual void addIndexItem(const char *s1,const char *s2) = 0; virtual void writeNonBreakableSpace(int) = 0; diff --git a/src/outputlist.h b/src/outputlist.h index e0a1553..6187c7d 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -267,8 +267,8 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startSmall); } void endSmall() { forall(&OutputGenerator::endSmall); } - void lineBreak() - { forall(&OutputGenerator::lineBreak); } + void lineBreak(const char *style=0) + { forall(&OutputGenerator::lineBreak,style); } void startBold() { forall(&OutputGenerator::startBold); } void endBold() diff --git a/src/qhp.cpp b/src/qhp.cpp new file mode 100644 index 0000000..3adbaaa --- /dev/null +++ b/src/qhp.cpp @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#include "qhp.h" +#include "qhpxmlwriter.h" +#include "message.h" +#include "config.h" + +#include <string.h> + +static QCString makeFileName(char const * withoutExtension) +{ + if (!withoutExtension) return QCString(); + return QCString(withoutExtension)+".html"; +} + +static QCString makeRef(char const * withoutExtension, char const * anchor) +{ + if (!withoutExtension) return QCString(); + QCString result = makeFileName(withoutExtension); + if (!anchor) return result; + return result+"#"+anchor; +} + +Qhp::Qhp() : m_prevSectionLevel(0), m_sectionLevel(0) +{ + m_toc.setIndentLevel(0); + m_doc.setIndentLevel(2); + m_index.setIndentLevel(2); + m_files.setIndentLevel(2); +} + +Qhp::~Qhp() +{ + clearPrevSection(); +} + +void Qhp::initialize() +{ + /* + <QtHelpProject version="1.0"> + <namespace>mycompany.com.myapplication.1_0</namespace> + <virtualFolder>doc</virtualFolder> + <customFilter name="My Application 1.0"> + <filterAttribute>myapp</filterAttribute> + <filterAttribute>1.0</filterAttribute> + </customFilter> + <filterSection> + <filterAttribute>myapp</filterAttribute> + <filterAttribute>1.0</filterAttribute> + .. + */ + QCString nameSpace = Config_getString("QHP_NAMESPACE"); + QCString virtualFolder = Config_getString("QHP_VIRTUAL_FOLDER"); + QCString projectTitle = getFullProjectName(); + QCString filterIdent = projectTitle; + QCString filterAttribute = projectTitle; + + char const * rootAttributes[] = + { "version", "1.0", 0 }; + char const * customFilterAttributes[] = + { "name", filterIdent, 0 }; + + m_doc.open("QtHelpProject", rootAttributes); + m_doc.openCloseContent("namespace", nameSpace); + m_doc.openCloseContent("virtualFolder", virtualFolder); + + m_doc.open("customFilter", customFilterAttributes); + m_doc.openCloseContent("filterAttribute", filterAttribute); + m_doc.close("customFilter"); + m_doc.open("filterSection"); + m_doc.openCloseContent("filterAttribute", filterAttribute); + + m_toc.open("toc"); + m_index.open("keywords"); + m_files.open("files"); +} + +void Qhp::finalize() +{ + // Finish TOC + handlePrevSection(); + m_toc.close("toc"); + m_doc.insert(m_toc); + + // Finish index + m_index.close("keywords"); + m_doc.insert(m_index); + + // Finish files + addFile("doxygen.css"); + addFile("doxygen.png"); + addFile("tab_b.gif"); + addFile("tab_l.gif"); + addFile("tab_r.gif"); + addFile("tabs.css"); + m_files.close("files"); + m_doc.insert(m_files); + + m_doc.close("filterSection"); + m_doc.close("QtHelpProject"); + + QCString fileName = Config_getString("HTML_OUTPUT") + "/" + getQhpFileName(); + QFile file(fileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n", fileName.data()); + exit(1); + } + m_doc.dumpTo(file); +} + +void Qhp::incContentsDepth() +{ + m_sectionLevel++; +} + +void Qhp::decContentsDepth() +{ + if (m_sectionLevel <= 0) + { + return; + } + m_sectionLevel--; +} + +void Qhp::addContentsItem(bool /*isDir*/, char const * name, + char const * /*ref*/, char const * file, + char const * /*anchor*/) +{ + // Backup difference before modification + int diff = m_prevSectionLevel - m_sectionLevel; + + handlePrevSection(); + setPrevSection(name, file, m_sectionLevel); + + // Close sections as needed + for (; diff > 0; diff--) + { + m_toc.close("section"); + } +} + +void Qhp::addIndexItem(char const * level1, char const * level2, + char const * contRef, char const * /*memRef*/, + char const * anchor, const MemberDef * /*md*/) +{ + /* + <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/> + */ + QCString ref = makeRef(contRef, anchor); + QCString id(level1); + id += "::"; + id += level2; + char const * attributes[] = + { "name", level2, + "id", id, + "ref", ref, + 0 + }; + m_index.openClose("keyword", attributes); +} + +void +Qhp::addIndexFile(char const * name) +{ + addFile(name); +} + +/*static*/ QCString +Qhp::getQhpFileName() +{ + + return "index.qhp"; +} + +/*static*/ QCString +Qhp::getFullProjectName() +{ + QCString const projectName = Config_getString("PROJECT_NAME"); + QCString const versionText = Config_getString("PROJECT_NUMBER"); + return projectName + (versionText.isEmpty() + ? QCString("") + : QCString(" ") + versionText); +} + +void +Qhp::handlePrevSection() +{ + /* + <toc> + <section title="My Application Manual" ref="index.html"> + <section title="Chapter 1" ref="doc.html#chapter1"/> + <section title="Chapter 2" ref="doc.html#chapter2"/> + <section title="Chapter 3" ref="doc.html#chapter3"/> + </section> + </toc> + */ + + if (m_prevSectionTitle.isNull()) + { + return; + } + + // Replace "Main Page" with <project_name> in TOC + QCString finalTitle; + if (m_prevSectionLevel==0 && m_prevSectionTitle=="Main Page") + { + finalTitle = getFullProjectName(); + } + if (finalTitle.isEmpty()) + { + finalTitle = m_prevSectionTitle; + } + QCString finalRef = makeFileName(m_prevSectionRef); + + char const * const attributes[] = + { "title", finalTitle, + "ref", finalRef, + NULL + }; + + if (m_prevSectionLevel < m_sectionLevel) + { + // Section with children + m_toc.open("section", attributes); + } + else + { + // Section without children + m_toc.openClose("section", attributes); + } + + clearPrevSection(); +} + +void Qhp::setPrevSection(char const * title, char const * ref, int level) +{ + m_prevSectionTitle = title; + m_prevSectionRef = ref; + m_prevSectionLevel = level; +} + +void Qhp::clearPrevSection() +{ + m_prevSectionTitle.resize(0); + m_prevSectionRef.resize(0); + m_prevSectionLevel = m_sectionLevel; +} + +void Qhp::addFile(char const * fileName) +{ + m_files.openCloseContent("file", fileName); +} diff --git a/src/qhp.h b/src/qhp.h new file mode 100644 index 0000000..9310a75 --- /dev/null +++ b/src/qhp.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#ifndef DOXYGEN_QHP_H +#define DOXYGEN_QHP_H + +#include "index.h" +#include "qhpxmlwriter.h" + +class Qhp : public IndexIntf +{ + public: + Qhp(); + ~Qhp(); + + // BEGIN IndexIntf + void initialize(); + void finalize(); + void incContentsDepth(); + void decContentsDepth(); + void addContentsItem(bool isDir, char const * name, char const * ref, + char const * file, char const * anchor); + void addIndexItem(char const * level1, char const * level2, + char const * contRef, char const * memRef, + char const * anchor, const MemberDef * md); + void addIndexFile(char const * name); + // END IndexIntf + + static QCString getQhpFileName(); + + private: + void handlePrevSection(); + void clearPrevSection(); + void setPrevSection(char const * title, char const * ref, int level); + void addFile(char const * fileName); + + static QCString getFullProjectName(); + + QhpXmlWriter m_doc; + QhpXmlWriter m_toc; + QhpXmlWriter m_index; + QhpXmlWriter m_files; + + QCString m_prevSectionTitle; + QCString m_prevSectionRef; + + int m_prevSectionLevel; + int m_sectionLevel; +}; + +#endif // DOXYGEN_QHP_H + diff --git a/src/qhpxmlwriter.cpp b/src/qhpxmlwriter.cpp new file mode 100644 index 0000000..93bb8cd --- /dev/null +++ b/src/qhpxmlwriter.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#include "qhpxmlwriter.h" +#include "util.h" + +#include <qfile.h> + +QhpXmlWriter::QhpXmlWriter() + : m_out(&m_backend), m_indentLevel(0), + m_curLineIndented(false), m_compress(false) +{ +} + +QhpXmlWriter::~QhpXmlWriter() +{ +} + +void QhpXmlWriter::setIndentLevel(int level) +{ + m_indentLevel = level; +} + +void QhpXmlWriter::setCompressionEnabled(bool enabled) +{ + m_compress = enabled; +} + +void QhpXmlWriter::insert(QhpXmlWriter const & source) +{ + m_out << source.m_backend.data(); +} + +void QhpXmlWriter::dumpTo(QFile & file) +{ + file.writeBlock(m_backend.data(), m_backend.length()); +} + +void QhpXmlWriter::open(char const * elementName, + char const * const * attributes) +{ + indent(); + openPure(elementName, attributes); + newLine(); + m_indentLevel++; +} + +void QhpXmlWriter::openClose(char const * elementName, + char const * const * attributes) +{ + indent(); + openClosePure(elementName, attributes); + newLine(); +} + +void QhpXmlWriter::openCloseContent(char const * elementName, + char const * content) +{ + indent(); + openPure(elementName); + m_out << convertToXML(content); + closePure(elementName); + newLine(); +} + +void QhpXmlWriter::close(char const * elementName) +{ + m_indentLevel--; + indent(); + closePure(elementName); + newLine(); +} + +void QhpXmlWriter::indent() +{ + if (m_curLineIndented) + { + return; + } + for (int i = 0; i < m_indentLevel; i++) + { + m_out << " "; + } + m_curLineIndented = true; +} + +void QhpXmlWriter::newLine() +{ + if (!m_compress) + { + m_out << "\n"; + m_curLineIndented = false; + } +} + +void QhpXmlWriter::openPureHelper(char const * elementName, + char const * const * attributes, bool close) +{ + m_out << "<" << elementName; + if (attributes) + { + for (char const * const * walker = attributes; + walker[0]; walker += 2) + { + char const * const key = walker[0]; + char const * const value = walker[1]; + if (!value) + { + continue; + } + m_out << " " << key << "=\"" << convertToXML(value) << "\""; + } + } + + if (close) + { + m_out << " /"; + } + m_out << ">"; +} + +void QhpXmlWriter::openPure(char const * elementName, + char const * const * attributes) +{ + openPureHelper(elementName, attributes, false); +} + +void QhpXmlWriter::openClosePure(char const * elementName, + char const * const * attributes) +{ + openPureHelper(elementName, attributes, true); +} + +void QhpXmlWriter::closePure(char const * elementName) +{ + m_out << "</" << elementName << ">"; +} + diff --git a/src/qhpxmlwriter.h b/src/qhpxmlwriter.h new file mode 100644 index 0000000..33e6152 --- /dev/null +++ b/src/qhpxmlwriter.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 by Sebastian Pipping. + * Copyright (C) 2008 Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + * Sebastian Pipping <sebastian@pipping.org> + */ + +#ifndef QHPXMLWRITER_H +#define QHPXMLWRITER_H + +#include <qstring.h> +#include <qtextstream.h> + +class QFile; + +class QhpXmlWriter +{ + public: + QhpXmlWriter(); + ~QhpXmlWriter(); + + void setIndentLevel(int level); + void setCompressionEnabled(bool enabled); + void insert(QhpXmlWriter const & source); + void dumpTo(QFile & file); + void open(char const * elementName, + char const * const * attributes = 0); + void openClose(char const * elementName, + char const * const * attributes = 0); + void openCloseContent(char const * elementName, char const * content); + void close(char const * elementName); + + static char * dupEscaped(const char * source); + + private: + void indent(); + void newLine(); + void openPureHelper(char const * elementName, + char const * const * attributes, bool close); + void openPure(char const * elementName, + char const * const * attributes = 0); + void openClosePure(char const * elementName, + char const * const * attributes = 0); + void closePure(char const * elementName); + + QString m_backend; + QTextOStream m_out; + int m_indentLevel; + bool m_curLineIndented; + bool m_compress; + +}; + +#endif // QHPXMLWRITER_H diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 9634acc..bd4630a 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -897,7 +897,7 @@ void RTFGenerator::writeStyleInfo(int) { } -void RTFGenerator::lineBreak() +void RTFGenerator::lineBreak(const char *) { DBG_RTF(t << "{\\comment (lineBreak)}" << endl) t << "\\par" << endl; diff --git a/src/rtfgen.h b/src/rtfgen.h index 37d5b95..3c895bf 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -124,7 +124,7 @@ class RTFGenerator : public OutputGenerator void endDescription(); void startDescItem(); void endDescItem(); - void lineBreak(); + void lineBreak(const char *style=0); void startMemberDoc(const char *,const char *,const char *,const char *); void endMemberDoc(bool); void startDoxyAnchor(const char *,const char *,const char *,const char *,const char *); diff --git a/src/util.cpp b/src/util.cpp index 945f48a..2b08e37 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -99,7 +99,7 @@ void TextGeneratorOLImpl::writeBreak() const { m_od.pushGeneratorState(); m_od.disableAllBut(OutputGenerator::Html); - m_od.lineBreak(); + m_od.lineBreak("typebreak"); m_od.popGeneratorState(); } @@ -1642,7 +1642,7 @@ nextChar: //uint rl=result.length(); uint rl=resultPos; if ((rl>0 && (isId(result.at(rl-1)) || result.at(rl-1)=='>')) && - (c!='*' || !findOperator2(s,i)) // avoid splitting operator* and operator->* + ((c!='*' && c!='&') || !findOperator2(s,i)) // avoid splitting operator* and operator->* and operator& ) { ADD_CHAR(' '); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 5535a90..adb479a 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -16,8 +16,7 @@ * Parser for VHDL subset * written by M. Kreis * supports VHDL-87 - * does not support all keywords of VHDL '93 (impure function/shared variables ..) - * and VHDL-AMS + * does not support VHDL-AMS ******************************************************************************/ // global includes @@ -1167,10 +1166,13 @@ QCString VhdlDocGen::trTypeString(int type) case VhdlDocGen::GENERIC: return "Generic"; case VhdlDocGen::DOCUMENT: return "Doc"; case VhdlDocGen::UNITS: return "Units"; - case VhdlDocGen::PORTMAP: return "Port Map"; + //case VhdlDocGen::PORTMAP: return "Port Map"; case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable"; case VhdlDocGen::GROUP: return "Group"; case VhdlDocGen::VFILE: return "File"; + case VhdlDocGen::COMPONENT_INST: return "Component Instantination"; + case VhdlDocGen::ALIAS: return "Alias"; + case VhdlDocGen::CONFIG: return "Configuration"; default: return ""; } } // convertType @@ -1649,7 +1651,7 @@ QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool fun void VhdlDocGen::writeVhdlDeclarations(MemberList* ml, - OutputList& ol,GroupDef* gd,ClassDef* cd) + OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd) { static ClassDef *cdef; //static GroupDef* gdef; @@ -1684,8 +1686,25 @@ void VhdlDocGen::writeVhdlDeclarations(MemberList* ml, VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,0,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE); VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,0,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE); VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,0,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP); + VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,0,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT_INST,FALSE),0,FALSE,VhdlDocGen::COMPONENT_INST); + VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,0,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS); + + // configurations must be added to global file definitions. + VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,0,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG); +} - +static void setConfigurationType(MemberList *ml) +{ + if (ml==0) return; + MemberDef *mdd=0; + MemberListIterator mmli(*ml); + for ( ; (mdd=mmli.current()); ++mmli ) + { + if (strcmp(mdd->argsString(),"configuration")==0) + { + mdd->setMemberSpecifiers(VhdlDocGen::CONFIG); + } + } } /* writes a vhdl type documentation */ @@ -1766,6 +1785,9 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, if (VhdlDocGen::isVariable(mdef)) Doxygen::tagFile << "shared variable"; if (VhdlDocGen::isFile(mdef)) Doxygen::tagFile << "file"; if (VhdlDocGen::isGroup(mdef)) Doxygen::tagFile << "group"; + if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << "component instantiation"; + if (VhdlDocGen::isAlias(mdef)) Doxygen::tagFile << "alias"; + if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << "configuration"; Doxygen::tagFile << "\">" << endl; Doxygen::tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl; @@ -1882,61 +1904,48 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, case VhdlDocGen::PACKAGE: case VhdlDocGen::ENTITY: case VhdlDocGen::COMPONENT: + case VhdlDocGen::COMPONENT_INST: + case VhdlDocGen::CONFIG: writeLink(mdef,ol); ol.insertMemberAlign(); + ol.startBold(); ol.docify(ltype); + ol.endBold(); ol.docify(" "); - if (VhdlDocGen::isComponent(mdef)) + if (VhdlDocGen::isComponent(mdef) || + VhdlDocGen::isConfig(mdef) || + VhdlDocGen::isCompInst(mdef)) { - nn=mdef->name(); + if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef)) + { + nn=ltype; + } + else + { + nn=mdef->name(); + } kl=getClass(nn.data()); if (kl) { nn=kl->getOutputFileBase(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - ol.docify(" "); - QCString name=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE); - ol.startBold(); - ol.docify(name.data()); - ol.endBold(); ol.startEmphasis(); - name.resize(0); - name+=" <"+mdef->name()+"> "; + QCString name("<Entity "); + if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef)) + { + name+=ltype+">"; + } + else + { + name+=mdef->name()+"> "; + } ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data()); ol.endEmphasis(); ol.popGeneratorState(); } } break; - case VhdlDocGen::USE: - kl=VhdlDocGen::getClass(mdef->name()); - if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break; - writeLink(mdef,ol); - ol.insertMemberAlign(); - ol.docify(" "); - - if (kl) - { - nn=kl->getOutputFileBase(); - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - ol.docify(" "); - QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE); - ol.startBold(); - ol.docify(name.data()); - name.resize(0); - ol.endBold(); - name+=" <"+mdef->name()+">"; - ol.startEmphasis(); - ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data()); - ol.popGeneratorState(); - } - break; - case VhdlDocGen::LIBRARY: - writeLink(mdef,ol); - ol.insertMemberAlign(); - break; case VhdlDocGen::SIGNAL: case VhdlDocGen::ATTRIBUTE: case VhdlDocGen::TYPE: @@ -1945,6 +1954,7 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, case VhdlDocGen::SHAREDVARIABLE: case VhdlDocGen::VFILE: case VhdlDocGen::GROUP: + case VhdlDocGen::ALIAS: writeLink(mdef,ol); ol.docify(" "); ol.insertMemberAlign(); @@ -2063,7 +2073,7 @@ void VhdlDocGen::writePlainVHDLDeclarations( pack.clear(); }//plainDeclaration -static bool membersHaveSpecificType(MemberList *ml,int type) +bool VhdlDocGen::membersHaveSpecificType(MemberList *ml,int type) { if (ml==0) return FALSE; MemberDef *mdd=0; @@ -2095,7 +2105,7 @@ void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, const char *title,const char *subtitle,bool /*showEnumValues*/,int type) { - + setConfigurationType(ml); if (!membersHaveSpecificType(ml,type)) return; if (title) @@ -2250,6 +2260,16 @@ QCString VhdlDocGen::trVhdlType(int type,bool sing) case VhdlDocGen::GROUP: if (sing) return "Group"; return "Groups"; + case VhdlDocGen::COMPONENT_INST: + if (sing) return "Component Instantiation"; + else return "Component Instantiations"; + case VhdlDocGen::ALIAS: + if (sing) return "Alias"; + return "Aliases"; + case VhdlDocGen::CONFIG: + if (sing) return "Configuration"; + return "Configurations"; + default: return "Class"; } diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index f8952a7..a42ed4f 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -69,10 +69,13 @@ class VhdlDocGen DOCUMENT, //18 0x12 UNITS, GENERIC, - PORTMAP, + PORTMAP, // obsolete + COMPONENT_INST, GROUP, VFILE, - SHAREDVARIABLE + SHAREDVARIABLE, + CONFIG, + ALIAS }; VhdlDocGen(); @@ -135,6 +138,10 @@ class VhdlDocGen //static void writeVhdlComponentList(OutputList &ol,int type); + static bool isConfig(const MemberDef *mdef) + { return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; } + static bool isAlias(const MemberDef *mdef) + { return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; } static bool isLibrary(const MemberDef *mdef) { return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; } static bool isGeneric(const MemberDef *mdef) @@ -179,6 +186,8 @@ class VhdlDocGen { return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; } static bool isGroup(const MemberDef *mdef) { return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; } + static bool isCompInst(const MemberDef *mdef) + { return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT_INST; } //----------------------------------------------------- // translatable items @@ -232,7 +241,7 @@ class VhdlDocGen static void writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition* d, OutputList &ol); - static void writeVhdlDeclarations(MemberList*,OutputList&,GroupDef*,ClassDef*); + static void writeVhdlDeclarations(MemberList*,OutputList&,GroupDef*,ClassDef*,FileDef*); static void writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, @@ -250,14 +259,17 @@ class VhdlDocGen static void adjustRecordMember(MemberDef *mdef); static bool writeDoc(EntryNav* rootNav); + static void writeLink(const MemberDef* mdef,OutputList &ol); + static void adjustMemberName(QCString& nn); + static bool membersHaveSpecificType(MemberList *ml,int type); + static void startFonts(const QCString& q, char *keyword,OutputList& ol); + static bool isNumber(const QCString& s); + private: static void getFuncParams(QList<Argument>&, const char* str); - static bool isNumber(const QCString& s); - static void startFonts(const QCString& q, char *keyword,OutputList& ol); static bool compareArgList(ArgumentList*,ArgumentList*); static void writeVhdlLink(const ClassDef* cdd ,OutputList& ol,QCString& type,QCString& name,QCString& beh); static void findAllArchitectures(QList<QCString>& ql,const ClassDef *cd); - static void writeLink(const MemberDef* mdef,OutputList &ol); static void writeStringLink(const MemberDef *mdef,QCString mem,OutputList& ol); }; diff --git a/src/vhdlscanner.l b/src/vhdlscanner.l index 1fd68d4..b279dd6 100644 --- a/src/vhdlscanner.l +++ b/src/vhdlscanner.l @@ -15,9 +15,8 @@ /****************************************************************************** * Parser for VHDL subset * written by M. Kreis - * supports VHDL-87 - * does not support all keywords of VHDL '93 (impure function/shared variables ..) - * and VHDL-AMS + * supports VHDL-87/93 + * does not support VHDL-AMS ******************************************************************************/ %{ @@ -76,6 +75,7 @@ static int isBody=0; static int isFunc=0; static int yyLineNr = 1; static char * g_buf = 0; +static uint g_bufSize = 0; static int iTextCounter = 0; static int iCounter = 0; static int bropen = 0; @@ -121,6 +121,19 @@ static void bufferClear() static void addText (char *word, int llen) { + if ((uint)(iCounter + llen) > g_bufSize) + { + char *pTmp = (char*)realloc(g_buf,iCounter+llen+2048); + if (pTmp) + { + g_buf = pTmp; + } + else + { + fprintf(stderr,"\n not enough memory for realloc\n"); + return; + } + } while (llen>0) { g_buf[iCounter]=*word++; @@ -211,6 +224,10 @@ void getType(Entry* p,char* text) { p->spec=VhdlDocGen::GROUP; } + else if (stricmp(name.data(),"alias" )==0) + { + p->spec=VhdlDocGen::ALIAS; + } else { err("wrong type"); @@ -494,16 +511,16 @@ void parserInit() VhdlDocGen::init(); } - uint SSIZE=inputFile.size()+1024; + g_bufSize=inputFile.size()+1024; if (g_buf==0) free(g_buf); - g_buf=(char*)(calloc(SSIZE,sizeof(char))); + g_buf=(char*)(calloc(g_bufSize,sizeof(char))); if (g_buf==0) { fprintf(stderr,"\n no enough memory"); return; } - g_buf[SSIZE-1]='\0'; + g_buf[g_bufSize-1]='\0'; } bool VHDLLanguageScanner::needsPreprocessing(const QCString &) @@ -575,19 +592,17 @@ CR [\r\n] BR [ \t\n\r] LETTER [a-zA-Z_0-9] NAME {LETTER}[a-zA-Z0-9_.]* -FUNCNAME [a-zA-Z"][*+\-_a-zA-Z0-9"\/]* +FUNCNAME [a-zA-Z"][*+\-_a-zA-Z0-9"\/=<>]* DIGITS [0-9]+|[0-9]+"."[0-9]+|[0-9]+"#"[0-9_a-fA-F\+\.]+"#" COMMENT "--"[^\n]* LABELID [a-z_A-Z][^\;]*";"({B}*{COMMENT})* PROTO [ (]* TEXTT "--"[^\/\@\*\#][^\n]* - -ENDE ({BR}*("end"){BR}*[;]{1}) +PROC ("function"|"procedure") +ENDE ({BR}*("end"){BR}*{PROC}*{BR}*[;]{1}) ENDEFF ("if"|"case"|"loop"|"generate"){BR}*[;] - -ENDE3 {BR}*[^a-zA-Z]("end"){BR}+{FUNCNAME}{BR}*[;] -ENDFUNC {B}*"end"{BR}+"function"{BR}+{FUNCNAME}{BR}*[;] - +ENDE3 ({BR}*("end"){BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;])|(ENDE) +ENDFUNC {B}*"end"{BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;] FUNCIMPURE "impure"|"pure" FUNCPROC ^{B}*{FUNCIMPURE}*{BR}*("function"|"procedure"){B}* ARCHITECTURE ("architecture"){BR}+{NAME}{BR}*("of") @@ -597,16 +612,17 @@ ARCHITECTURE ("architecture"){BR}+{NAME}{BR}*("of") */ PROCESS ({B}*{FUNCNAME}{B}*:{BR}*)?({B}*("postponed"){BR}+)?{B}*("process"){BR}*{PROTO} -ENDPROCESS ("end"){BR}*("process") +ENDPROCESS ("end"){BR}*("postponed")*("process"){BR}*{FUNCNAME}*{BR}*[;] LIBUSE ^{B}*("use"|"library"){BR}+ ENTITY ^{B}*("component"|"entity"|"package"){BR}+ PBODY ("package"){B}+("body"){BR}+{NAME} SHARED ("shared"){BR}+("variable") -SIGTYPES ^{B}*({SHARED}|"file"|"group"|"subtype"|"type"|"constant"|"attribute"|"signal"|"units"){BR}+ +SIGTYPES ^{B}*({SHARED}|"alias"|"file"|"group"|"subtype"|"type"|"constant"|"attribute"|"signal"|"units"){BR}+ +CONFIG ("configuration"){BR}+{NAME}{BR}*("of"){BR}+{NAME}{BR}+"is" ALLTYPESMAP {B}*[_a-zA-ZA_Z0-9. ]*{B}* -MAPCOMPONENT ({ALLTYPESMAP}{BR}*[:]{BR}*{ALLTYPESMAP}{BR}*("port"|"generic"){BR}+("map"){BR}*("("){1}) +MAPCOMPONENT ({ALLTYPESMAP}{BR}*[:]{BR}*{ALLTYPESMAP}{BR}*{TEXTT}*{BR}*("port"|"generic"){BR}+("map"){BR}*("("){1}) BRACEOPEN [(]{1} BRACECLOSE [)]{1} @@ -624,6 +640,7 @@ ALLID [^;()\t ] %x ParseRecord %x ParseUnits %x ParseProcess +%x ParseFunc %x FindName %x FindEntityName %x FindGenPort @@ -634,6 +651,20 @@ ALLID [^;()\t ] %% +<Start>{CONFIG} { // found configuration + + QCString qcs(vhdlscanYYtext); + current->name=VhdlDocGen::getIndexWord(qcs,1); + current->type=VhdlDocGen::getIndexWord(qcs,3); + current->startLine=yyLineNr; + current->bodyLine=yyLineNr; + current->section=Entry::VARIABLE_SEC; + current->spec=VhdlDocGen::CONFIG; + current->args="configuration"; + newEntry(); + BEGIN(Start); +} + <Start>{SIGTYPES} { // found type constant|type|attribute and so on.. bropen=0; lineCount(); @@ -783,37 +814,14 @@ ALLID [^;()\t ] lineCount(); QCString type; QCString tt(yytext); - tt = tt.stripWhiteSpace(); - //printf(" tt=%s\n",tt.data()); - //VhdlDocGen::deleteAllChars(tt,'\n'); - QCString name = VhdlDocGen::getIndexWord(tt,0); - int i=name.find(':'); - if (i!=-1) - { - name = name.left(i); - tt = tt.right(tt.length()-i-1); - } - int j = tt.find('.'); - if (j!=-1) - { - int k=tt.find(" ",j,FALSE); - if (k>(j+1)) - type=tt.mid(j+1,k-j-1); - } - else - { - type=VhdlDocGen::getIndexWord(tt,1); - if (type==":") type=VhdlDocGen::getIndexWord(tt,2); - if (type=="component") type=VhdlDocGen::getIndexWord(tt,3); - } - //printf("Add mapping %s->%s\n",type.data(),name.data()); - - current->spec=VhdlDocGen::PORTMAP; + QRegExp regg("[ \n\t:-]"); + QStringList qsl=QStringList::split(regg,tt,false); + current->spec=VhdlDocGen::COMPONENT_INST; current->section=Entry::VARIABLE_SEC; current->startLine=yyLineNr; current->bodyLine=yyLineNr; - current->type=type; - current->name=name; + current->type=QCString(qsl[1]); + current->name=QCString(qsl[0]); if (lastCompound) { lastCompound->addSubEntry(current); @@ -985,7 +993,7 @@ ALLID [^;()\t ] BEGIN(ParseRecord); } -<ParseType>{B}+("is"){B}*{CR}|{B}+("is"){B}*"--" { // found a new function in an architecture ? +<ParseType>{BR}+("is"){BR}+|{BR}+("is"){B}*"--" { // found a new function in an architecture ? addText(yytext,yyleng); lineCount(); QCString ttt; @@ -1075,51 +1083,58 @@ ALLID [^;()\t ] <ParseType>{ENDE}|{ENDFUNC} { // found end of function|process + QRegExp regg("[ \n\t;]"); lineCount(); - if (functionEntry) - { - functionEntry->endBodyLine=yyLineNr; - functionEntry=0; - } - - if (isBody==1 && isFunc==1 && bropen==0) + QCString tt(yytext); + tt=tt.lower(); + QStringList ql=QStringList::split(regg,tt,FALSE); + int index=ql.findIndex(QCString("if"))+1; + index+=ql.findIndex(QCString("case"))+1; + index+=ql.findIndex(QCString("loop"))+1; + index+=ql.findIndex(QCString("generate"))+1; + bufferClear(); + if (index==0) { - isFunc=0; + if (isFunc) + { + Entry* pFunc=getEntryAtLine(current_root,iFuncLine); + if (pFunc && pFunc->section==Entry::FUNCTION_SEC) + { + pFunc->endBodyLine=yyLineNr; + } + isFunc=0; + BEGIN(Start); + } } - - bufferClear(); - BEGIN(Start); - } +<ParseFunc>[^;()] { + // eat process body + lineCount(); + BEGIN(ParseFunc); + } -<ParseType>{ENDE3} { +<ParseFunc>{ENDE3} { + QRegExp regg("[ \n\t;]"); lineCount(); QCString tt(yytext); tt=tt.lower(); - VhdlDocGen::deleteAllChars(tt,';'); - tt.stripWhiteSpace(); - QStringList ql=QStringList::split(" ",tt,FALSE); + QStringList ql=QStringList::split(regg,tt,FALSE); int index=ql.findIndex(QCString("if"))+1; index+=ql.findIndex(QCString("case"))+1; index+=ql.findIndex(QCString("loop"))+1; index+=ql.findIndex(QCString("generate"))+1; bufferClear(); - if (functionEntry && index==0) + if (index==0 && isFunc) { - functionEntry->endBodyLine=yyLineNr; - functionEntry=0; + Entry* pFunc=getEntryAtLine(current_root,iFuncLine); + if (pFunc && pFunc->section==Entry::FUNCTION_SEC) + { + pFunc->endBodyLine=yyLineNr; + } isFunc=0; BEGIN(Start); } - else if (index==0) - { - BEGIN(Start); - } - else - { - BEGIN(ParseType); - } } <ParseType>";" { @@ -1130,6 +1145,16 @@ ALLID [^;()\t ] if (isFunc) { parseFunctionProto(); + bufferClear(); + if (lastCompound && lastCompound->spec==VhdlDocGen::PACKAGE) + { + isFunc=0; + BEGIN(Start); + } + else + { + BEGIN(ParseFunc); + } }//if else { @@ -1199,10 +1224,10 @@ ALLID [^;()\t ] { newEntry(); } + isFunc=0; + bufferClear(); + BEGIN(Start); } - isFunc=0; - //bufferClear(); - BEGIN(Start); } else { |