diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2008-09-14 19:14:55 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2008-09-14 19:14:55 (GMT) |
commit | 9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7 (patch) | |
tree | 7c2a1d6f7f4f4a314acdd54d620ac8a75519e369 /src | |
parent | 093ac41f561578b904905e466df307131cd80893 (diff) | |
download | Doxygen-9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7.zip Doxygen-9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7.tar.gz Doxygen-9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7.tar.bz2 |
Release-1.5.6-20080914
Diffstat (limited to 'src')
-rw-r--r-- | src/code.l | 50 | ||||
-rw-r--r-- | src/commentscan.l | 16 | ||||
-rw-r--r-- | src/config.l | 125 | ||||
-rw-r--r-- | src/cppvalue.cpp | 10 | ||||
-rw-r--r-- | src/declinfo.l | 2 | ||||
-rw-r--r-- | src/defargs.l | 18 | ||||
-rw-r--r-- | src/docparser.cpp | 18 | ||||
-rw-r--r-- | src/doctokenizer.l | 11 | ||||
-rw-r--r-- | src/doxygen.cpp | 76 | ||||
-rw-r--r-- | src/doxygen.h | 2 | ||||
-rw-r--r-- | src/htmlgen.cpp | 12 | ||||
-rw-r--r-- | src/htmlgen.h | 1 | ||||
-rw-r--r-- | src/htmlhelp.cpp | 5 | ||||
-rw-r--r-- | src/layout.cpp | 29 | ||||
-rw-r--r-- | src/layout_default.h | 16 | ||||
-rw-r--r-- | src/layout_default.xml | 16 | ||||
-rw-r--r-- | src/memberlist.cpp | 19 | ||||
-rw-r--r-- | src/pagedef.cpp | 4 | ||||
-rw-r--r-- | src/pre.l | 4 | ||||
-rw-r--r-- | src/rtfdocvisitor.cpp | 20 | ||||
-rw-r--r-- | src/scanner.l | 58 | ||||
-rw-r--r-- | src/util.cpp | 151 | ||||
-rw-r--r-- | src/util.h | 8 |
23 files changed, 442 insertions, 229 deletions
@@ -389,7 +389,7 @@ static void pushScope(const char *s) g_classScope += "::"; g_classScope += s; } - //printf("pushScope() result: `%s'\n",g_classScope.data()); + //printf("pushScope(%s) result: `%s'\n",s,g_classScope.data()); } /*! remove the top class/namespace name from the scope */ @@ -441,7 +441,18 @@ static void setClassScope(const QCString &name) // remove template from scope n=n.left(ts)+n.right(n.length()-te-1); } - g_classScope = n; + while (!g_classScopeLengthStack.isEmpty()) + { + popScope(); + } + g_classScope.resize(0); + int i; + while ((i=n.find("::"))!=-1) + { + pushScope(n.left(i)); + n = n.mid(i+2); + } + pushScope(n); //printf("--->New class scope `%s'\n",g_classScope.data()); } @@ -821,7 +832,6 @@ static bool getLinkInScope(const QCString &c, // scope if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) && md->isLinkable()) { - //printf("Found!\n"); if (g_exampleBlock) { QCString anchor; @@ -871,7 +881,7 @@ static bool getLink(const char *className, CodeOutputInterface &ol, const char *text=0) { - //printf("getLink(%s,%s)\n",className,memberName); + //printf("getLink(%s,%s) g_curClassName=%s\n",className,memberName,g_curClassName.data()); QCString m=removeRedundantWhiteSpace(memberName); QCString c=className; if (!getLinkInScope(c,m,memberName,ol,text)) @@ -1201,7 +1211,7 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName) { //CodeClassDef *ccd=0; ClassDef *ccd=0; - QCString locScope=g_classScope.copy(); + QCString locScope=g_classScope; QCString locFunc=removeRedundantWhiteSpace(funcName); //fprintf(stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data()); int len=2; @@ -1209,7 +1219,14 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName) if (i==-1) i=locFunc.findRev("."),len=1; if (i>0) { - locScope=locFunc.left(i); + if (locScope.isEmpty()) + { + locScope=locFunc.left(i); + } + else + { + locScope+="::"+locFunc.left(i); + } locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace(); int ts=locScope.find('<'); // start of template int te=locScope.findRev('>'); // end of template @@ -1650,7 +1667,7 @@ static int yyread(char *buf,int max_size) B [ \t] BN [ \t\n\r] -ID "$"?[a-z_A-Z][a-z_A-Z0-9]* +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID}) @@ -2200,6 +2217,10 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} startFontClass("keywordflow"); codifyLines(yytext); endFontClass(); + // insert the variable in the parent scope, see bug 546158 + g_theVarContext.popScope(); + g_theVarContext.addVariable(g_parmType,g_parmName); + g_theVarContext.pushScope(); g_name.resize(0);g_type.resize(0); } <Body>{FLOWKW}/{BN}*"(" { @@ -2328,6 +2349,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() addType(); generateFunctionLink(*g_code,yytext); + //printf("---> g_classScope=%s\n",g_classScope.data()); //g_theVarContext.addVariable(g_type,yytext); g_bracketCount=0; g_args.resize(0); @@ -2770,7 +2792,9 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} int index = g_name.findRev("::"); if (index!=-1) { - ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,g_name.left(index)); + QCString scope = g_name.left(index); + if (!g_classScope.isEmpty()) scope.prepend(g_classScope+"::"); + ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope); if (cd) { setClassScope(cd->name()); @@ -2885,22 +2909,22 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <SkipInits>{ID} { generateClassOrGlobalLink(*g_code,yytext); } -<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/"(" { +<FuncCall>{ID}/"(" { generateFunctionLink(*g_code,yytext); } -<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") { +<FuncCall>{ID}/("."|"->") { g_name=yytext; generateClassOrGlobalLink(*g_code,yytext); BEGIN( MemberCall2 ); } -<FuncCall,MemberCall2>("("{B}*("*"{B}*)+[a-z_A-Z][a-z_A-Z0-9]*{B}*")"{B}*)/("."|"->") { +<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { g_code->codify(yytext); int s=0;while (!isId(yytext[s])) s++; int e=yyleng-1;while (!isId(yytext[e])) e--; g_name=((QCString)yytext).mid(s,e-s+1); BEGIN( MemberCall2 ); } -<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") { +<MemberCall2>{ID}/([ \t\n]*"(") { if (!g_args.isEmpty()) generateMemberLink(*g_code,g_args,yytext); else @@ -2908,7 +2932,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} g_args.resize(0); BEGIN( FuncCall ); } -<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) { +<MemberCall2>{ID}/([ \t\n]*("."|"->")) { //g_code->codify(yytext); g_name=yytext; generateClassOrGlobalLink(*g_code,yytext); diff --git a/src/commentscan.l b/src/commentscan.l index 8351407..1500f49 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -801,13 +801,13 @@ ATTR ({B}+[^>\n]*)? DOCNL "\n"|"\\_linebr" LC "\\"{B}*"\n" NW [^a-z_A-Z0-9] -FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+] -FILEECHAR [a-z_A-Z0-9\-\+] +FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+] +FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+] FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"") -ID "$"?[a-z_A-Z][a-z_A-Z0-9]* -LABELID [a-z_A-Z][a-z_A-Z0-9\-]* +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* +LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) -SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) +SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID}) MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+ RCSTAG "$"{ID}":"[^\n$]+"$" @@ -1111,7 +1111,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ------------ handle argument of namespace command --------------- */ <NameSpaceDocArg1>{SCOPENAME} { // handle argument - current->name = yytext; + current->name = substitute(yytext,".","::"); BEGIN( Comment ); } <NameSpaceDocArg1>{LC} { // line continuation @@ -1155,7 +1155,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* ------ handle argument of class/struct/union command --------------- */ <ClassDocArg1>{SCOPENAME} { // first argument - current->name = yytext; + current->name = substitute(yytext,".","::"); if (current->section==Entry::PROTOCOLDOC_SEC) { current->name+="-p"; @@ -1164,7 +1164,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" BEGIN( ClassDocArg2 ); } <CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" { - current->name = yytext; + current->name = substitute(yytext,".","::"); BEGIN( ClassDocArg2 ); } <ClassDocArg1,CategoryDocArg1>{LC} { // line continuation diff --git a/src/config.l b/src/config.l index 21e7a39..6790c76 100644 --- a/src/config.l +++ b/src/config.l @@ -1901,13 +1901,13 @@ void Config::create() "documentation. If set to YES the scope will be hidden. \n", FALSE ); - //cb = addBool( - // "SHOW_INCLUDE_FILES", - // "If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n" - // "will put a list of the files that are included by a file in the documentation \n" - // "of that file. \n", - // TRUE - // ); + cb = addBool( + "SHOW_INCLUDE_FILES", + "If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n" + "will put a list of the files that are included by a file in the documentation \n" + "of that file. \n", + TRUE + ); cb = addBool( "INLINE_INFO", "If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \n" @@ -1993,13 +1993,13 @@ void Config::create() "command in the documentation regardless of this setting. \n", 0,10000,30 ); - //cb = addBool( - // "SHOW_USED_FILES", - // "Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n" - // "at the bottom of the documentation of classes and structs. If set to YES the \n" - // "list will mention the files that were used to generate the documentation. \n", - // TRUE - // ); + cb = addBool( + "SHOW_USED_FILES", + "Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n" + "at the bottom of the documentation of classes and structs. If set to YES the \n" + "list will mention the files that were used to generate the documentation. \n", + TRUE + ); cb = addBool( "SHOW_DIRECTORIES", "If the sources in your project are distributed over multiple directories \n" @@ -2036,19 +2036,12 @@ void Config::create() "doxygen. The layout file controls the global structure of the generated output files \n" "in an output format independent way. The create the layout file that represents \n" "doxygen's defaults, run doxygen with the -l option. You can optionally specify a \n" - "file name after the option, if omitted doxygenlayout.xml will be used as the name \n" + "file name after the option, if omitted DoxygenLayout.xml will be used as the name \n" "of the layout file.\n" ); cs->setWidgetType(ConfigString::File); addObsolete("DETAILS_AT_TOP"); - addObsolete("SHOW_INCLUDE_FILES"); - addObsolete("SHOW_USED_FILES"); addObsolete("ALPHABETICAL_INDEX"); - addObsolete("CLASS_GRAPH"); - addObsolete("COLLABORATION_GRAPH"); - addObsolete("GROUP_GRAPHS"); - addObsolete("INCLUDE_GRAPH"); - addObsolete("INCLUDED_BY_GRAPH"); //----------------------------------------------------------------------------------------------- @@ -2528,7 +2521,7 @@ void Config::create() "Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \n" "probably better off using the HTML help feature. Other possible values \n" "for this tag are: HIERARCHIES, which will generate the Groups, Directories,\n" - "and Class Hiererachy pages using a tree view instead of an ordered list;\n" + "and Class Hierarchy pages using a tree view instead of an ordered list;\n" "ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which\n" "disables this behavior completely. For backwards compatibility with previous\n" "releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE\n" @@ -3048,31 +3041,31 @@ void Config::create() "different font using DOT_FONTNAME you can set the path where dot \n" "can find it using this tag. \n" ); - //cb = addBool( - // "CLASS_GRAPH", - // "If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n" - // "will generate a graph for each documented class showing the direct and \n" - // "indirect inheritance relations. Setting this tag to YES will force the \n" - // "the CLASS_DIAGRAMS tag to NO.\n", - // TRUE - // ); - //cb->addDependency("HAVE_DOT"); - //cb = addBool( - // "COLLABORATION_GRAPH", - // "If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n" - // "will generate a graph for each documented class showing the direct and \n" - // "indirect implementation dependencies (inheritance, containment, and \n" - // "class references variables) of the class with other documented classes. \n", - // TRUE - // ); - //cb->addDependency("HAVE_DOT"); - //cb = addBool( - // "GROUP_GRAPHS", - // "If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n" - // "will generate a graph for groups, showing the direct groups dependencies\n", - // TRUE - // ); - //cb->addDependency("HAVE_DOT"); + cb = addBool( + "CLASS_GRAPH", + "If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n" + "will generate a graph for each documented class showing the direct and \n" + "indirect inheritance relations. Setting this tag to YES will force the \n" + "the CLASS_DIAGRAMS tag to NO.\n", + TRUE + ); + cb->addDependency("HAVE_DOT"); + cb = addBool( + "COLLABORATION_GRAPH", + "If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n" + "will generate a graph for each documented class showing the direct and \n" + "indirect implementation dependencies (inheritance, containment, and \n" + "class references variables) of the class with other documented classes. \n", + TRUE + ); + cb->addDependency("HAVE_DOT"); + cb = addBool( + "GROUP_GRAPHS", + "If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n" + "will generate a graph for groups, showing the direct groups dependencies\n", + TRUE + ); + cb->addDependency("HAVE_DOT"); cb = addBool( "UML_LOOK", "If the UML_LOOK tag is set to YES doxygen will generate inheritance and \n" @@ -3088,24 +3081,24 @@ void Config::create() FALSE ); cb->addDependency("HAVE_DOT"); - //cb = addBool( - // "INCLUDE_GRAPH", - // "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n" - // "tags are set to YES then doxygen will generate a graph for each documented \n" - // "file showing the direct and indirect include dependencies of the file with \n" - // "other documented files. \n", - // TRUE - // ); - //cb->addDependency("HAVE_DOT"); - //cb = addBool( - // "INCLUDED_BY_GRAPH", - // "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n" - // "HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n" - // "documented header file showing the documented files that directly or \n" - // "indirectly include this file. \n", - // TRUE - // ); - //cb->addDependency("HAVE_DOT"); + cb = addBool( + "INCLUDE_GRAPH", + "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n" + "tags are set to YES then doxygen will generate a graph for each documented \n" + "file showing the direct and indirect include dependencies of the file with \n" + "other documented files. \n", + TRUE + ); + cb->addDependency("HAVE_DOT"); + cb = addBool( + "INCLUDED_BY_GRAPH", + "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n" + "HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n" + "documented header file showing the documented files that directly or \n" + "indirectly include this file. \n", + TRUE + ); + cb->addDependency("HAVE_DOT"); cb = addBool( "CALL_GRAPH", "If the CALL_GRAPH and HAVE_DOT options are set to YES then \n" diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp index af4b03d..7acce1f 100644 --- a/src/cppvalue.cpp +++ b/src/cppvalue.cpp @@ -71,7 +71,15 @@ CPPValue parseCharacter() // does not work for '\n' and the alike case '?': return CPPValue((long)'\?'); case '\'': return CPPValue((long)'\''); case '"': return CPPValue((long)'"'); - case '0': return parseOctal(); + case '0': // fall through + case '1': // fall through + case '2': // fall through + case '3': // fall through + case '4': // fall through + case '5': // fall through + case '6': // fall through + case '7': // fall through + return parseOctal(); case 'x': case 'X': return parseHexadecimal(); default: printf("Invalid escape sequence %s found!\n",g_strToken.data()); diff --git a/src/declinfo.l b/src/declinfo.l index d36610e..d4c2676 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -97,7 +97,7 @@ static int yyread(char *buf,int max_size) %} B [ \t] -ID ([a-z_A-Z][a-z_A-Z0-9]*)|(@[0-9]+) +ID ([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+) %option nounput %option noyywrap diff --git a/src/defargs.l b/src/defargs.l index f44c1f3..42faf17 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -98,7 +98,7 @@ static int yyread(char *buf,int max_size) %} B [ \t] -ID [a-z_A-Z][a-z_A-Z0-9]* +ID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* %option noyywrap @@ -302,6 +302,22 @@ ID [a-z_A-Z][a-z_A-Z0-9]* { // type contains a name a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)); a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace(); + + // if the type becomes a type specifier only then we make a mistake + // and need to correct it to avoid seeing a nameless parameter + // "struct A" as a parameter with type "struct" and name "A". + int sv=0; + if (a->type.left(6)=="const ") sv=6; + else if (a->type.left(8)=="volatile ") sv=9; + if (a->type.mid(sv)=="struct" || + a->type.mid(sv)=="union" || + a->type.mid(sv)=="class" || + a->type.mid(sv)=="typename" || + a->type=="const" || a->type=="volatile") + { + a->type = a->type + " " + a->name; + a->name.resize(0); + } } else // assume only the type was specified, try to determine name later { diff --git a/src/docparser.cpp b/src/docparser.cpp index a434ac7..3a3c999 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -327,7 +327,7 @@ static void checkArgumentName(const QString &name,bool isParam) //printf("isDocsForDefinition()=%d\n",g_memberDef->isDocsForDefinition()); if (al==0) return; // no argument list - static QRegExp re("[a-zA-Z0-9_]+\\.*"); + static QRegExp re("[a-zA-Z0-9_\\x80-\\xFF]+\\.*"); int p=0,i=0,l; while ((i=re.match(name,p,&l))!=-1) // to handle @param x,y { @@ -2135,8 +2135,8 @@ DocRef::DocRef(DocNode *parent,const QString &target,const QString &context) : if (sec->type!=SectionInfo::Page) m_anchor = sec->label; m_refToAnchor = sec->type==SectionInfo::Anchor; m_refToSection = sec->type!=SectionInfo::Anchor; - //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d\n", - // m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor); + //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d type=%d\n", + // m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor,sec->type); return; } else if (resolveLink(context,target,TRUE,&compound,anchor)) @@ -2760,7 +2760,8 @@ int DocInternal::parse(int level) (level==4 && retval==RetVal_Paragraph) ) { - DocSection *s=new DocSection(this,level,g_token->sectionId); + DocSection *s=new DocSection(this, + QMIN(level+Doxygen::subpageNestingLevel,4),g_token->sectionId); m_children.append(s); retval = s->parse(); } @@ -5817,7 +5818,8 @@ int DocSection::parse() while (retval==RetVal_Subsection) // more sections follow { //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - DocSection *s=new DocSection(this,2,g_token->sectionId); + DocSection *s=new DocSection(this, + QMIN(2+Doxygen::subpageNestingLevel,4),g_token->sectionId); m_children.append(s); retval = s->parse(); } @@ -5828,7 +5830,8 @@ int DocSection::parse() while (retval==RetVal_Subsubsection) // more sections follow { //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - DocSection *s=new DocSection(this,3,g_token->sectionId); + DocSection *s=new DocSection(this, + QMIN(3+Doxygen::subpageNestingLevel,4),g_token->sectionId); m_children.append(s); retval = s->parse(); } @@ -6015,7 +6018,8 @@ void DocRoot::parse() SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; if (sec) { - DocSection *s=new DocSection(this,1,g_token->sectionId); + DocSection *s=new DocSection(this, + QMIN(1+Doxygen::subpageNestingLevel,4),g_token->sectionId); m_children.append(s); retval = s->parse(); } diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 7edafa0..d183e4c 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -240,8 +240,8 @@ static void handleHtmlTag() else // value without any quotes { startAttrib=i; - // search for separator - while (i<yyleng && !isspace(c)) { c=tagText.at(++i); } + // search for separator or end symbol + while (i<yyleng && !isspace(c) && c!='>') { c=tagText.at(++i); } endAttrib=i; if (i<yyleng) c=tagText.at(++i); } @@ -312,7 +312,8 @@ PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]" TEMPCHAR [a-z_A-Z0-9,: \t\*\&] FUNCCHAR [a-z_A-Z0-9,:\<\> \t\*\&] SCOPESEP "::"|"#"|"." -SCOPEPRE {ID}("<"{TEMPCHAR}*">")?{SCOPESEP} +TEMPLPART "<"{TEMPCHAR}*">" +SCOPEPRE {ID}{TEMPLPART}?{SCOPESEP} SCOPEKEYS ":"({ID}":")* SCOPECPP {SCOPEPRE}*(~)?{ID}("<"{TEMPCHAR}*">")? SCOPEOBJC {SCOPEPRE}?{ID}{SCOPEKEYS}? @@ -339,7 +340,7 @@ HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|" HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P" HTMLKEYW {HTMLKEYL}|{HTMLKEYU} LABELID [a-z_A-Z][a-z_A-Z0-9\-]* -REFWORD ("#"|"::")?({ID}("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}? +REFWORD ("#"|"::")?({ID}{TEMPLPART}?("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}? %option noyywrap %option yylineno @@ -810,7 +811,7 @@ REFWORD ("#"|"::")?({ID}("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}? g_token->name = g_token->name.stripWhiteSpace(); return TK_WORD; } -<St_Link>{LINKMASK} { +<St_Link>{LINKMASK}|{REFWORD} { g_token->name = yytext; return TK_WORD; } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 0c1bdae..e8a045f 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -138,7 +138,7 @@ QCString Doxygen::objDBFileName; QCString Doxygen::entryDBFileName; bool Doxygen::gatherDefines = TRUE; IndexList Doxygen::indexList; - +int Doxygen::subpageNestingLevel = 0; bool Doxygen::userComments = FALSE; // locally accessible globals @@ -1952,6 +1952,7 @@ static MemberDef *addVariableToClass( md->memberType()==MemberDef::Variable) { // Objective-C 2.0 property // turn variable into a property + md->setProtection(root->protection); cd->reclassifyMember(md,MemberDef::Property); } addMemberDocs(rootNav,md,def,0,FALSE); @@ -2842,14 +2843,18 @@ static void buildFunctionList(EntryNav *rootNav) int te=rname.find('>'); if (memIndex>0 && (ts==-1 || te==-1)) { - nd = Doxygen::namespaceSDict->find(rname.left(memIndex)); - isMember = nd==0; - if (nd) - { - // strip namespace scope from name - scope=rname.left(memIndex); - rname=rname.right(rname.length()-memIndex-2); - } + // note: the following code was replaced by inMember=TRUE to deal with a + // function rname='X::foo' of class X inside a namespace also called X... + // bug id 548175 + //nd = Doxygen::namespaceSDict->find(rname.left(memIndex)); + //isMember = nd==0; + //if (nd) + //{ + // // strip namespace scope from name + // scope=rname.left(memIndex); + // rname=rname.right(rname.length()-memIndex-2); + //} + isMember = TRUE; } else { @@ -2962,13 +2967,7 @@ static void buildFunctionList(EntryNav *rootNav) md->setArgumentList(argList); } } -#if 0 - else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && mnd==rnd) - { - warn(root->docFile,root->docLine,"Warning: member %s: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->name().data(),md->docLine(),md->docFile().data()); - //printf("md->docs=[%s] root->docs=[%s]\n",md->documentation().data(),root->doc.data()); - } -#endif + md->setDocumentation(root->doc,root->docFile,root->docLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); @@ -2977,12 +2976,6 @@ static void buildFunctionList(EntryNav *rootNav) { md->setArgsString(root->args); } -#if 0 - else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && mnd==rnd) - { - warn(root->briefFile,root->briefLine,"Warning: member %s: ignoring the brief description found here, since another one was found at line %d of file %s!",md->name().data(),md->briefLine(),md->briefFile().data()); - } -#endif md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->addSectionsToDefinition(root->anchors); @@ -4160,6 +4153,7 @@ static bool findClassRelation( // TODO: here we should try to find the correct template specialization // but for now, we only look for the unspecializated base class. int e=findEndOfTemplate(baseClassName,i+1); + //printf("baseClass==0 i=%d e=%d\n",i,e); if (e!=-1) // end of template was found at e { templSpec=baseClassName.mid(i,e-i); @@ -4182,6 +4176,7 @@ static bool findClassRelation( // instance (for instance if a class // derived from a template argument) { + //printf("baseClass=%p templSpec=%s\n",baseClass,templSpec.data()); ClassDef *templClass=getClass(baseClass->name()+templSpec); if (templClass) { @@ -4193,6 +4188,7 @@ static bool findClassRelation( //printf("cd=%p baseClass=%p\n",cd,baseClass); bool found=baseClass!=0 && (baseClass!=cd || mode==TemplateInstances); + //printf("1. found=%d\n",found); if (!found && si!=-1) { QCString tmpTemplSpec; @@ -4209,12 +4205,11 @@ static bool findClassRelation( found=baseClass!=0 && baseClass!=cd; if (found) templSpec = tmpTemplSpec; } + //printf("2. found=%d\n",found); //printf("root->name=%s biName=%s baseClassName=%s\n", // root->name.data(),biName.data(),baseClassName.data()); - //FileDef *fd=cd->getFileDef(); - //NamespaceDef *nd=cd->getNamespaceDef(); if (!found) { baseClass=findClassWithinClassContext(context,cd,baseClassName); @@ -4227,6 +4222,7 @@ static bool findClassRelation( // make templSpec canonical templSpec = getCanonicalTemplateSpec(cd, cd->getFileDef(), templSpec); + //printf("3. found=%d\n",found); if (found) { Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",biName.data(),templSpec.isEmpty()?"":templSpec.data()); @@ -4650,7 +4646,7 @@ static void addListReferences() QCString name = pd->name(); if (pd->getGroupDef()) { - name = pd->getGroupDef()->getOutputFileBase().copy(); + name = pd->getGroupDef()->getOutputFileBase(); } { LockingPtr< QList<ListItemInfo> > xrefItems = pd->xrefListItems(); @@ -4659,6 +4655,20 @@ static void addListReferences() name,pd->title()); } } + DirSDict::Iterator ddi(*Doxygen::directories); + DirDef *dd = 0; + for (ddi.toFirst();(dd=ddi.current());++ddi) + { + QCString name = dd->getOutputFileBase(); + //if (dd->getGroupDef()) + //{ + // name = dd->getGroupDef()->getOutputFileBase(); + //} + LockingPtr< QList<ListItemInfo> > xrefItems = dd->xrefListItems(); + addRefItem(xrefItems.pointer(), + theTranslator->trDir(TRUE,TRUE), + name,dd->displayName()); + } } //---------------------------------------------------------------------- @@ -5207,9 +5217,13 @@ static void findMember(EntryNav *rootNav, isRelated=TRUE; isMemberOf=(root->relatesType == MemberOf); if (getClass(root->relates)==0 && !scopeName.isEmpty()) + { scopeName= mergeScopes(scopeName,root->relates); + } else + { scopeName = root->relates; + } } if (root->relates.isEmpty() && rootNav->parent() && @@ -5285,7 +5299,8 @@ static void findMember(EntryNav *rootNav, { scopeName=namespaceName; } - else if (!getClass(className)) // class name only exists in a namespace + else if (!root->relates.isEmpty() || // relates command with explicit scope + !getClass(className)) // class name only exists in a namespace { scopeName=namespaceName+"::"+className; } @@ -5741,7 +5756,7 @@ static void findMember(EntryNav *rootNav, { Debug::print(Debug::FindMembers,0,"2. related function\n" " scopeName=%s className=%s\n",scopeName.data(),className.data()); - if (className.isEmpty()) className=root->relates.copy(); + if (className.isEmpty()) className=root->relates; ClassDef *cd; //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); if ((cd=getClass(scopeName))) @@ -7661,6 +7676,7 @@ static void findDirDocumentation(EntryNav *rootNav) //printf("Match for with dir %s\n",matchingDir->name().data()); matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine); matchingDir->setDocumentation(root->doc,root->docFile,root->docLine); + matchingDir->setRefItems(root->sli); addDirToGroups(root,matchingDir); } else @@ -7731,7 +7747,7 @@ static void findMainPage(EntryNav *rootNav) indexName, Doxygen::mainPage->name(), Doxygen::mainPage->title(), - SectionInfo::Section); + SectionInfo::Page); Doxygen::sectionDict.insert(indexName,si); Doxygen::mainPage->addSectionsToDefinition(root->anchors); } @@ -9057,7 +9073,7 @@ void readConfiguration(int argc, char **argv) genLayout=TRUE; layoutName=getArg(argc,argv,optind); if (!layoutName) - { layoutName="doxygenlayout.xml"; } + { layoutName="DoxygenLayout.xml"; } break; case 'd': debugLabel=getArg(argc,argv,optind); @@ -9611,7 +9627,7 @@ void parseInput() bool defaultLayoutUsed = FALSE; if (layoutFileName.isEmpty()) { - layoutFileName = "doxygenlayout.xml"; + layoutFileName = "DoxygenLayout.xml"; defaultLayoutUsed = TRUE; } diff --git a/src/doxygen.h b/src/doxygen.h index 4a8430e..034389f 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -43,7 +43,6 @@ class PageSList; class PageSDict; class PageDef; class SearchIndex; -class DirDef; class ParserManager; class ObjCache; class Store; @@ -130,6 +129,7 @@ class Doxygen static bool gatherDefines; static bool userComments; static IndexList indexList; + static int subpageNestingLevel; }; void initDoxygen(); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index bcc462c..500651b 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -806,11 +806,11 @@ void HtmlGenerator::startDoxyAnchor(const char *,const char *, { t << "<a class=\"anchor\" name=\"" << anchor << "\"></a>"; t << "<!-- doxytag: member=\""; - docify(name); + docify(name,TRUE); t << "\" ref=\""; - docify(anchor); + docify(anchor,TRUE); t << "\" args=\""; - docify(args); + docify(args,TRUE); t << "\" -->"; } @@ -1030,6 +1030,11 @@ void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type) void HtmlGenerator::docify(const char *str) { + docify(str,FALSE); +} + +void HtmlGenerator::docify(const char *str,bool inHtmlComment) +{ if (str) { const char *p=str; @@ -1043,6 +1048,7 @@ void HtmlGenerator::docify(const char *str) case '>': t << ">"; break; case '&': t << "&"; break; case '"': t << """; break; + case '-': if (inHtmlComment) t << "-"; else t << "-"; break; case '\\': if (*p=='<') { t << "<"; p++; } diff --git a/src/htmlgen.h b/src/htmlgen.h index 9f97d35..9e012c8 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -247,6 +247,7 @@ class HtmlGenerator : public OutputGenerator QCString lastTitle; QCString lastFile; QCString relPath; + void docify(const char *text,bool inHtmlComment); HtmlGenerator &operator=(const HtmlGenerator &g); HtmlGenerator(const HtmlGenerator &g); diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 0944c15..2a48662 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -22,6 +22,7 @@ #include <stdlib.h> #include <qlist.h> #include <qdict.h> +#include <qregexp.h> #include "qtextcodec.h" #include "htmlhelp.h" @@ -117,6 +118,10 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2, { QCString key = level1; if (level2) key+= (QCString)"?" + level2; + if (key.find(QRegExp("@[0-9]+"))!=-1) // skip anonymous stuff + { + return; + } if (dict->find(key)==0) // new key { //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n", diff --git a/src/layout.cpp b/src/layout.cpp index 3a9949c..85b200f 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -32,6 +32,27 @@ static const char layout_default[] = #include "layout_default.h" ; +static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE) +{ + QCString visible = convertToQCString(attrib.value("visible")); + if (visible.isEmpty()) return defVal; + if (visible.at(0)=='$' && visible.length()>1) + { + QCString id = visible.mid(1); + ConfigOption *opt = Config::instance()->get(id); + if (opt && opt->kind()==ConfigOption::O_Bool) + { + return *((ConfigBool *)opt)->valueRef(); + } + else if (!opt) + { + err("Warning: found unsupported value %s for visible attribute in layout file\n", + visible.data()); + } + } + return visible!="no" && visible!="0"; +} + //--------------------------------------------------------------------------------- LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind) const @@ -658,8 +679,7 @@ class LayoutParser : public QXmlDefaultHandler void startSimpleEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib) { - QCString visible = convertToQCString(attrib.value("visible")); - bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0"); + bool isVisible = elemIsVisible(attrib); if (m_part!=-1 && isVisible) { LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part, @@ -670,8 +690,7 @@ class LayoutParser : public QXmlDefaultHandler void startSectionEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib, const QCString &title) { - QCString visible = convertToQCString(attrib.value("visible")); - bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0"); + bool isVisible = elemIsVisible(attrib); QCString userTitle = convertToQCString(attrib.value("title")); //printf("startSectionEntry: title='%s' userTitle='%s'\n", // title.data(),userTitle.data()); @@ -704,8 +723,6 @@ class LayoutParser : public QXmlDefaultHandler void startMemberDefEntry(const QXmlAttributes &attrib,MemberList::ListType type, const QCString &title,const QCString &) { - //QCString visible = convertToQCString(attrib.value("visible")); - //bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0"); QCString userTitle = convertToQCString(attrib.value("title")); if (userTitle.isEmpty()) userTitle = title; //printf("memberdef: %s\n",userTitle.data()); diff --git a/src/layout_default.h b/src/layout_default.h index 1067d12..dc1c087 100644 --- a/src/layout_default.h +++ b/src/layout_default.h @@ -25,9 +25,9 @@ " <!-- Layout definition for a class page -->\n" " <class>\n" " <briefdescription visible=\"yes\"/>\n" -" <includes visible=\"yes\"/>\n" -" <inheritancegraph visible=\"yes\"/>\n" -" <collaborationgraph visible=\"yes\"/>\n" +" <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n" +" <inheritancegraph visible=\"$CLASS_GRAPH\"/>\n" +" <collaborationgraph visible=\"$COLLABORATION_GRAPH\"/>\n" " <allmemberslink visible=\"yes\"/>\n" " <memberdecl>\n" " <membergroups visible=\"yes\"/>\n" @@ -72,7 +72,7 @@ " <properties title=\"\"/>\n" " <events title=\"\"/>\n" " </memberdef>\n" -" <usedfiles visible=\"yes\"/>\n" +" <usedfiles visible=\"$SHOW_USED_FILES\"/>\n" " <authorsection visible=\"yes\"/>\n" " </class>\n" "\n" @@ -101,9 +101,9 @@ " <!-- Layout definition for a file page -->\n" " <file>\n" " <briefdescription visible=\"yes\"/>\n" -" <includes visible=\"yes\"/>\n" -" <includegraph visible=\"yes\"/>\n" -" <includedbygraph visible=\"yes\"/>\n" +" <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n" +" <includegraph visible=\"$INCLUDE_GRAPH\"/>\n" +" <includedbygraph visible=\"$INCLUDED_BY_GRAPH\"/>\n" " <sourcelink visible=\"yes\"/>\n" " <memberdecl>\n" " <classes visible=\"yes\" title=\"\"/>\n" @@ -128,7 +128,7 @@ " <!-- Layout definition for a group page -->\n" " <group>\n" " <briefdescription visible=\"yes\"/>\n" -" <groupgraph visible=\"yes\"/>\n" +" <groupgraph visible=\"$GROUP_GRAPHS\"/>\n" " <memberdecl>\n" " <classes visible=\"yes\" title=\"\"/>\n" " <namespaces visible=\"yes\" title=\"\"/>\n" diff --git a/src/layout_default.xml b/src/layout_default.xml index 6532a9e..82404f4 100644 --- a/src/layout_default.xml +++ b/src/layout_default.xml @@ -25,9 +25,9 @@ <!-- Layout definition for a class page --> <class> <briefdescription visible="yes"/> - <includes visible="yes"/> - <inheritancegraph visible="yes"/> - <collaborationgraph visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <inheritancegraph visible="$CLASS_GRAPH"/> + <collaborationgraph visible="$COLLABORATION_GRAPH"/> <allmemberslink visible="yes"/> <memberdecl> <membergroups visible="yes"/> @@ -72,7 +72,7 @@ <properties title=""/> <events title=""/> </memberdef> - <usedfiles visible="yes"/> + <usedfiles visible="$SHOW_USED_FILES"/> <authorsection visible="yes"/> </class> @@ -101,9 +101,9 @@ <!-- Layout definition for a file page --> <file> <briefdescription visible="yes"/> - <includes visible="yes"/> - <includegraph visible="yes"/> - <includedbygraph visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <includegraph visible="$INCLUDE_GRAPH"/> + <includedbygraph visible="$INCLUDED_BY_GRAPH"/> <sourcelink visible="yes"/> <memberdecl> <classes visible="yes" title=""/> @@ -128,7 +128,7 @@ <!-- Layout definition for a group page --> <group> <briefdescription visible="yes"/> - <groupgraph visible="yes"/> + <groupgraph visible="$GROUP_GRAPHS"/> <memberdecl> <classes visible="yes" title=""/> <namespaces visible="yes" title=""/> diff --git a/src/memberlist.cpp b/src/memberlist.cpp index d6b389b..e2ffedb 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -26,6 +26,7 @@ #include "outputlist.h" #include "groupdef.h" #include "marshal.h" +#include "vhdldocgen.h" MemberList::MemberList() { @@ -319,6 +320,8 @@ void MemberList::writeDeclarations(OutputList &ol, /*, bool inGroup,bool countSubGroups*/) { //printf("----- writeDeclaration() this=%p ----\n",this); + static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); + countDecMembers(showEnumValues); // count member not in group Definition *ctx = cd; if (ctx==0 && nd) ctx = nd; @@ -342,7 +345,21 @@ void MemberList::writeDeclarations(OutputList &ol, ol.endMemberSubtitle(); } - writePlainDeclarations(ol,cd,nd,fd,gd); + // TODO: Two things need to be worked out for proper VHDL output: + // 1. Signals and types under the group need to be + // formatted to associate them with the group somehow + // indentation, or at the very least, extra space after + // the group is done + // 2. This might need to be repeated below for memberGroupLists + if (optimizeVhdl) // use specific declarations function + { + VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd); + } + else + { + writePlainDeclarations(ol,cd,nd,fd,gd); + } + //printf("memberGroupList=%p\n",memberGroupList); if (memberGroupList) diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 2f59f2a..cf2c21a 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -75,7 +75,7 @@ void PageDef::writeDocumentation(OutputList &ol) else pageName=name().lower(); - startFile(ol,pageName,pageName,title(),HLI_None,TRUE); + startFile(ol,pageName,pageName,title(),HLI_Pages,TRUE); ol.pushGeneratorState(); //1.{ @@ -200,7 +200,9 @@ void PageDef::writePageDocumentation(OutputList &ol) ol.startSection(subPage->name(),title,sectionType); ol.parseText(title); ol.endSection(subPage->name(),sectionType); + Doxygen::subpageNestingLevel++; subPage->writePageDocumentation(ol); + Doxygen::subpageNestingLevel--; } ol.popGeneratorState(); @@ -222,7 +222,7 @@ static FILE *findFile(const char *fileName,bool localInclude) QFileInfo fi(g_yyFileName); if (fi.exists()) { - QCString absName = QCString(fi.dirPath().data())+"/"+fileName; + QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName; FILE *f = checkAndOpenFile(absName); if (f) { @@ -1152,7 +1152,7 @@ static void readIncludeFile(const QCString &inc) // Deal with file changes due to // #include's within { .. } blocks - QCString lineStr; + QCString lineStr(g_yyFileName.length()+20); lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data()); outputArray(lineStr.data(),lineStr.length()); diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index da7b062..9bb5888 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -1203,6 +1203,26 @@ void RTFDocVisitor::visitPre(DocParamList *pl) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n"); + + // Put in the direction: in/out/in,out if specified. + if (pl->direction()!=DocParamSect::Unspecified) + { + m_t << "["; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } + m_t << "] "; + } + m_t << "{\\i "; //QStrListIterator li(pl->parameters()); //const char *s; diff --git a/src/scanner.l b/src/scanner.l index b102853..3bd0fad 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -559,27 +559,17 @@ BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] BS ^(({B}*"//")?)(({B}*"*"+)?){B}* -FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+] -FILEECHAR [a-z_A-Z0-9\-\+] +FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+] +FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+] FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"") -ID "$"?[a-z_A-Z][a-z_A-Z0-9]* -LABELID [a-z_A-Z][a-z_A-Z0-9\-]* +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID}) TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")? FTSCOPE {ID}("<"[a-z_A-Z0-9\*\&,]*">")? CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID}) -ATTR ({B}+[^>\n]*)? -A [aA] -BR [bB][rR] PRE [pP][rR][eE] CODE [cC][oO][dD][eE] -TABLE [tT][aA][bB][lL][eE] -P [pP] -UL [uU][lL] -OL [oO][lL] -DL [dD][lL] -TITLE [tT][iI][tT][lL][eE] CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] IDLATTR ("["[^\]]*"]"){BN}* @@ -795,12 +785,19 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else REJECT; } - <FindMembers>{PHPKW} { if (insidePHP) BEGIN( NextSemi ); else REJECT; } +<FindMembers>"%{"[^\n]* { // Mozilla XPIDL lang-specific block + if (!insideIDL) + REJECT; + } +<FindMembers>"%}" { // Mozilla XPIDL lang-specific block end + if (!insideIDL) + REJECT; + } <FindMembers>{B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property current->mtype = mtype = Property; current->protection = protection = Public ; @@ -4326,11 +4323,11 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->spec |= Entry::Template; current->tArgLists->append(al); currentArgumentList = al; - current->name+="<"; + //current->name+="<"; templateStr="<"; fullArgString = templateStr; - copyArgString = ¤t->name; - currentArgumentContext = CompoundName; + copyArgString = ¤t->args; + currentArgumentContext = ClassVar; BEGIN( ReadTempArgs ); } <ObjCProtocolList>"<" { @@ -4464,6 +4461,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } + else if (insideCli && strcmp(yytext,"abstract")) + { + current->spec|=Entry::Abstract; + } + else if (insideCli && strcmp(yytext,"sealed")) + { + current->spec|=Entry::Sealed; + } else { if (current->section == Entry::ENUM_SEC) @@ -4672,9 +4677,22 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) <BasesProt>{BN} { lineCount(); } <BasesProt>. { unput(*yytext); BEGIN(Bases); } <Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} { - baseName+=yytext; - current->args += ' '; - current->args += yytext; + QCString baseScope = yytext; + if (insideCS && baseScope.stripWhiteSpace()=="where") + { + // type contraint for a class + delete current->typeConstr; + current->typeConstr = new ArgumentList; + current->typeConstr->append(new Argument); + lastCSConstraint = YY_START; + BEGIN( CSConstraintName ); + } + else + { + baseName+=yytext; + current->args += ' '; + current->args += yytext; + } } <Bases>{BN}*{ID}("."{ID})* { // Java style class QCString name = substitute(yytext,".","::"); diff --git a/src/util.cpp b/src/util.cpp index 4c2e628..945f48a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -116,13 +116,6 @@ void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file, // an inheritance tree of depth of 100000 should be enough for everyone :-) const int maxInheritanceDepth = 100000; -bool isId(int c) -{ - if (c<0 || c>255) return FALSE; - return c=='_' || isalnum(c); -} - - /*! Removes all anoymous scopes from string s Possible examples: @@ -1504,7 +1497,13 @@ QCString removeRedundantWhiteSpace(const QCString &s) { static bool cliSupport = Config_getBool("CPP_CLI_SUPPORT"); if (s.isEmpty()) return s; - QCString result; + int resultLen = 1024; + int resultPos = 0; + QCString result(resultLen); + // we use ADD_CHAR(c) instead of result+=c to + // improve the performance of this function +#define ADD_CHAR(c) if (resultPos>=resultLen) { resultLen+=1024; result.resize(resultLen); } \ + result[resultPos++]=(c) uint i; uint l=s.length(); uint csp=0; @@ -1539,13 +1538,16 @@ nextChar: if (c=='"') // quoted string { i++; - result+=c; + ADD_CHAR(c); while (i<l) { char cc=s.at(i); - result+=cc; + ADD_CHAR(cc); if (cc=='\\') // escaped character - { result+=s.at(i+1); i+=2; } + { + ADD_CHAR(s.at(i+1)); + i+=2; + } else if (cc=='"') // end of string { i++; goto nextChar; } else // any other character @@ -1557,21 +1559,24 @@ nextChar: (i<8 || !findOperator(s,i)) // string in front is not "operator" ) { - result+="< "; // insert extra space for layouting (nested) templates + ADD_CHAR('<'); + ADD_CHAR(' '); } else if (i>0 && c=='>' && // current char is a > (isId(s.at(i-1)) || isspace((uchar)s.at(i-1)) || s.at(i-1)=='*' || s.at(i-1)=='&') && // prev char is an id char or space (i<8 || !findOperator(s,i)) // string in front is not "operator" ) { - result+=" >"; // insert extra space for layouting (nested) templates + ADD_CHAR(' '); + ADD_CHAR('>'); } else if (i>0 && c==',' && !isspace((uchar)s.at(i-1)) && ((i<l-1 && isId(s.at(i+1))) || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2))) // for PHP || (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3))))) // for PHP { - result+=", "; + ADD_CHAR(','); + ADD_CHAR(' '); } else if (i>0 && ((isId(s.at(i)) && s.at(i-1)==')') || @@ -1579,8 +1584,8 @@ nextChar: ) ) { - result+=' '; - result+=s.at(i); + ADD_CHAR(' '); + ADD_CHAR(s.at(i)); } else if (c=='t' && csp==5 /*&& (i<5 || !isId(s.at(i-5)))*/ && !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || @@ -1591,14 +1596,16 @@ nextChar: ) // prevent const ::A from being converted to const::A { - result+="t "; + ADD_CHAR('t'); + ADD_CHAR(' '); if (s.at(i+1)==' ') i++; csp=0; } else if (c==':' && csp==6 /*&& (i<6 || !isId(s.at(i-6)))*/) // replace const::A by const ::A { - result+=" :"; + ADD_CHAR(' '); + ADD_CHAR(':'); csp=0; } else if (c=='l' && vsp==7 /*&& (i<7 || !isId(s.at(i-7)))*/ && @@ -1610,14 +1617,16 @@ nextChar: ) // prevent virtual ::A from being converted to virtual::A { - result+="l "; + ADD_CHAR('l'); + ADD_CHAR(' '); if (s.at(i+1)==' ') i++; vsp=0; } else if (c==':' && vsp==8 /*&& (i<8 || !isId(s.at(i-8)))*/) // replace virtual::A by virtual ::A { - result+=" :"; + ADD_CHAR(' '); + ADD_CHAR(':'); vsp=0; } else if (!isspace((uchar)c) || // not a space @@ -1630,19 +1639,25 @@ nextChar: { if (c=='*' || c=='&' || c=='@' || c=='$') { - uint rl=result.length(); + //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->* ) { - result+=' '; + ADD_CHAR(' '); } } - result+=c; - if (cliSupport && (c=='^' || c=='%') && i>1 && isId(s.at(i-1))) result+=' '; // C++/CLI: Type^ name and Type% name + ADD_CHAR(c); + if (cliSupport && (c=='^' || c=='%') && i>1 && isId(s.at(i-1))) + { + ADD_CHAR(' '); // C++/CLI: Type^ name and Type% name + } } } //printf("removeRedundantWhiteSpace(`%s')=`%s'\n",s.data(),result.data()); + ADD_CHAR(0); + result.resize(resultPos); return result; } @@ -1671,7 +1686,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope, bool keepSpaces) { //printf("`%s'\n",text); - static QRegExp regExp("[a-z_A-Z][~!a-z_A-Z0-9.:]*"); + static QRegExp regExp("[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9.:\\x80-\\xFF]*"); static QRegExp regExpSplit("(?!:),"); QCString txtStr=text; int strLen = txtStr.length(); @@ -3180,7 +3195,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(), // d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>"); - static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*"); + static QRegExp id("[a-z_A-Z\\x80-\\xFF][:a-z_A-Z0-9\\x80-\\xFF]*"); QCString canType,templSpec,word; int i,p=0,pp=0; @@ -3197,7 +3212,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) // (i.e. type is not a template specialization) // then resolve any identifiers inside. { - static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); + static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*"); int tp=0,tl,ti; // for each identifier template specifier //printf("adding resolved %s to %s\n",templSpec.data(),canType.data()); @@ -3304,6 +3319,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr bool checkCV ) { + //printf("*** matchArguments2\n"); ASSERT(srcScope!=0 && dstScope!=0); if (srcAl==0 || dstAl==0) @@ -4024,7 +4040,8 @@ bool resolveRef(/* in */ const char *scName, /* in */ const char *name, /* in */ bool inSeeBlock, /* out */ Definition **resContext, - /* out */ MemberDef **resMember + /* out */ MemberDef **resMember, + bool lookForSpecialization ) { QCString tsName = name; @@ -4087,10 +4104,21 @@ bool resolveRef(/* in */ const char *scName, // strip template specifier // TODO: match against the correct partial template instantiation int templPos=nameStr.find('<'); + bool tryUnspecializedVersion = FALSE; if (templPos!=-1 && nameStr.find("operator")==-1) { int endTemplPos=nameStr.findRev('>'); - nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1); + if (endTemplPos!=-1) + { + if (!lookForSpecialization) + { + nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1); + } + else + { + tryUnspecializedVersion = TRUE; + } + } } QCString scopeStr=scName; @@ -4138,6 +4166,11 @@ bool resolveRef(/* in */ const char *scName, } } + if (tryUnspecializedVersion) + { + return resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE); + } + return FALSE; } @@ -4414,18 +4447,34 @@ QCString substituteClassNames(const QCString &s) QCString substitute(const char *s,const char *src,const char *dst) { - // TODO: optimize by using strstr() instead of find - QCString input=s; - QCString output; - int i=0,p; - while ((p=input.find(src,i))!=-1) + if (s==0 || src==0 || dst==0) return s; + const char *p, *q; + int srcLen = strlen(src); + int dstLen = strlen(dst); + int resLen; + if (srcLen!=dstLen) { - output+=input.mid(i,p-i); - output+=dst; - i=p+strlen(src); + int count; + for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++; + resLen = p-s+strlen(p)+count*(dstLen-srcLen); } - output+=input.mid(i,input.length()-i); - return output; + else // result has same size as s + { + resLen = strlen(s); + } + QCString result(resLen+1); + char *r; + for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen) + { + int l = (int)(q-p); + memcpy(r,p,l); + r+=l; + memcpy(r,dst,dstLen); + r+=dstLen; + } + strcpy(r,p); + //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data()); + return result; } //---------------------------------------------------------------------- @@ -4667,7 +4716,19 @@ QCString escapeCharsInString(const char *name,bool allowDots) case '+': result+="_09"; break; case '=': result+="_0A"; break; default: - if (caseSenseNames || !isupper(c)) + if (c<0) + { + static char map[] = "0123456789ABCDEF"; + char ids[5]; + unsigned char id = (unsigned char)c; + ids[0]='_'; + ids[1]='x'; + ids[2]=map[id>>4]; + ids[3]=map[id&0xF]; + ids[4]=0; + result+=ids; + } + else if (caseSenseNames || !isupper(c)) { result+=c; } @@ -5280,7 +5341,7 @@ void addMembersToMemberGroup(MemberList *ml, */ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCString &templSpec) { - static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); + static const QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*"); name.resize(0); templSpec.resize(0); int i,l; @@ -5347,7 +5408,7 @@ QCString substituteTemplateArgumentsInString( // name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data()); if (formalArgs==0) return name; QCString result; - static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); + static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*"); int p=0,l,i; // for each identifier in the base class name (e.g. B<T> -> B and T) while ((i=re.match(name,p,&l))!=-1) @@ -6208,7 +6269,7 @@ QCString stripPath(const char *s) /** returns \c TRUE iff string \a s contains word \a w */ bool containsWord(const QCString &s,const QCString &word) { - static QRegExp wordExp("[a-z_A-Z]+"); + static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+"); int p=0,i,l; while ((i=wordExp.match(s,p,&l))!=-1) { @@ -6220,7 +6281,7 @@ bool containsWord(const QCString &s,const QCString &word) bool findAndRemoveWord(QCString &s,const QCString &word) { - static QRegExp wordExp("[a-z_A-Z]+"); + static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+"); int p=0,i,l; while ((i=wordExp.match(s,p,&l))!=-1) { @@ -6284,7 +6345,7 @@ void stringToSearchIndex(const QCString &docBaseUrl,const QCString &title, if (searchEngine) { Doxygen::searchIndex->setCurrentDoc(title,docBaseUrl,anchor); - static QRegExp wordPattern("[a-z_A-Z][a-z_A-Z0-9]*"); + static QRegExp wordPattern("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*"); int i,p=0,l; while ((i=wordPattern.match(str,p,&l))!=-1) { @@ -135,7 +135,8 @@ bool resolveRef(/* in */ const char *scName, /* in */ const char *name, /* in */ bool inSeeBlock, /* out */ Definition **resContext, - /* out */ MemberDef **resMember + /* out */ MemberDef **resMember, + /* in */ bool lookForSpecializations = TRUE ); bool resolveLink(/* in */ const char *scName, @@ -191,7 +192,10 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n); int guessSection(const char *name); -bool isId(int c); +inline bool isId(int c) +{ + return c=='_' || isalnum(c) || c>=128 || c<0; +} QCString removeRedundantWhiteSpace(const QCString &s); |