diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2012-12-26 15:59:17 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2012-12-26 15:59:17 (GMT) |
commit | 48f4de5c47d55b6622b6fdc9b5c288e19d5692f9 (patch) | |
tree | 629c4681a5158d26512b815623754b33165d8d23 /src | |
parent | fee4053bd3dd075a2dd2cba4da8166ec5307eadd (diff) | |
download | Doxygen-48f4de5c47d55b6622b6fdc9b5c288e19d5692f9.zip Doxygen-48f4de5c47d55b6622b6fdc9b5c288e19d5692f9.tar.gz Doxygen-48f4de5c47d55b6622b6fdc9b5c288e19d5692f9.tar.bz2 |
Release-1.8.3
Diffstat (limited to 'src')
51 files changed, 953 insertions, 423 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 4349d3f..8517893 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -2220,7 +2220,7 @@ void ClassDef::writeMemberList(OutputList &ol) { //ol.writeListItem(); ol.writeString(" <tr bgcolor=\"#f0f0f0\""); - if ((idx&1)==0) ol.writeString("class=\"even\""); + if ((idx&1)==0) ol.writeString(" class=\"even\""); idx++; ol.writeString("><td class=\"entry\">"); if (cd->isObjectiveC()) @@ -4106,15 +4106,14 @@ void ClassDef::writeInheritedMemberDeclarations(OutputList &ol, int lt1,lt2; convertProtectionLevel(lt,ibcd->prot,<1,<2); //printf("%s:convert %d->(%d,%d)\n",icd->name().data(),lt,lt1,lt2); - if (visitedClasses->find(icd)!=0) - { - return; // already processed before (in case of multiple inheritance) - } - visitedClasses->insert(icd,icd); - if (lt1!=-1) + if (visitedClasses->find(icd)==0) { - icd->writeMemberDeclarations(ol,(MemberListType)lt1, - title,QCString(),FALSE,inheritedFrom,lt2,invert,visitedClasses); + visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance + if (lt1!=-1) + { + icd->writeMemberDeclarations(ol,(MemberListType)lt1, + title,QCString(),FALSE,inheritedFrom,lt2,invert,visitedClasses); + } } } } @@ -427,11 +427,11 @@ static void setCurrentDoc(const QCString &anchor) { if (g_searchCtx) { - Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE); + g_code->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE); } else { - Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE); + g_code->setCurrentDoc(g_sourceFileDef,anchor,TRUE); } } } @@ -440,7 +440,7 @@ static void addToSearchIndex(const char *text) { if (Doxygen::searchIndex) { - Doxygen::searchIndex->addWord(text,FALSE); + g_code->addWord(text,FALSE); } } diff --git a/src/commentcnv.l b/src/commentcnv.l index 88d9ce3..9d99830 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -183,16 +183,16 @@ static void startCondSection(const char *sectId) CondParser prs; bool expResult = prs.parse(g_fileName,g_lineNr,sectId); g_condStack.push(new CondCtx(g_lineNr,sectId,g_skip)); - if (guardType == Guard_Cond) + if (guardType == Guard_Cond) // found @cond { - if (expResult) + if (!expResult) // not enabled { g_skip=TRUE; } } - else if (guardType == Guard_CondNot) + else if (guardType == Guard_CondNot) // found @notcond { - if (!expResult) + if (expResult) // enabled { g_skip=TRUE; } @@ -294,7 +294,7 @@ void replaceComment(int offset); <Scan>\n { /* new line */ copyToOutput(yytext,(int)yyleng); } -<Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */ +<Scan>("//!"|"///")/.*\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */ if (g_mlBrief) { REJECT; // bail out if we do not need to convert @@ -310,7 +310,9 @@ void replaceComment(int offset); copyToOutput("/**",3); replaceAliases(yytext+i); g_inSpecialComment=TRUE; - BEGIN(SComment); + //BEGIN(SComment); + g_readLineCtx=SComment; + BEGIN(ReadLine); } } <Scan>"//##Documentation".*/\n { /* Start of Rational Rose ANSI C++ comment block */ @@ -323,6 +325,7 @@ void replaceComment(int offset); BEGIN(SComment); } <Scan>"//"/.*\n { /* one line C++ comment */ + g_inSpecialComment=yytext[2]=='/' || yytext[2]=='!'; copyToOutput(yytext,(int)yyleng); g_readLineCtx=YY_START; BEGIN(ReadLine); @@ -679,11 +682,6 @@ void replaceComment(int offset); guardType = Guard_Cond; BEGIN(CondLine); } -<CComment,ReadLine>[\\@]"condnot"[ \t]+ { // conditional section - g_condCtx = YY_START; - guardType = Guard_CondNot; - BEGIN(CondLine); - } <CComment,ReadLine>[\\@]"endcond"/[^a-z_A-Z0-9] { // end of conditional section bool oldSkip=g_skip; endCondSection(); @@ -706,9 +704,9 @@ void replaceComment(int offset); <CondLine>[!()&| \ta-z_A-Z0-9.\-]+ { bool oldSkip=g_skip; startCondSection(yytext); - if (g_condCtx==CComment && !oldSkip && g_skip) + if ((g_condCtx==CComment || g_readLineCtx==SComment) && + !oldSkip && g_skip) { - //printf("** Adding terminator for comment!\n"); if (g_lang!=SrcLangExt_Python && g_lang!=SrcLangExt_VHDL && g_lang!=SrcLangExt_Fortran) @@ -717,7 +715,14 @@ void replaceComment(int offset); ADDCHAR('/'); } } - BEGIN(g_condCtx); + if (g_readLineCtx==SComment) + { + BEGIN(SComment); + } + else + { + BEGIN(g_condCtx); + } } <CondLine>[ \t]* <CComment,ReadLine>[\\@]"cond"[ \t\r]*/\n | @@ -726,7 +731,8 @@ void replaceComment(int offset); if (YY_START!=CondLine) g_condCtx=YY_START; bool oldSkip=g_skip; startCondSection(" "); // fake section id causing the section to be hidden unconditionally - if (g_condCtx==CComment && !oldSkip && g_skip) + if ((g_condCtx==CComment || g_readLineCtx==SComment) && + !oldSkip && g_skip) { //printf("** Adding terminator for comment!\n"); if (g_lang!=SrcLangExt_Python && @@ -737,7 +743,14 @@ void replaceComment(int offset); } } if (*yytext=='\n') g_lineNr++; - BEGIN(g_condCtx); + if (g_readLineCtx==SComment) + { + BEGIN(SComment); + } + else + { + BEGIN(g_condCtx); + } } <CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias without arguments replaceAliases(yytext); @@ -804,7 +817,7 @@ void replaceComment(int offset); void replaceComment(int offset) { - if (g_mlBrief) + if (g_mlBrief || g_skip) { copyToOutput(yytext,(int)yyleng); } diff --git a/src/commentscan.l b/src/commentscan.l index 375b0f9..68f6b5f 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -413,6 +413,9 @@ static bool g_spaceBeforeCmd; static bool g_spaceBeforeIf; static QCString g_copyDocArg; +static QCString g_guardExpr; +static int g_roundCount; + //----------------------------------------------------------------------------- static QStack<Grouping> g_autoGroupStack; @@ -807,6 +810,7 @@ static void endBrief(bool addToOutput=TRUE) } } +static void handleGuard(const QCString &expr); /* ----------------------------------------------------------------- */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); @@ -917,6 +921,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" %x SkipLang %x CiteLabel %x CopyDoc +%x GuardExpr %% @@ -1032,7 +1037,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } int i=0; while (yytext[i]==' ' || yytext[i]=='\t') i++; - if (i>0) addOutput(QCString(yytext).left(i)); + //if (i>0) addOutput(QCString(yytext).left(i)); // removed for bug 689341 if (cmdPtr->func && cmdPtr->func(cmdName)) { // implicit split of the comment block into two @@ -1725,36 +1730,34 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ----- handle arguments of if/ifnot commands ------- */ -<GuardParam>[!()&| \ta-z_A-Z0-9.\-]+ {// parameter of if/ifnot guard - CondParser prs; - bool sectionEnabled=prs.parse(yyFileName,yyLineNr,yytext); - bool parentEnabled = TRUE; - if (!guards.isEmpty()) parentEnabled = guards.top()->isEnabled(); - if (parentEnabled) - { - if ( - (sectionEnabled && guardType==Guard_If) || - (!sectionEnabled && guardType==Guard_IfNot) - ) // section is visible - { - guards.push(new GuardedSection(TRUE,TRUE)); - enabledSectionFound=TRUE; - BEGIN( GuardParamEnd ); - } - else // section is invisible - { - if (guardType!=Guard_Skip) - { - guards.push(new GuardedSection(FALSE,TRUE)); - } - BEGIN( SkipGuardedSection ); - } - } - else // invisible because of parent - { - guards.push(new GuardedSection(FALSE,FALSE)); - BEGIN( SkipGuardedSection ); - } +<GuardParam>"(" { + g_guardExpr=yytext; + g_roundCount=1; + BEGIN(GuardExpr); + } +<GuardExpr>[^()]* { + g_guardExpr+=yytext; + } +<GuardExpr>"(" { + g_guardExpr+=yytext; + g_roundCount++; + } +<GuardExpr>")" { + g_guardExpr+=yytext; + g_roundCount--; + if (g_roundCount==0) + { + handleGuard(g_guardExpr); + } + } +<GuardExpr>\n { + warn(yyFileName,yyLineNr, + "warning: invalid expression '%s' for guard",g_guardExpr.data()); + unput(*yytext); + BEGIN(GuardParam); + } +<GuardParam>[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot guard + handleGuard(yytext); } <GuardParam>{DOCNL} { // end of argument if (*yytext=='\n') yyLineNr++; @@ -2952,6 +2955,40 @@ static void groupAddDocs(Entry *e,const char *fileName) } } +static void handleGuard(const QCString &expr) +{ + CondParser prs; + bool sectionEnabled=prs.parse(yyFileName,yyLineNr,expr); + bool parentEnabled = TRUE; + if (!guards.isEmpty()) parentEnabled = guards.top()->isEnabled(); + if (parentEnabled) + { + if ( + (sectionEnabled && guardType==Guard_If) || + (!sectionEnabled && guardType==Guard_IfNot) + ) // section is visible + { + guards.push(new GuardedSection(TRUE,TRUE)); + enabledSectionFound=TRUE; + BEGIN( GuardParamEnd ); + } + else // section is invisible + { + if (guardType!=Guard_Skip) + { + guards.push(new GuardedSection(FALSE,TRUE)); + } + BEGIN( SkipGuardedSection ); + } + } + else // invisible because of parent + { + guards.push(new GuardedSection(FALSE,FALSE)); + BEGIN( SkipGuardedSection ); + } +} + + #if !defined(YY_FLEX_SUBMINOR_VERSION) //---------------------------------------------------------------------------- diff --git a/src/condparser.cpp b/src/condparser.cpp index 4920ade..2cadc1e 100644 --- a/src/condparser.cpp +++ b/src/condparser.cpp @@ -37,18 +37,19 @@ bool CondParser::parse(const char *fileName,int lineNr,const char *expr) m_tokenType = NOTHING; // initialize all variables - m_e = m_expr.data(); // let m_e point to the start of the expression + m_e = m_expr; // let m_e point to the start of the expression + bool answer=FALSE; getToken(); if (m_tokenType==DELIMITER && m_token.isEmpty()) { - return "Empty expression"; + // empty expression: answer==FALSE } - bool answer=FALSE; - if (m_err.isEmpty()) + else if (m_err.isEmpty()) { answer = parseLevel1(); +#if 0 // check for garbage at the end of the expression // an expression ends with a character '\0' and token_type = delimeter if (m_tokenType!=DELIMITER || !m_token.isEmpty()) @@ -70,12 +71,14 @@ bool CondParser::parse(const char *fileName,int lineNr,const char *expr) m_err=QCString("Unexpected part '")+m_token+"'"; } } +#endif } if (m_err) { warn(fileName,lineNr,"Warning: problem evaluating expression '%s': %s", expr,m_err.data()); } + //printf("expr='%s' answer=%d\n",expr,answer); return answer; } diff --git a/src/config.l b/src/config.l index 7c37dea..0422411 100644 --- a/src/config.l +++ b/src/config.l @@ -506,26 +506,9 @@ static FILE *tryPath(const char *path,const char *fileName) static void substEnvVarsInStrList(QStrList &sl); static void substEnvVarsInString(QCString &s); -static bool isAbsolute(const char * fileName) -{ -# ifdef _WIN32 - if (isalpha (fileName [0]) && fileName[1] == ':') - fileName += 2; -# endif - char const fst = fileName [0]; - if (fst == '/') { - return true; - } -# ifdef _WIN32 - if (fst == '\\') - return true; -# endif - return false; -} - static FILE *findFile(const char *fileName) { - if(isAbsolute(fileName)) + if(portable_isAbsolutePath(fileName)) return tryPath(NULL, fileName); substEnvVarsInStrList(includePathList); char *s=includePathList.first(); @@ -1458,7 +1441,7 @@ void Config::check() config_err("error: Unsupported value for MATHJAX_FORMAT: Should be one of HTML-CSS, NativeMML, or SVG\n"); Config_getEnum("MATHJAX_FORMAT")="HTML-CSS"; } - + // add default words if needed QStrList &annotationFromBrief = Config_getList("ABBREVIATE_BRIEF"); if (annotationFromBrief.isEmpty()) diff --git a/src/config.xml b/src/config.xml index 3ca3313..a75ff80 100644 --- a/src/config.xml +++ b/src/config.xml @@ -1148,12 +1148,42 @@ can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. ' defval='1' depends='GENERATE_HTML'/> <option type='bool' id='SERVER_BASED_SEARCH' docs=' When the SERVER_BASED_SEARCH tag is enabled the search engine will be -implemented using a PHP enabled web server instead of at the web client -using Javascript. Doxygen will generate the search PHP script and index -file to put on the web server. The advantage of the server -based approach is that it scales better to large projects and allows -full text search. The disadvantages are that it is more difficult to setup -and does not have live searching capabilities. +implemented using a web server instead of a web client using Javascript. +There are two flavours of web server based search depending on the +EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +searching and an index file used by the script. When EXTERNAL_SEARCH is +enabled the indexing and searching needs to be provided by external tools. +See the manual for details. +' defval='0' depends='SEARCHENGINE'/> + <option type='bool' id='EXTERNAL_SEARCH' docs=' +When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +script for searching. Instead the search results are written to an XML file +which needs to be processed by an external indexer. Doxygen will invoke an +external search engine pointed to by the SEARCHENGINE_URL option to obtain +the search results. Doxygen ships with an example indexer (doxyindexer) and +search engine (doxysearch.cgi) which are based on the open source search engine +library Xapian. See the manual for configuration details. +' defval='0' depends='SEARCHENGINE'/> + <option type='string' id='SEARCHENGINE_URL' docs=' +The SEARCHENGINE_URL should point to a search engine hosted by a web server +which will returned the search results when EXTERNAL_SEARCH is enabled. +Doxygen ships with an example search engine (doxysearch) which is based on +the open source search engine library Xapian. See the manual for configuration +details. +' defval='' depends='SEARCHENGINE'/> + <option type='string' id='SEARCHDATA_FILE' format='file' docs=' +When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +search data is written to a file for indexing by an external tool. With the +SEARCHDATA_FILE tag the name of this file can be specified. +' defval='searchdata.xml' depends='SEARCHENGINE'/> + <option type='list' id='EXTRA_SEARCH_MAPPINGS' docs=' +The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other +doxygen projects that are not otherwise connected via tags files, but are +all added to the same search index. Each project needs to have a tag file set +via GENERATE_TAGFILE. The search mapping then maps the name of the tag file +to a relative location where the documentation can be found, similar to the +TAGFILES option but without actually processing the tag file. +The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... ' defval='0' depends='SEARCHENGINE'/> </group> <group name='LaTeX' docs='configuration options related to the LaTeX output'> diff --git a/src/configoptions.cpp b/src/configoptions.cpp index 229cd13..846142c 100644 --- a/src/configoptions.cpp +++ b/src/configoptions.cpp @@ -1680,15 +1680,61 @@ void addConfigOptions(Config *cfg) cb = cfg->addBool( "SERVER_BASED_SEARCH", "When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n" - "implemented using a PHP enabled web server instead of at the web client\n" - "using Javascript. Doxygen will generate the search PHP script and index\n" - "file to put on the web server. The advantage of the server\n" - "based approach is that it scales better to large projects and allows\n" - "full text search. The disadvantages are that it is more difficult to setup\n" - "and does not have live searching capabilities.", + "implemented using a web server instead of a web client using Javascript.\n" + "There are two flavours of web server based search depending on the\n" + "EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for\n" + "searching and an index file used by the script. When EXTERNAL_SEARCH is\n" + "enabled the indexing and searching needs to be provided by external tools.\n" + "See the manual for details.", FALSE ); cb->addDependency("SEARCHENGINE"); + //---- + cb = cfg->addBool( + "EXTERNAL_SEARCH", + "When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP\n" + "script for searching. Instead the search results are written to an XML file\n" + "which needs to be processed by an external indexer. Doxygen will invoke an\n" + "external search engine pointed to by the SEARCHENGINE_URL option to obtain\n" + "the search results. Doxygen ships with an example indexer (doxyindexer) and\n" + "search engine (doxysearch.cgi) which are based on the open source search engine\n" + "library Xapian. See the manual for configuration details.", + FALSE + ); + cb->addDependency("SEARCHENGINE"); + //---- + cs = cfg->addString( + "SEARCHENGINE_URL", + "The SEARCHENGINE_URL should point to a search engine hosted by a web server\n" + "which will returned the search results when EXTERNAL_SEARCH is enabled.\n" + "Doxygen ships with an example search engine (doxysearch) which is based on\n" + "the open source search engine library Xapian. See the manual for configuration\n" + "details." + ); + cs->addDependency("SEARCHENGINE"); + //---- + cs = cfg->addString( + "SEARCHDATA_FILE", + "When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n" + "search data is written to a file for indexing by an external tool. With the\n" + "SEARCHDATA_FILE tag the name of this file can be specified." + ); + cs->setDefaultValue("searchdata.xml"); + cs->setWidgetType(ConfigString::File); + cs->addDependency("SEARCHENGINE"); + //---- + cl = cfg->addList( + "EXTRA_SEARCH_MAPPINGS", + "The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other\n" + "doxygen projects that are not otherwise connected via tags files, but are\n" + "all added to the same search index. Each project needs to have a tag file set\n" + "via GENERATE_TAGFILE. The search mapping then maps the name of the tag file\n" + "to a relative location where the documentation can be found,\n" + "similar to the\n" + "TAGFILES option but without actually processing the tag file.\n" + "The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ..." + ); + cl->addDependency("SEARCHENGINE"); //--------------------------------------------------------------------------- cfg->addInfo("LaTeX","configuration options related to the LaTeX output"); //--------------------------------------------------------------------------- diff --git a/src/definition.cpp b/src/definition.cpp index adaf74a..2833be7 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -509,7 +509,12 @@ void Definition::writeDocAnchorsToTagFile() //printf("write an entry!\n"); if (definitionType()==TypeMember) Doxygen::tagFile << " "; Doxygen::tagFile << " <docanchor file=\"" - << si->fileName << "\">" << si->label + << si->fileName << "\""; + if (!si->title.isEmpty()) + { + Doxygen::tagFile << " title=\"" << convertToXML(si->title) << "\""; + } + Doxygen::tagFile << ">" << si->label << "</docanchor>" << endl; } } diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 6dd5f56..d2b5123 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -350,7 +350,7 @@ SPCMD4 {CMD}"::" INOUT "inout"|"in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in") PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]" TEMPCHAR [a-z_A-Z0-9,: \t\*\&] -FUNCCHAR [a-z_A-Z0-9,:\<\> \t\*\&\[\]] +FUNCCHAR [a-z_A-Z0-9,:\<\> \t\^\*\&\[\]] SCOPESEP "::"|"#"|"." TEMPLPART "<"{TEMPCHAR}*">" SCOPEPRE {ID}{TEMPLPART}?{SCOPESEP} diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 482d9fc..916c64d 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -6625,7 +6625,6 @@ static void findObjCMethodDefinitions(EntryNav *rootNav) static void findEnums(EntryNav *rootNav) { if (rootNav->section()==Entry::ENUM_SEC) - // non anonymous enumeration { rootNav->loadEntry(g_storage); Entry *root = rootNav->entry(); @@ -6791,74 +6790,7 @@ static void findEnums(EntryNav *rootNav) // name.data(),mn->count()); } addMemberToGroups(root,md); - -#if 0 - if (rootNav->children()) - { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; - for (;(e=eli.current());++eli) - { - //printf("e->name=%s isRelated=%d\n",e->name.data(),isRelated); - MemberName *fmn=0; - MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd; - if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()])) - // get list of members with the same name as the field - { - MemberNameIterator fmni(*fmn); - MemberDef *fmd; - for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) - { - if (fmd->isEnumValue()) - { - //printf("found enum value with same name\n"); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') - { - NamespaceDef *fnd=fmd->getNamespaceDef(); - if (fnd==nd) // enum value is inside a namespace - { - md->insertEnumField(fmd); - fmd->setEnumScope(md); - } - } - else if (isGlobal) - { - FileDef *ffd=fmd->getFileDef(); - if (ffd==fd) // enum value has file scope - { - md->insertEnumField(fmd); - fmd->setEnumScope(md); - } - } - else if (isRelated && cd) // reparent enum value to - // match the enum's scope - { - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name - fmd->setEnumClassScope(cd); // cross ref with enum name - fmd->setOuterScope(cd); - fmd->makeRelated(); - cd->insertMember(fmd); - } - else - { - ClassDef *fcd=fmd->getClassDef(); - if (fcd==cd) // enum value is inside a class - { - //printf("Inserting enum field %s in enum scope %s\n", - // fmd->name().data(),md->name().data()); - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name - } - } - } - } - } - } - } -#endif } - rootNav->releaseEntry(); } else @@ -10775,7 +10707,17 @@ void generateOutput() } else // write data for external search index { - Doxygen::searchIndex->write(Config_getString("OUTPUT_DIRECTORY")+"/searchdata.xml"); + HtmlGenerator::writeExternalSearchPage(); + QCString searchDataFile = Config_getString("SEARCHDATA_FILE"); + if (searchDataFile.isEmpty()) + { + searchDataFile="searchdata.xml"; + } + if (!portable_isAbsolutePath(searchDataFile)) + { + searchDataFile.prepend(Config_getString("OUTPUT_DIRECTORY")+"/"); + } + Doxygen::searchIndex->write(searchDataFile); } } diff --git a/src/doxygen.css b/src/doxygen.css index de6fd81..544cc71 100644 --- a/src/doxygen.css +++ b/src/doxygen.css @@ -763,7 +763,7 @@ table.doxtable th { } table.fieldtable { - width: 100%; + /*width: 100%;*/ margin-bottom: 10px; border: 1px solid ##B4; border-spacing: 0px; @@ -786,9 +786,13 @@ table.fieldtable { vertical-align: top; } +.fieldtable td.fieldname { + padding-top: 5px; +} + .fieldtable td.fielddoc { border-bottom: 1px solid ##B4; - width: 100%; + /*width: 100%;*/ } .fieldtable td.fielddoc p:first-child { diff --git a/src/doxygen_css.h b/src/doxygen_css.h index 64a9f25..2b3f668 100644 --- a/src/doxygen_css.h +++ b/src/doxygen_css.h @@ -763,7 +763,7 @@ "}\n" "\n" "table.fieldtable {\n" -" width: 100%;\n" +" /*width: 100%;*/\n" " margin-bottom: 10px;\n" " border: 1px solid ##B4;\n" " border-spacing: 0px;\n" @@ -786,9 +786,13 @@ " vertical-align: top;\n" "}\n" "\n" +".fieldtable td.fieldname {\n" +" padding-top: 5px;\n" +"}\n" +"\n" ".fieldtable td.fielddoc {\n" " border-bottom: 1px solid ##B4;\n" -" width: 100%;\n" +" /*width: 100%;*/\n" "}\n" "\n" ".fieldtable td.fielddoc p:first-child {\n" diff --git a/src/eclipsehelp.cpp b/src/eclipsehelp.cpp index da9f13b..df65a13 100644 --- a/src/eclipsehelp.cpp +++ b/src/eclipsehelp.cpp @@ -19,7 +19,7 @@ #include "doxygen.h" #include <qfile.h> -EclipseHelp::EclipseHelp() : m_depth(0), m_endtag(FALSE), m_tocfile(0) +EclipseHelp::EclipseHelp() : m_depth(0), m_endtag(FALSE), m_openTags(0), m_tocfile(0) { } @@ -51,6 +51,7 @@ void EclipseHelp::openedTag() { m_tocstream << ">" << endl; m_endtag = FALSE; + ++m_openTags; } } @@ -144,8 +145,13 @@ void EclipseHelp::decContentsDepth() // -- end of the opened topic closedTag(); --m_depth; - indent(); - m_tocstream << "</topic>" << endl; + + if (m_openTags==m_depth) + { + --m_openTags; + indent(); + m_tocstream << "</topic>" << endl; + } } /*! @@ -172,19 +178,41 @@ void EclipseHelp::addContentsItem( { // -- write the topic tag closedTag(); - indent(); - m_tocstream << "<topic label=\"" << convertToXML(name) << "\""; if (file) { - m_tocstream << " href=\"" << convertToXML(m_pathprefix) - << file << Doxygen::htmlFileExtension; - if (anchor) + switch (file[0]) // check for special markers (user defined URLs) { - m_tocstream << "#" << anchor; + case '^': + // URL not supported by eclipse toc.xml + break; + + case '!': + indent(); + m_tocstream << "<topic label=\"" << convertToXML(name) << "\""; + m_tocstream << " href=\"" << convertToXML(m_pathprefix) << &file[1] << "\""; + m_endtag = TRUE; + break; + + default: + indent(); + m_tocstream << "<topic label=\"" << convertToXML(name) << "\""; + m_tocstream << " href=\"" << convertToXML(m_pathprefix) + << file << Doxygen::htmlFileExtension; + if (anchor) + { + m_tocstream << "#" << anchor; + } + m_tocstream << "\""; + m_endtag = TRUE; + break; } - m_tocstream << "\""; } - m_endtag = TRUE; + else + { + indent(); + m_tocstream << "<topic label=\"" << convertToXML(name) << "\""; + m_endtag = TRUE; + } } void EclipseHelp::addIndexItem( diff --git a/src/eclipsehelp.h b/src/eclipsehelp.h index 841dc81..3be7fc0 100644 --- a/src/eclipsehelp.h +++ b/src/eclipsehelp.h @@ -60,6 +60,7 @@ class EclipseHelp : public IndexIntf private: int m_depth; bool m_endtag; + int m_openTags; QFile * m_tocfile; FTextStream m_tocstream; diff --git a/src/extsearch.js b/src/extsearch.js new file mode 100644 index 0000000..920c12b --- /dev/null +++ b/src/extsearch.js @@ -0,0 +1,129 @@ +function SearchBox(name, resultsPath, inFrame, label) +{ + this.searchLabel = label; + this.DOMSearchField = function() + { return document.getElementById("MSearchField"); } + this.DOMSearchBox = function() + { return document.getElementById("MSearchBox"); } + this.OnSearchFieldFocus = function(isActive) + { + if (isActive) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + var searchField = this.DOMSearchField(); + if (searchField.value == this.searchLabel) + { + searchField.value = ''; + } + } + else + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + } + } +} + +function trim(s) { + return s?s.replace(/^\s\s*/, '').replace(/\s\s*$/, ''):''; +} + +function getURLParameter(name) { + return decodeURIComponent((new RegExp('[?|&]'+name+ + '='+'([^&;]+?)(&|#|;|$)').exec(location.search) + ||[,""])[1].replace(/\+/g, '%20'))||null; +} + +var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''', + "/": '/' +}; + +function escapeHtml(s) { + return String(s).replace(/[&<>"'\/]/g, function (s) { + return entityMap[s]; + }); +} + +function searchFor(query,page,count) { + $.getJSON(serverUrl+"?cb=?", + { + n:count, + p:page, + q:query + }, + function(data) { + var results = $('#searchresults'); + $('#MSearchField').val(query); + if (data.hits>0) { + if (data.hits==1) { + results.html('<p>'+searchResultsText[1]+'</p>'); + } else { + results.html('<p>'+searchResultsText[2].replace(/\$num/,data.hits)+'</p>'); + } + var r='<table>'; + $.each(data.items, function(i,item){ + var prefix = tagMap[item.tag]; + if (prefix) prefix+='/'; else prefix=''; + r+='<tr class="searchresult">'+ + '<td align="right">'+(data.first+i+1)+'.</td>'+ + '<td>'+escapeHtml(item.type)+' '+ + '<a href="'+escapeHtml(prefix+item.url)+ + '">'+escapeHtml(item.name)+'</a>'; + if (item.type=="source") { + var l=item.url.match(/[1-9][0-9]*$/); + if (l) r+=' at line '+parseInt(l[0]); + } + r+='</td>'; + for (var i=0;i<item.fragments.length;i++) + { + r+='<tr><td></td><td>'+item.fragments[i]+'</td></tr>'; + } + r+='</tr>'; + }); + r+='</table>'; + if (data.pages>1) // write multi page navigation bar + { + r+='<div class="searchpages">'; + if (data.page>0) + { + r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+(page-1).toString()+','+count.toString()+')">«</a></span> '; + } + var firstPage = data.page-5; + var lastPage = data.page+5; + if (firstPage<0) + { + lastPage-=firstPage; + firstPage=0; + } + if (lastPage>data.pages) + { + lastPage=data.pages; + } + for(var i=firstPage;i<lastPage;i++) + { + if (i==data.page) + { + r+='<span class="pages"><b>'+(i+1).toString()+'</b></span> '; + } + else + { + r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+i.toString()+','+count.toString()+')">'+(i+1).toString()+'</a></span> '; + } + } + if (data.page+1<data.pages) + { + r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+(page+1).toString()+','+count.toString()+')">»</a></span>'; + } + r+='</div>'; + } + results.append(r); + } else { + results.html('<p>'+searchResultsText[0]+'</p>'); + } + }); +} diff --git a/src/extsearch_js.h b/src/extsearch_js.h new file mode 100644 index 0000000..dc72659 --- /dev/null +++ b/src/extsearch_js.h @@ -0,0 +1,129 @@ +"function SearchBox(name, resultsPath, inFrame, label)\n" +"{\n" +" this.searchLabel = label;\n" +" this.DOMSearchField = function()\n" +" { return document.getElementById(\"MSearchField\"); }\n" +" this.DOMSearchBox = function()\n" +" { return document.getElementById(\"MSearchBox\"); }\n" +" this.OnSearchFieldFocus = function(isActive)\n" +" {\n" +" if (isActive)\n" +" {\n" +" this.DOMSearchBox().className = 'MSearchBoxActive';\n" +" var searchField = this.DOMSearchField();\n" +" if (searchField.value == this.searchLabel) \n" +" {\n" +" searchField.value = '';\n" +" }\n" +" }\n" +" else\n" +" {\n" +" this.DOMSearchBox().className = 'MSearchBoxInactive';\n" +" this.DOMSearchField().value = this.searchLabel;\n" +" }\n" +" }\n" +"}\n" +"\n" +"function trim(s) {\n" +" return s?s.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, ''):'';\n" +"}\n" +"\n" +"function getURLParameter(name) {\n" +" return decodeURIComponent((new RegExp('[?|&]'+name+\n" +" '='+'([^&;]+?)(&|#|;|$)').exec(location.search)\n" +" ||[,\"\"])[1].replace(/\\+/g, '%20'))||null;\n" +"}\n" +"\n" +"var entityMap = {\n" +" \"&\": \"&\",\n" +" \"<\": \"<\",\n" +" \">\": \">\",\n" +" '\"': '"',\n" +" \"'\": ''',\n" +" \"/\": '/'\n" +"};\n" +"\n" +"function escapeHtml(s) {\n" +" return String(s).replace(/[&<>\"'\\/]/g, function (s) {\n" +" return entityMap[s];\n" +" });\n" +"}\n" +"\n" +"function searchFor(query,page,count) {\n" +" $.getJSON(serverUrl+\"?cb=?\",\n" +" {\n" +" n:count,\n" +" p:page,\n" +" q:query\n" +" },\n" +" function(data) {\n" +" var results = $('#searchresults');\n" +" $('#MSearchField').val(query);\n" +" if (data.hits>0) {\n" +" if (data.hits==1) {\n" +" results.html('<p>'+searchResultsText[1]+'</p>');\n" +" } else {\n" +" results.html('<p>'+searchResultsText[2].replace(/\\$num/,data.hits)+'</p>');\n" +" }\n" +" var r='<table>';\n" +" $.each(data.items, function(i,item){\n" +" var prefix = tagMap[item.tag];\n" +" if (prefix) prefix+='/'; else prefix='';\n" +" r+='<tr class=\"searchresult\">'+\n" +" '<td align=\"right\">'+(data.first+i+1)+'.</td>'+\n" +" '<td>'+escapeHtml(item.type)+' '+\n" +" '<a href=\"'+escapeHtml(prefix+item.url)+\n" +" '\">'+escapeHtml(item.name)+'</a>';\n" +" if (item.type==\"source\") {\n" +" var l=item.url.match(/[1-9][0-9]*$/);\n" +" if (l) r+=' at line '+parseInt(l[0]);\n" +" }\n" +" r+='</td>';\n" +" for (var i=0;i<item.fragments.length;i++)\n" +" {\n" +" r+='<tr><td></td><td>'+item.fragments[i]+'</td></tr>';\n" +" }\n" +" r+='</tr>';\n" +" });\n" +" r+='</table>';\n" +" if (data.pages>1) // write multi page navigation bar\n" +" {\n" +" r+='<div class=\"searchpages\">';\n" +" if (data.page>0)\n" +" {\n" +" r+='<span class=\"pages\"><a href=\"javascript:searchFor(\\''+escapeHtml(query)+'\\','+(page-1).toString()+','+count.toString()+')\">«</a></span> ';\n" +" }\n" +" var firstPage = data.page-5;\n" +" var lastPage = data.page+5;\n" +" if (firstPage<0)\n" +" {\n" +" lastPage-=firstPage;\n" +" firstPage=0;\n" +" } \n" +" if (lastPage>data.pages)\n" +" {\n" +" lastPage=data.pages;\n" +" }\n" +" for(var i=firstPage;i<lastPage;i++)\n" +" {\n" +" if (i==data.page)\n" +" {\n" +" r+='<span class=\"pages\"><b>'+(i+1).toString()+'</b></span> ';\n" +" }\n" +" else\n" +" {\n" +" r+='<span class=\"pages\"><a href=\"javascript:searchFor(\\''+escapeHtml(query)+'\\','+i.toString()+','+count.toString()+')\">'+(i+1).toString()+'</a></span> ';\n" +" }\n" +" }\n" +" if (data.page+1<data.pages)\n" +" {\n" +" r+='<span class=\"pages\"><a href=\"javascript:searchFor(\\''+escapeHtml(query)+'\\','+(page+1).toString()+','+count.toString()+')\">»</a></span>';\n" +" }\n" +" r+='</div>';\n" +" }\n" +" results.append(r);\n" +" } else {\n" +" results.html('<p>'+searchResultsText[0]+'</p>');\n" +" }\n" +" });\n" +"}\n" diff --git a/src/filedef.cpp b/src/filedef.cpp index 58e3c23..331c792 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -62,6 +62,8 @@ class DevNullCodeDocInterface : public CodeOutputInterface virtual void endFontClass() {} virtual void writeCodeAnchor(const char *) {} virtual void linkableSymbol(int, const char *,Definition *,Definition *) {} + virtual void setCurrentDoc(Definition *,const char *,bool) {} + virtual void addWord(const char *,bool) {} }; //--------------------------------------------------------------------------- diff --git a/src/groupdef.cpp b/src/groupdef.cpp index c0a6abb..a72a19b 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -934,8 +934,8 @@ void GroupDef::writeDocumentation(OutputList &ol) ol.disable(OutputGenerator::Man); ol.parseText(title); ol.popGeneratorState(); - ol.endTitleHead(getOutputFileBase(),title); addGroupListToTitle(ol,this); + ol.endTitleHead(getOutputFileBase(),title); ol.endHeaderSection(); ol.startContents(); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 288673b..90d9f84 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -98,6 +98,9 @@ static const char dynsections_script[]= #include "dynsections_js.h" ; +static const char extsearch_script[]= +#include "extsearch_js.h" +; static QCString g_header; static QCString g_footer; @@ -876,9 +879,19 @@ static void writeClientSearchBox(FTextStream &t,const char *relPath) static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch) { + static bool externalSearch = Config_getBool("EXTERNAL_SEARCH"); t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n"; t << " <div class=\"left\">\n"; - t << " <form id=\"FSearchBox\" action=\"" << relPath << "search.php\" method=\"get\">\n"; + t << " <form id=\"FSearchBox\" action=\"" << relPath; + if (externalSearch) + { + t << "search" << Doxygen::htmlFileExtension; + } + else + { + t << "search.php"; + } + t << "\" method=\"get\">\n"; t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n"; if (!highlightSearch) { @@ -1699,6 +1712,15 @@ void HtmlGenerator::writeStyleInfo(int part) } Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8()); } + static QCString extraCssFile = Config_getString("HTML_EXTRA_STYLESHEET"); + if (!extraCssFile.isEmpty()) + { + QFileInfo fi(extraCssFile); + if (fi.exists()) + { + Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8()); + } + } } } @@ -2950,7 +2972,7 @@ void HtmlGenerator::writeSearchPage() t << " ),\n"; t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n"; t << " 'search' => \"" << theTranslator->trSearch() << "\",\n"; - t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("",""), "\"","\\\""), "\n","\\n") << "\",\n"; + t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n"; t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n"; t << ");\n\n"; t << "</script>\n"; @@ -2984,24 +3006,16 @@ void HtmlGenerator::writeSearchPage() t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " << versionString << " -->" << endl; - //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); - static bool searchEngine = Config_getBool("SEARCHENGINE"); - if (searchEngine /* && !generateTreeView*/) - { - t << "<script type=\"text/javascript\">\n"; - t << "var searchBox = new SearchBox(\"searchBox\", \"" - << "search\",false,'" << theTranslator->trSearch() << "');\n"; - t << "</script>\n"; - } + t << "<script type=\"text/javascript\">\n"; + t << "var searchBox = new SearchBox(\"searchBox\", \"" + << "search\",false,'" << theTranslator->trSearch() << "');\n"; + t << "</script>\n"; if (!Config_getBool("DISABLE_INDEX")) { writeDefaultQuickLinks(t,TRUE,HLI_Search,0,""); } else { - //t << " \n<div class=\"qindex\">\n"; - //t << " <form class=\"search\" action=\"search.php\" " - // << "method=\"get\">\n"; t << "</div>" << endl; } @@ -3010,8 +3024,6 @@ void HtmlGenerator::writeSearchPage() t << "main();\n"; t << "</script>\n"; - writeSearchInfo(t,""); - // Write empty navigation path, to make footer connect properly if (generateTreeView) { @@ -3027,37 +3039,123 @@ void HtmlGenerator::writeSearchPage() if (sf.open(IO_WriteOnly)) { FTextStream t(&sf); - t << "function SearchBox(name, resultsPath, inFrame, label)\n"; - t << "{\n"; - t << " this.searchLabel = label;\n"; - t << " this.DOMSearchField = function()\n"; - t << " { return document.getElementById(\"MSearchField\"); }\n"; - t << " this.DOMSearchBox = function()\n"; - t << " { return document.getElementById(\"MSearchBox\"); }\n"; - t << " this.OnSearchFieldFocus = function(isActive)\n"; - t << " {\n"; - t << " if (isActive)\n"; - t << " {\n"; - t << " this.DOMSearchBox().className = 'MSearchBoxActive';\n"; - t << " var searchField = this.DOMSearchField();\n"; - t << " if (searchField.value == this.searchLabel) \n"; - t << " {\n"; - t << " searchField.value = '';\n"; - t << " }\n"; - t << " }\n"; - t << " else\n"; - t << " {\n"; - t << " this.DOMSearchBox().className = 'MSearchBoxInactive';\n"; - t << " this.DOMSearchField().value = this.searchLabel;\n"; - t << " }\n"; - t << " }\n"; - t << "}\n"; + t << extsearch_script; } else { err("Failed to open file '%s' for writing...\n",scriptName.data()); } +} + +void HtmlGenerator::writeExternalSearchPage() +{ + static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); + QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + FTextStream t(&f); + t << substituteHtmlKeywords(g_header,"Search",""); + + t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " + << versionString << " -->" << endl; + t << "<script type=\"text/javascript\">\n"; + t << "var searchBox = new SearchBox(\"searchBox\", \"" + << "search\",false,'" << theTranslator->trSearch() << "');\n"; + t << "</script>\n"; + if (!Config_getBool("DISABLE_INDEX")) + { + writeDefaultQuickLinks(t,TRUE,HLI_Search,0,""); + t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n"; + t << " </form>\n"; + t << " </div><div class=\"right\"></div>\n"; + t << " </div>\n"; + t << " </li>\n"; + t << " </ul>\n"; + t << " </div>\n"; + t << "</div>\n"; + } + else + { + t << "</div>" << endl; + } + t << writeSplitBarAsString("search",""); + t << "<div class=\"header\">" << endl; + t << " <div class=\"headertitle\">" << endl; + t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl; + t << " </div>" << endl; + t << "</div>" << endl; + t << "<div class=\"contents\">" << endl; + + t << "<div id=\"searchresults\"></div>" << endl; + t << "</div>" << endl; + + if (generateTreeView) + { + t << "</div><!-- doc-contents -->" << endl; + } + writePageFooter(t,"Search","",""); + } + QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js"; + QFile sf(scriptName); + if (sf.open(IO_WriteOnly)) + { + FTextStream t(&sf); + t << "var searchResultsText=[" + << "\"" << theTranslator->trSearchResults(0) << "\"," + << "\"" << theTranslator->trSearchResults(1) << "\"," + << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl; + t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl; + t << "var tagMap = {" << endl; + // add standard tag file mappings + QDictIterator<QCString> it(Doxygen::tagDestinationDict); + QCString *dest; + bool first=TRUE; + for (it.toFirst();(dest=it.current());++it) + { + if (!first) t << "," << endl; + t << " \"" << it.currentKey() << "\": \"" << *dest << "\""; + first=FALSE; + } + // add additional user specified mappings + QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS"); + char *ml=extraSearchMappings.first(); + while (ml) + { + QCString mapLine = ml; + int eqPos = mapLine.find('='); + if (eqPos!=-1) // tag command contains a destination + { + QCString tagName = mapLine.left(eqPos).stripWhiteSpace(); + QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace(); + if (!tagName.isEmpty() && Doxygen::tagDestinationDict.find(tagName)==0) + { + if (!first) t << "," << endl; + t << " \"" << tagName << "\": \"" << destName << "\""; + first=FALSE; + } + } + ml=extraSearchMappings.next(); + } + if (!first) t << endl; + t << "};" << endl << endl; + t << extsearch_script; + t << endl; + t << "$(document).ready(function() {" << endl; + t << " var query = trim(getURLParameter('query'));" << endl; + t << " if (query) {" << endl; + t << " searchFor(query,0,20);" << endl; + t << " } else {" << endl; + t << " var results = $('#results');" << endl; + t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl; + t << " }" << endl; + t << "});" << endl; + } + else + { + err("Failed to open file '%s' for writing...\n",scriptName.data()); + } } void HtmlGenerator::startConstraintList(const char *header) @@ -3284,3 +3382,19 @@ void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritI t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n"; } +void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) +{ + if (Doxygen::searchIndex) + { + Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile); + } +} + +void HtmlGenerator::addWord(const char *word,bool hiPriority) +{ + if (Doxygen::searchIndex) + { + Doxygen::searchIndex->addWord(word,hiPriority); + } +} + diff --git a/src/htmlgen.h b/src/htmlgen.h index 78a4d0c..17f12fb 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -48,6 +48,8 @@ class HtmlCodeGenerator : public CodeOutputInterface void endFontClass(); void writeCodeAnchor(const char *anchor); void linkableSymbol(int,const char *,Definition *,Definition *); + void setCurrentDoc(Definition *,const char *,bool) {} + void addWord(const char *,bool) {} private: void docify(const char *str); @@ -71,6 +73,7 @@ class HtmlGenerator : public OutputGenerator static void writeSearchInfo(FTextStream &t,const QCString &relPath); static void writeSearchData(const char *dir); static void writeSearchPage(); + static void writeExternalSearchPage(); static QCString writeLogoAsString(const char *path); static QCString writeSplitBarAsString(const char *name,const char *relpath); @@ -111,6 +114,8 @@ class HtmlGenerator : public OutputGenerator { m_codeGen.linkableSymbol(line,symName,symDef,context); } // --------------------------- + void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile); + void addWord(const char *word,bool hiPriority); void writeDoc(DocNode *,Definition *,MemberDef *); void startFile(const char *name,const char *manName,const char *title); diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 2fccdd6..945a7c5 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -460,7 +460,6 @@ void HtmlHelp::createProjectFile() FTextStream t(&f); QCString indexName="index"+Doxygen::htmlFileExtension; - //if (Config_getBool("GENERATE_TREEVIEW")) indexName="main"+Doxygen::htmlFileExtension; t << "[OPTIONS]\n"; if (!Config_getString("CHM_FILE").isEmpty()) { @@ -496,52 +495,6 @@ void HtmlHelp::createProjectFile() t << s << endl; s = indexFiles.next(); } -#if 0 - // items not found by the html help compiler scan. - t << "tabs.css" << endl; - t << "tab_a.png" << endl; - t << "tab_b.png" << endl; - t << "tab_h.png" << endl; - t << "tab_s.png" << endl; - t << "nav_h.png" << endl; - t << "nav_f.png" << endl; - t << "bc_s.png" << endl; - if (Config_getBool("HTML_DYNAMIC_SECTIONS")) - { - t << "open.png" << endl; - t << "closed.png" << endl; - } - if (Config_getBool("GENERATE_HTMLHELP")) - { - t << "ftv2blank.png" << endl; - t << "ftv2doc.png" << endl; - t << "ftv2folderclosed.png" << endl; - t << "ftv2folderopen.png" << endl; - t << "ftv2lastnode.png" << endl; - t << "ftv2link.png" << endl; - t << "ftv2mlastnode.png" << endl; - t << "ftv2mnode.png" << endl; - t << "ftv2node.png" << endl; - t << "ftv2plastnode.png" << endl; - t << "ftv2pnode.png" << endl; - t << "ftv2vertline.png" << endl; - } - if (Config_getBool("SEARCHENGINE")) - { - t << "search_l.png" << endl; - t << "search_m.png" << endl; - t << "search_r.png" << endl; - if (Config_getBool("SERVER_BASED_SEARCH")) - { - t << "mag.png" << endl; - } - else - { - t << "mag_sel.png" << endl; - t << "close.png" << endl; - } - } -#endif uint i; for (i=0;i<imageFiles.count();i++) { diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 5fc2361..f3610a3 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -1663,7 +1663,7 @@ void LatexDocVisitor::startDotFile(const QCString &fileName, } else { - m_t << "[width=\\textwidth]"; + m_t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; } m_t << "{" << baseName << "}"; @@ -1727,7 +1727,7 @@ void LatexDocVisitor::startMscFile(const QCString &fileName, } else { - m_t << "[width=\\textwidth]"; + m_t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; } m_t << "{" << baseName << "}"; diff --git a/src/latexgen.h b/src/latexgen.h index 1fe92dd..76069d3 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -268,6 +268,9 @@ class LatexGenerator : public OutputGenerator void writeCodeAnchor(const char *) {} void linkableSymbol(int,const char *,Definition *,Definition *) {} + void setCurrentDoc(Definition *,const char *,bool) {} + void addWord(const char *,bool) {} + private: LatexGenerator(const LatexGenerator &); diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 546f6ea..39d303a 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -116,6 +116,7 @@ HEADERS = arguments.h \ searchindex.h \ search_css.h \ search_js.h \ + extsearch_js.h \ search_functions_php.h \ search_opensearch_php.h \ section.h \ diff --git a/src/libdoxygen.t.in b/src/libdoxygen.t.in index 2ffb5cb..e11e010 100644 --- a/src/libdoxygen.t.in +++ b/src/libdoxygen.t.in @@ -138,6 +138,9 @@ search_js.h: search.js search_css.h: search.css cat search.css | $(TO_C_CMD) >search_css.h +extsearch_js.h: extsearch.js + cat extsearch.js | $(TO_C_CMD) >extsearch_js.h + doxygen_css.h: doxygen.css cat doxygen.css | $(TO_C_CMD) >doxygen_css.h diff --git a/src/mangen.h b/src/mangen.h index a4af56c..f40d0c3 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -257,6 +257,8 @@ class ManGenerator : public OutputGenerator void writeCodeAnchor(const char *) {} void linkableSymbol(int,const char *,Definition *,Definition *) {} + void setCurrentDoc(Definition *,const char *,bool) {} + void addWord(const char *,bool) {} private: bool firstCol; diff --git a/src/markdown.cpp b/src/markdown.cpp index 2571a1a..15b36a3 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -299,6 +299,10 @@ static int findEmphasisChar(const char *data, int size, char c, int c_size) i++; } } + else if (i<size-1 && isIdChar(i+1)) // @cmd, stop processing, see bug 690385 + { + return 0; + } else { i++; @@ -1700,7 +1704,8 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size) else if (j>0 && data[j-1]=='>') indent=j+1; j++; } - if (j>0 && data[j-1]=='>') // disqualify last > if not followed by space + if (j>0 && data[j-1]=='>' && + !(j==size || data[j]=='\n')) // disqualify last > if not followed by space { indent--; j--; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index d658c4a..1482180 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -2350,6 +2350,10 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (title.at(0)=='@') { ldef = title = "anonymous enum"; + if (!m_impl->enumBaseType.isEmpty()) + { + ldef+=" : "+m_impl->enumBaseType; + } } else { @@ -2897,6 +2901,10 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container) ol.startInlineMemberName(); ol.docify(doxyName); + if (isVariable() && argsString() && !isObjCMethod()) + { + linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,argsString()); + } if (!m_impl->bitfields.isEmpty()) // add bitfields { linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields.simplifyWhiteSpace()); @@ -3545,13 +3553,13 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, typeDecl.endBold(); } typeDecl.writeChar(' '); - if (!m_impl->enumBaseType.isEmpty()) - { - typeDecl.writeChar(':'); - typeDecl.writeChar(' '); - typeDecl.docify(m_impl->enumBaseType); - typeDecl.writeChar(' '); - } + } + if (!m_impl->enumBaseType.isEmpty()) + { + typeDecl.writeChar(':'); + typeDecl.writeChar(' '); + typeDecl.docify(m_impl->enumBaseType); + typeDecl.writeChar(' '); } uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE"); @@ -4987,6 +4995,14 @@ void MemberDef::_addToSearchIndex() if (ln!=qn) { Doxygen::searchIndex->addWord(qn,TRUE); + if (getClassDef()) + { + Doxygen::searchIndex->addWord(getClassDef()->displayName(),TRUE); + } + else if (getNamespaceDef()) + { + Doxygen::searchIndex->addWord(getNamespaceDef()->displayName(),TRUE); + } } } } diff --git a/src/navtree.js b/src/navtree.js index d4b241a..3d8134a 100644 --- a/src/navtree.js +++ b/src/navtree.js @@ -75,24 +75,22 @@ function getScript(scriptName,func,show) function createIndent(o,domNode,node,level) { - if (node.parentNode && node.parentNode.parentNode) { - createIndent(o,domNode,node.parentNode,level+1); - } + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } var imgNode = document.createElement("img"); - imgNode.width = 16; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.width = 16; imgNode.height = 22; - if (level==0 && node.childrenData) { + imgNode.border = 0; + if (node.childrenData) { node.plus_img = imgNode; node.expandToggle = document.createElement("a"); node.expandToggle.href = "javascript:void(0)"; node.expandToggle.onclick = function() { if (node.expanded) { $(node.getChildrenUL()).slideUp("fast"); - if (node.isLast) { - node.plus_img.src = node.relpath+"ftv2plastnode.png"; - } else { - node.plus_img.src = node.relpath+"ftv2pnode.png"; - } + node.plus_img.src = node.relpath+"ftv2pnode.png"; node.expanded = false; } else { expandNode(o, node, false, false); @@ -100,33 +98,11 @@ function createIndent(o,domNode,node,level) } node.expandToggle.appendChild(imgNode); domNode.appendChild(node.expandToggle); + imgNode.src = node.relpath+"ftv2pnode.png"; } else { + imgNode.src = node.relpath+"ftv2node.png"; domNode.appendChild(imgNode); - } - if (level==0) { - if (node.isLast) { - if (node.childrenData) { - imgNode.src = node.relpath+"ftv2plastnode.png"; - } else { - imgNode.src = node.relpath+"ftv2lastnode.png"; - domNode.appendChild(imgNode); - } - } else { - if (node.childrenData) { - imgNode.src = node.relpath+"ftv2pnode.png"; - } else { - imgNode.src = node.relpath+"ftv2node.png"; - domNode.appendChild(imgNode); - } - } - } else { - if (node.isLast) { - imgNode.src = node.relpath+"ftv2blank.png"; - } else { - imgNode.src = node.relpath+"ftv2vertline.png"; - } - } - imgNode.border = "0"; + } } var animationInProgress = false; @@ -364,7 +340,7 @@ function showNode(o, node, index, hash) },true); } else { var rootBase = stripPath(o.toroot.replace(/\..+$/, '')); - if (rootBase=="index" || rootBase=="pages") { + if (rootBase=="index" || rootBase=="pages" || rootBase=="search") { expandNode(o, n, true, true); } selectAndHighlight(hash,n); @@ -420,6 +396,7 @@ function navTo(o,root,hash,relpath) var url=root+hash; var i=-1; while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index if (navTreeSubIndices[i]) { gotoNode(o,i,root,hash,relpath) } else { diff --git a/src/navtree_js.h b/src/navtree_js.h index b0c6d7c..2e4df6a 100644 --- a/src/navtree_js.h +++ b/src/navtree_js.h @@ -75,24 +75,22 @@ "\n" "function createIndent(o,domNode,node,level)\n" "{\n" -" if (node.parentNode && node.parentNode.parentNode) {\n" -" createIndent(o,domNode,node.parentNode,level+1);\n" -" }\n" +" var level=-1;\n" +" var n = node;\n" +" while (n.parentNode) { level++; n=n.parentNode; }\n" " var imgNode = document.createElement(\"img\");\n" -" imgNode.width = 16;\n" +" imgNode.style.paddingLeft=(16*level).toString()+'px';\n" +" imgNode.width = 16;\n" " imgNode.height = 22;\n" -" if (level==0 && node.childrenData) {\n" +" imgNode.border = 0;\n" +" if (node.childrenData) {\n" " node.plus_img = imgNode;\n" " node.expandToggle = document.createElement(\"a\");\n" " node.expandToggle.href = \"javascript:void(0)\";\n" " node.expandToggle.onclick = function() {\n" " if (node.expanded) {\n" " $(node.getChildrenUL()).slideUp(\"fast\");\n" -" if (node.isLast) {\n" -" node.plus_img.src = node.relpath+\"ftv2plastnode.png\";\n" -" } else {\n" -" node.plus_img.src = node.relpath+\"ftv2pnode.png\";\n" -" }\n" +" node.plus_img.src = node.relpath+\"ftv2pnode.png\";\n" " node.expanded = false;\n" " } else {\n" " expandNode(o, node, false, false);\n" @@ -100,33 +98,11 @@ " }\n" " node.expandToggle.appendChild(imgNode);\n" " domNode.appendChild(node.expandToggle);\n" +" imgNode.src = node.relpath+\"ftv2pnode.png\";\n" " } else {\n" +" imgNode.src = node.relpath+\"ftv2node.png\";\n" " domNode.appendChild(imgNode);\n" -" }\n" -" if (level==0) {\n" -" if (node.isLast) {\n" -" if (node.childrenData) {\n" -" imgNode.src = node.relpath+\"ftv2plastnode.png\";\n" -" } else {\n" -" imgNode.src = node.relpath+\"ftv2lastnode.png\";\n" -" domNode.appendChild(imgNode);\n" -" }\n" -" } else {\n" -" if (node.childrenData) {\n" -" imgNode.src = node.relpath+\"ftv2pnode.png\";\n" -" } else {\n" -" imgNode.src = node.relpath+\"ftv2node.png\";\n" -" domNode.appendChild(imgNode);\n" -" }\n" -" }\n" -" } else {\n" -" if (node.isLast) {\n" -" imgNode.src = node.relpath+\"ftv2blank.png\";\n" -" } else {\n" -" imgNode.src = node.relpath+\"ftv2vertline.png\";\n" -" }\n" -" }\n" -" imgNode.border = \"0\";\n" +" } \n" "}\n" "\n" "var animationInProgress = false;\n" @@ -364,7 +340,7 @@ " },true);\n" " } else {\n" " var rootBase = stripPath(o.toroot.replace(/\\..+$/, ''));\n" -" if (rootBase==\"index\" || rootBase==\"pages\") {\n" +" if (rootBase==\"index\" || rootBase==\"pages\" || rootBase==\"search\") {\n" " expandNode(o, n, true, true);\n" " }\n" " selectAndHighlight(hash,n);\n" @@ -420,6 +396,7 @@ " var url=root+hash;\n" " var i=-1;\n" " while (NAVTREEINDEX[i+1]<=url) i++;\n" +" if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index\n" " if (navTreeSubIndices[i]) {\n" " gotoNode(o,i,root,hash,relpath)\n" " } else {\n" diff --git a/src/outputgen.h b/src/outputgen.h index df4c4e2..8d67e3d 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -73,6 +73,8 @@ class CodeOutputInterface virtual void writeCodeAnchor(const char *name) = 0; virtual void linkableSymbol(int line,const char *symName, Definition *symDef,Definition *context) = 0; + virtual void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) = 0; + virtual void addWord(const char *word,bool hiPriority) = 0; }; /** Base Interface used for generating output outside of the diff --git a/src/outputlist.cpp b/src/outputlist.cpp index adab93b..5ea2a21 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -321,6 +321,7 @@ FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3) FORALL3(const char *a1,int a2,const char *a3,a1,a2,a3) FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3) FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3) +FORALL3(Definition *a1,const char *a2,bool a3,a1,a2,a3) FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) FORALL4(const char *a1,const char *a2,const char *a3,int a4,a1,a2,a3,a4) diff --git a/src/outputlist.h b/src/outputlist.h index 90a3723..23221d3 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -470,6 +470,11 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endFontClass); } void writeCodeAnchor(const char *name) { forall(&OutputGenerator::writeCodeAnchor,name); } + void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) + { forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); } + void addWord(const char *word,bool hiPriority) + { forall(&OutputGenerator::addWord,word,hiPriority); } + void startPlainFile(const char *name) { OutputGenerator *og=outputs->first(); @@ -529,6 +534,7 @@ class OutputList : public OutputDocInterface FORALLPROTO3(uchar,uchar,uchar); FORALLPROTO3(const char *,const char *,const char *); FORALLPROTO3(const ClassDiagram &,const char *,const char *); + FORALLPROTO3(Definition*,const char *,bool); FORALLPROTO4(SectionTypes,const char *,const char *,const char *); FORALLPROTO4(const char *,const char *,const char *,const char *); FORALLPROTO4(const char *,const char *,const char *,bool); diff --git a/src/portable.cpp b/src/portable.cpp index bb13ddb..554bb0b 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -409,3 +409,22 @@ void portable_sleep(int ms) usleep(1000*ms); #endif } + +bool portable_isAbsolutePath(const char *fileName) +{ +# ifdef _WIN32 + if (isalpha (fileName [0]) && fileName[1] == ':') + fileName += 2; +# endif + char const fst = fileName [0]; + if (fst == '/') { + return true; + } +# ifdef _WIN32 + if (fst == '\\') + return true; +# endif + return false; +} + + diff --git a/src/portable.h b/src/portable.h index de798dd..1471ce1 100644 --- a/src/portable.h +++ b/src/portable.h @@ -34,6 +34,7 @@ void portable_sysTimerStart(); void portable_sysTimerStop(); double portable_getSysElapsedTime(); void portable_sleep(int ms); +bool portable_isAbsolutePath(const char *fileName); extern "C" { void * portable_iconv_open(const char* tocode, const char* fromcode); @@ -42,6 +43,5 @@ extern "C" { int portable_iconv_close (void *cd); } - #endif @@ -761,7 +761,7 @@ static inline void addTillEndOfString(const QCString &expr,QCString *rest, uint &pos,char term,QCString &arg) { int cc; - while ((cc=getNextChar(expr,rest,pos))!=EOF) + while ((cc=getNextChar(expr,rest,pos))!=EOF && cc!=0) { if (cc=='\\') arg+=(char)cc,cc=getNextChar(expr,rest,pos); else if (cc==term) return; @@ -804,7 +804,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int // PHASE 1: read the macro arguments if (def->nargs==0) { - while ((cc=getNextChar(expr,rest,j))!=EOF) + while ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0) { char c = (char)cc; if (c==')') break; @@ -813,7 +813,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int else { while (!done && (argCount<def->nargs || def->varArgs) && - ((cc=getNextChar(expr,rest,j))!=EOF) + ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0) ) { char c=(char)cc; @@ -822,7 +822,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int int level=1; arg+=c; //char term='\0'; - while ((cc=getNextChar(expr,rest,j))!=EOF) + while ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0) { char c=(char)cc; //printf("processing %c: term=%c (%d)\n",c,term,term); @@ -871,14 +871,14 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int { arg+=c; bool found=FALSE; - while (!found && (cc=getNextChar(expr,rest,j))!=EOF) + while (!found && (cc=getNextChar(expr,rest,j))!=EOF && cc!=0) { found = cc=='"'; if (cc=='\\') { c=(char)cc; arg+=c; - if ((cc=getNextChar(expr,rest,j))==EOF) break; + if ((cc=getNextChar(expr,rest,j))==EOF || cc==0) break; } c=(char)cc; arg+=c; @@ -888,14 +888,14 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int { arg+=c; bool found=FALSE; - while (!found && (cc=getNextChar(expr,rest,j))!=EOF) + while (!found && (cc=getNextChar(expr,rest,j))!=EOF && cc!=0) { found = cc=='\''; if (cc=='\\') { c=(char)cc; arg+=c; - if ((cc=getNextChar(expr,rest,j))==EOF) break; + if ((cc=getNextChar(expr,rest,j))==EOF || cc==0) break; } c=(char)cc; arg+=c; @@ -2498,12 +2498,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) outputArray(yytext,yyleng); BEGIN(CondLine); } -<SkipCComment,SkipCPPComment>[\\@]"condnot"[ \t]+ { // conditional section - guardType = Guard_CondNot; - g_condCtx = YY_START; - outputArray(yytext,(int)yyleng); - BEGIN(CondLine); - } <CondLine>[!()&| \ta-z_A-Z0-9.\-]+ { startCondSection(yytext); outputArray(yytext,(int)yyleng); @@ -2558,6 +2552,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } <CopyCComment>\n { g_yyLineNr++; + outputChar('\n'); g_defLitText+=yytext; g_defText+=' '; } @@ -2809,7 +2804,7 @@ static int getNextChar(const QCString &expr,QCString *rest,uint &pos) else { int cc=yyinput(); - //printf("%c=yyinput()\n",cc); + //printf("%d=yyinput() %d\n",cc,EOF); return cc; } } diff --git a/src/rtfgen.h b/src/rtfgen.h index 92b858f..784cfcc 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -258,6 +258,8 @@ class RTFGenerator : public OutputGenerator void writeCodeAnchor(const char *) {} void linkableSymbol(int,const char *,Definition *,Definition *) {} + void setCurrentDoc(Definition *,const char *,bool) {} + void addWord(const char *,bool) {} static bool preProcessFileInplace(const char *path,const char *name); diff --git a/src/scanner.l b/src/scanner.l index c711765..8efca45 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -3053,13 +3053,24 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <FindMembers>":" { - if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" + if (current->type.isEmpty() && + current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}' { - addType(current); - current->name.sprintf("__pad%d__",padCount++); + current->section=Entry::ENUM_SEC; + current->name.resize(0); + current->args.resize(0); + BEGIN(EnumBaseType); } - BEGIN(BitFields); - current->bitfields+=":"; + else + { + if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" + { + addType(current); + current->name.sprintf("__pad%d__",padCount++); + } + BEGIN(BitFields); + current->bitfields+=":"; + } } <BitFields>. { current->bitfields+=*yytext; @@ -3069,6 +3080,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <EnumBaseType>\n { lineCount(); + current->args+=' '; } <FindMembers>[;,] { QCString oldType = current->type; @@ -3428,7 +3440,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" current->program += yytext; } } -<ReadBody,ReadNSBody,ReadBodyIntf>"{" { current->program += yytext ; +<ReadBody,ReadNSBody,ReadBodyIntf>"{" { current->program += yytext ; ++curlyCount ; } <ReadBodyIntf>"}" { @@ -4672,11 +4684,11 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } } } +<SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647) + lineCount(); + ++curlyCount; + } <SkipInits>"{" { // C++11 style initializer - //addToBody(yytext); - //lastCurlyContext = FindMembers; - //curlyCount=0; - //BEGIN( SkipCurly ) ; unput('{'); BEGIN( Function ); } diff --git a/src/search.css b/src/search.css index 5e6b12f..e467ae0 100644 --- a/src/search.css +++ b/src/search.css @@ -236,3 +236,36 @@ DIV.searchresults { margin-left: 10px; margin-right: 10px; } + +/*---------------- External search page results */ + +.searchresult { + background-color: ##F2; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/src/search_css.h b/src/search_css.h index 9b6656b..9c3b08a 100644 --- a/src/search_css.h +++ b/src/search_css.h @@ -236,3 +236,36 @@ " margin-left: 10px;\n" " margin-right: 10px;\n" "}\n" +"\n" +"/*---------------- External search page results */\n" +"\n" +".searchresult {\n" +" background-color: ##F2;\n" +"}\n" +"\n" +".pages b {\n" +" color: white;\n" +" padding: 5px 5px 3px 5px;\n" +" background-image: url(\"../tab_a.png\");\n" +" background-repeat: repeat-x;\n" +" text-shadow: 0 1px 1px #000000;\n" +"}\n" +"\n" +".pages {\n" +" line-height: 17px;\n" +" margin-left: 4px;\n" +" text-decoration: none;\n" +"}\n" +"\n" +".hl {\n" +" font-weight: bold;\n" +"}\n" +"\n" +"#searchresults {\n" +" margin-bottom: 20px;\n" +"}\n" +"\n" +".searchpages {\n" +" margin-top: 10px;\n" +"}\n" +"\n" diff --git a/src/search_functions.php b/src/search_functions.php index f5c3688..acd7f3c 100644 --- a/src/search_functions.php +++ b/src/search_functions.php @@ -17,14 +17,6 @@ function end_form($value) function end_page() { - //global $config; - //global $translator; - //if ($config['GENERATE_TREEVIEW']) - //{ - // echo "</div>\n<div id=\"nav-path\" class=\"navpath\">\n <ul>\n <li class=\"footer\">"; - // echo $translator['logo']; - // echo "</li>\n </ul>\n</div>"; - //} echo "</body></html>"; } diff --git a/src/search_functions_php.h b/src/search_functions_php.h index 1b72ae7..b09c259 100644 --- a/src/search_functions_php.h +++ b/src/search_functions_php.h @@ -17,14 +17,6 @@ "\n" "function end_page()\n" "{\n" -" //global $config;\n" -" //global $translator;\n" -" //if ($config['GENERATE_TREEVIEW'])\n" -" //{\n" -" // echo \"</div>\\n<div id=\\\"nav-path\\\" class=\\\"navpath\\\">\\n <ul>\\n <li class=\\\"footer\\\">\";\n" -" // echo $translator['logo'];\n" -" // echo \"</li>\\n </ul>\\n</div>\";\n" -" //}\n" " echo \"</body></html>\";\n" "}\n" "\n" diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 42c9114..fef0f13 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -192,9 +192,9 @@ static int charsToIndex(const char *word) //return h; // Simple hashing that allows for substring searching - uint c1=word[0]; + uint c1=((uchar *)word)[0]; if (c1==0) return -1; - uint c2=word[1]; + uint c2=((uchar *)word)[1]; if (c2==0) return -1; return c1*256+c2; } @@ -202,16 +202,16 @@ static int charsToIndex(const char *word) void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse) { static QRegExp nextPart("[_a-z:][A-Z]"); - //printf("SearchIndex::addWord(%s,%d)\n",word,hiPriority); if (word==0 || word[0]=='\0') return; QCString wStr = QCString(word).lower(); + //printf("SearchIndex::addWord(%s,%d) wStr=%s\n",word,hiPriority,wStr.data()); IndexWord *w = m_words[wStr]; if (w==0) { int idx=charsToIndex(wStr); + //fprintf(stderr,"addWord(%s) at index %d\n",word,idx); if (idx<0) return; w = new IndexWord(wStr); - //fprintf(stderr,"addWord(%s) at index %d\n",word,idx); m_index[idx]->append(w); m_words.insert(wStr,w); } @@ -413,6 +413,7 @@ struct SearchDocEntry { QCString type; QCString name; + QCString args; QCString tagFile; QCString url; GrowBuf importantText; @@ -530,10 +531,15 @@ void SearchIndexExternal::setCurrentDoc(Definition *ctx,const char *anchor,bool SearchDocEntry *e = new SearchDocEntry; e->type = isSourceFile ? QCString("source") : definitionToName(ctx); e->name = ctx->qualifiedName(); + if (ctx->definitionType()==Definition::TypeMember) + { + e->args = ((MemberDef*)ctx)->argsString(); + } e->tagFile = tagFile; e->url = url; p->current = e; p->docEntries.append(key,e); + //printf("searchIndexExt %s : %s\n",e->name.data(),e->url.data()); } } @@ -543,6 +549,7 @@ void SearchIndexExternal::addWord(const char *word,bool hiPriority) GrowBuf *pText = hiPriority ? &p->current->importantText : &p->current->normalText; if (pText->getPos()>0) pText->addChar(' '); pText->addStr(word); + //printf("addWord %s\n",word); } void SearchIndexExternal::write(const char *fileName) @@ -562,7 +569,14 @@ void SearchIndexExternal::write(const char *fileName) t << " <doc>" << endl; t << " <field name=\"type\">" << doc->type << "</field>" << endl; t << " <field name=\"name\">" << convertToXML(doc->name) << "</field>" << endl; - t << " <field name=\"tag\">" << convertToXML(doc->tagFile) << "</field>" << endl; + if (!doc->args.isEmpty()) + { + t << " <field name=\"args\">" << convertToXML(doc->args) << "</field>" << endl; + } + if (!doc->tagFile.isEmpty()) + { + t << " <field name=\"tag\">" << convertToXML(doc->tagFile) << "</field>" << endl; + } t << " <field name=\"url\">" << convertToXML(doc->url) << "</field>" << endl; t << " <field name=\"keywords\">" << convertToXML(doc->importantText.get()) << "</field>" << endl; t << " <field name=\"text\">" << convertToXML(doc->normalText.get()) << "</field>" << endl; @@ -1356,12 +1370,19 @@ void writeSearchCategories(FTextStream &t) void initSearchIndexer() { - static bool searchEngine = Config_getBool("SEARCHENGINE"); + static bool searchEngine = Config_getBool("SEARCHENGINE"); static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); + static bool externalSearch = Config_getBool("EXTERNAL_SEARCH"); if (searchEngine && serverBasedSearch) { - //Doxygen::searchIndex = new SearchIndexExternal; - Doxygen::searchIndex = new SearchIndex; + if (externalSearch) // external tools produce search index and engine + { + Doxygen::searchIndex = new SearchIndexExternal; + } + else // doxygen produces search index and engine + { + Doxygen::searchIndex = new SearchIndex; + } } else // no search engine or pure javascript based search function { diff --git a/src/store.cpp b/src/store.cpp index 74719a9..521aa9b 100644 --- a/src/store.cpp +++ b/src/store.cpp @@ -402,21 +402,23 @@ void Store::dumpBlock(portable_off_t s,portable_off_t e) portable_fseek(m_file,s,SEEK_SET); int size = (int)(e-s); uchar *buf = new uchar[size]; - (void)fread(buf,size,1,m_file); - int i,j; - for (i=0;i<size;i+=16) + if (fread(buf,size,1,m_file)==(size_t)size) { - printf("%08x: ",(int)s+i); - for (j=i;j<QMIN(size,i+16);j++) - { - printf("%02x ",buf[i+j]); - } - printf(" "); - for (j=i;j<QMIN(size,i+16);j++) + int i,j; + for (i=0;i<size;i+=16) { - printf("%c",(buf[i+j]>=32 && buf[i+j]<128)?buf[i+j]:'.'); + printf("%08x: ",(int)s+i); + for (j=i;j<QMIN(size,i+16);j++) + { + printf("%02x ",buf[i+j]); + } + printf(" "); + for (j=i;j<QMIN(size,i+16);j++) + { + printf("%c",(buf[i+j]>=32 && buf[i+j]<128)?buf[i+j]:'.'); + } + printf("\n"); } - printf("\n"); } delete[] buf; portable_fseek(m_file,m_cur,SEEK_SET); diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 553d195..42dcf68 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -44,9 +44,13 @@ class TagAnchorInfo { public: - TagAnchorInfo(const QCString &f,const QCString &l) : label(l), fileName(f) {} + TagAnchorInfo(const QCString &f, + const QCString &l, + const QCString &t=QCString()) + : label(l), fileName(f), title(t) {} QCString label; QCString fileName; + QCString title; }; /** List of TagAnchorInfo objects. */ @@ -417,7 +421,7 @@ class TagFileParser : public QXmlDefaultHandler case InFile: m_curFile->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; case InNamespace: m_curNamespace->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; case InGroup: m_curGroup->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; - case InPage: m_curPage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; + case InPage: m_curPage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; case InMember: m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; case InPackage: m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; case InDir: m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break; @@ -485,6 +489,7 @@ class TagFileParser : public QXmlDefaultHandler void startDocAnchor(const QXmlAttributes& attrib ) { m_fileName = attrib.value("file").utf8(); + m_title = attrib.value("title").utf8(); m_curString = ""; } @@ -825,6 +830,7 @@ class TagFileParser : public QXmlDefaultHandler QCString m_curString; QCString m_tagName; QCString m_fileName; + QCString m_title; State m_state; QStack<State> m_stateStack; QXmlLocator *m_locator; @@ -1041,7 +1047,7 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) { //printf("New sectionInfo file=%s anchor=%s\n", // ta->fileName.data(),ta->label.data()); - SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label, + SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->title, SectionInfo::Anchor,0,m_tagName); Doxygen::sectionDict->append(ta->label,si); e->anchors->append(si); diff --git a/src/tclscanner.l b/src/tclscanner.l index aaeac41..c3d5df0 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -1946,7 +1946,7 @@ static void tcl_command_NAMESPACE() { D QCString myNs, myName, myStr; - Entry *myEntryNs=NULL; + //Entry *myEntryNs=NULL; tcl_scan *myScan = tcl.scan.at(0); tcl_codify_cmd("keyword",0); @@ -1967,7 +1967,7 @@ D tcl.entry_current->endBodyLine = tcl.line_body1; tcl.entry_main->addSubEntry(tcl.entry_current); tcl.ns.insert(myName,tcl.entry_current); - myEntryNs = tcl.entry_current; + //myEntryNs = tcl.entry_current; myStr = (*tcl.list_commandwords.at(6)).utf8(); if (tcl.list_commandwords.count() > 7) { diff --git a/src/translator_cn.h b/src/translator_cn.h index 94a40dc..197cfe4 100644 --- a/src/translator_cn.h +++ b/src/translator_cn.h @@ -543,7 +543,7 @@ class TranslatorChinese : public TranslatorAdapter_1_8_2 if (i!=numEntries-1) // not the last entry, so we need a separator { if (i<numEntries-2) // not the fore last entry - result+=","; + result+=","CN_SPC; else // the fore last entry result+=CN_SPC", 以及"CN_SPC; } diff --git a/src/util.cpp b/src/util.cpp index 836ac70..0d48f96 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -7638,4 +7638,3 @@ bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile) ); } - diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index ba8fd1f..0a0141f 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -4087,7 +4087,6 @@ void FlowNode::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc) prev.fill(' ',len+1); Argument *arg; - bool first=TRUE; q+="\n"; for (;(arg=ali.current());++ali) { @@ -4109,7 +4108,6 @@ void FlowNode::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc) attl.prepend(prev.data()); temp+=attl; - first=FALSE; } q+=temp; } diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index e5ac2d7..07ea086 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -404,6 +404,12 @@ class XMLCodeGenerator : public CodeOutputInterface void linkableSymbol(int, const char *,Definition *,Definition *) { } + void setCurrentDoc(Definition *,const char *,bool) + { + } + void addWord(const char *,bool) + { + } void finish() { |