diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/code.l | 43 | ||||
-rw-r--r-- | src/commentscan.l | 11 | ||||
-rw-r--r-- | src/config.l | 14 | ||||
-rw-r--r-- | src/definition.cpp | 115 | ||||
-rw-r--r-- | src/definition.h | 3 | ||||
-rw-r--r-- | src/docparser.cpp | 112 | ||||
-rw-r--r-- | src/doxygen.cpp | 107 | ||||
-rw-r--r-- | src/latexgen.cpp | 3 | ||||
-rw-r--r-- | src/memberdef.cpp | 19 | ||||
-rw-r--r-- | src/memberlist.cpp | 9 | ||||
-rw-r--r-- | src/pyscanner.l | 2 | ||||
-rw-r--r-- | src/scanner.l | 99 | ||||
-rw-r--r-- | src/textdocvisitor.cpp | 2 | ||||
-rw-r--r-- | src/util.cpp | 60 | ||||
-rw-r--r-- | src/util.h | 3 |
15 files changed, 470 insertions, 132 deletions
@@ -222,7 +222,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) ltype = ltype.right(ltype.length()-6); } if (ltype.isEmpty() || lname.isEmpty()) return; - DBG_CTX((stderr,"** addVariable trying: type=%s name=%s g_currentDefinition=%s\n", + DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n", ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>")); Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast(); ClassDef *varType; @@ -232,7 +232,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions ) { - DBG_CTX((stderr,"** addVariable type=%s name=%s\n",ltype.data(),lname.data())); + DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data())); scope->append(lname,varType); // add it to a list } else if ((i=ltype.find('<'))!=-1) @@ -253,7 +253,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) } if (newDef) { - DBG_CTX((stderr,"** addVariable type=%s templ=%s name=%s\n",typeName.data(),templateArgs.data(),lname.data())); + DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data())); scope->append(lname, newDef); } else @@ -268,7 +268,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) // is hidden to avoid false links to global variables with the same name // TODO: make this work for namespaces as well! { - DBG_CTX((stderr,"** addVariable: dummy context\n")); + DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data())); scope->append(lname,dummyContext); } else @@ -876,7 +876,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, } QCString className=clName; if (className.isEmpty()) return; - if (g_insideProtocolList) + if (g_insideProtocolList) // for Obj-C { className+="-p"; } @@ -919,10 +919,14 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, { //printf("non-dummy context lcd=%s!\n",lcd->name().data()); g_theCallContext.setClass(lcd); - if (getLink(g_classScope,clName,ol,clName)) - { - return; - } + + // to following is needed for links to a global variable, but is + // no good for a link to a local variable that is also a global symbol. + + //if (getLink(g_classScope,clName,ol,clName)) + //{ + //return; + //} } isLocal=TRUE; //fprintf(stderr,"is a local variable cd=%p!\n",cd); @@ -1750,6 +1754,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} if (!g_curClassName.isEmpty()) // valid class name { pushScope(g_curClassName); + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); g_scopeStack.push(SCOPEBLOCK); } } @@ -1859,6 +1864,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <Body,FuncCall>"{" { g_theVarContext.pushScope(); + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); g_scopeStack.push(INNERBLOCK); if (g_searchingForBody) @@ -1874,11 +1880,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} } g_type.resize(0); g_name.resize(0); + BEGIN( Body ); } <Body,MemberCall,MemberCall2>"}" { g_theVarContext.popScope(); + g_type.resize(0); + g_name.resize(0); int *scope = g_scopeStack.pop(); + DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); if (scope==SCOPEBLOCK || scope==CLASSBLOCK) { popScope(); @@ -1914,6 +1924,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} g_theVarContext.popScope(); int *scope = g_scopeStack.pop(); + DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); if (scope==SCOPEBLOCK || scope==CLASSBLOCK) { popScope(); @@ -1980,7 +1991,10 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} <ClassVar>{ID} { g_type = g_curClassName.copy(); g_name = yytext; - g_theVarContext.addVariable(g_type,g_name); + if (g_insideBody) + { + g_theVarContext.addVariable(g_type,g_name); + } generateClassOrGlobalLink(*g_code,yytext); } <ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* { @@ -2005,6 +2019,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} if (g_insideBody) g_bodyCurlyCount++; if (!g_curClassName.isEmpty()) // valid class name { + DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n")); g_scopeStack.push(CLASSBLOCK); pushScope(g_curClassName); //fprintf(stderr,"***** g_curClassName=%s\n",g_curClassName.data()); @@ -2032,6 +2047,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} } else // not a class name -> assume inner block { + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); g_scopeStack.push(INNERBLOCK); } g_curClassName.resize(0); @@ -2185,6 +2201,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} if (*yytext==')') { g_theCallContext.popScope(); + g_bracketCount--; BEGIN(FuncCall); } } @@ -2440,6 +2457,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} g_saveType = g_type.copy(); if (*yytext!='[' && !g_type.isEmpty()) { + //printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom()); if (g_scopeStack.top()!=CLASSBLOCK) { //printf("AddVariable: '%s' '%s' context=%d\n", @@ -2625,6 +2643,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} g_parmType.resize(0);g_parmName.resize(0); } <MemberCall2,FuncCall>"(" { + g_parmType.resize(0);g_parmName.resize(0); g_code->codify(yytext); g_bracketCount++; g_theCallContext.pushScope(); @@ -2717,10 +2736,12 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} { setClassScope(g_realScope); } + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); g_scopeStack.push(SCOPEBLOCK); } else { + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); g_scopeStack.push(INNERBLOCK); } yytext[yyleng-1]='\0'; @@ -2806,11 +2827,13 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} if (g_insideBody) g_bodyCurlyCount++; if (g_name.find("::")!=-1) { + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); g_scopeStack.push(SCOPEBLOCK); setClassScope(g_realScope); } else { + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); g_scopeStack.push(INNERBLOCK); } g_type.resize(0); g_name.resize(0); diff --git a/src/commentscan.l b/src/commentscan.l index 9a7f698..1b55244 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -272,7 +272,7 @@ class DocCmdMapper { if (m_map.find(p->cmdName)!=0) { - printf("Error: command %s already added\n",p->cmdName); + printf("Error: DocCmdMapper: command %s already added\n",p->cmdName); exit(1); } Cmd *cmd = new Cmd; @@ -687,7 +687,14 @@ static inline void setOutput(OutputContext ctx) current->briefLine = yyLineNr; } } - pOutputString = ¤t->brief; + if (current->brief.isEmpty()) + { + pOutputString = ¤t->brief; + } + else + { + pOutputString = ¤t->doc; + } break; case OutputXRef: pOutputString = &outputXRef; diff --git a/src/config.l b/src/config.l index cb73dfb..35b1b8c 100644 --- a/src/config.l +++ b/src/config.l @@ -647,6 +647,8 @@ static void readIncludeFile(const char *incName) tmpString.resize(0); } <GetQuotedString>"\""|"\n" { + // we add a bogus space to signal that the string was quoted. This space will be stripped later on. + tmpString+=" "; //printf("Quoted String = `%s'\n",tmpString.data()); if (lastState==GetString) { @@ -790,6 +792,8 @@ static void substEnvVarsInString(QCString &s) s = s.left(i)+env+s.right(s.length()-i-l); p=i+env.length(); // next time start at the end of the expanded string } + s=s.stripWhiteSpace(); // to strip the bogus space that was added when an argument + // has quotes //printf("substEnvVarInString(%s) end\n",s.data()); } @@ -799,7 +803,9 @@ static void substEnvVarsInStrList(QStrList &sl) while (s) { QCString result(s); + // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE. bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1); + // here we strip the quote again substEnvVarsInString(result); //printf("Result %s was quoted=%d\n",result.data(),wasQuoted); @@ -1718,6 +1724,14 @@ void Config::create() FALSE ); cb = addBool( + "EXTRACT_ANON_NSPACES", + "If this flag is set to YES, the members of anonymous namespaces will be extracted \n" + "and appear in the documentation as a namespace called 'anonymous_namespace{file}', \n" + "where file will be replaced with the base name of the file that contains the anonymous \n" + "namespace. By default anonymous namespace are hidden. \n", + FALSE + ); + cb = addBool( "HIDE_UNDOC_MEMBERS", "If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n" "undocumented members of documented classes, files or namespaces. \n" diff --git a/src/definition.cpp b/src/definition.cpp index 668e566..ba0bcd2 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -18,6 +18,7 @@ #include "qtbc.h" #include <ctype.h> #include <qregexp.h> +#include <md5.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -63,6 +64,7 @@ class DefinitionImpl DocInfo *details; // not exported BriefInfo *brief; // not exported BodyInfo *body; // not exported + QCString docSignatures; QCString localName; // local (unqualified) name of the definition // in the future m_name should become m_localName @@ -280,7 +282,7 @@ Definition::Definition(const char *df,int dl, m_isSymbol = isSymbol; if (isSymbol) addToMap(name,this); _setBriefDescription(b,df,dl); - _setDocumentation(d,df,dl,TRUE); + _setDocumentation(d,df,dl,TRUE,FALSE); if (matchExcludedSymbols(name)) m_impl->hidden = TRUE; } @@ -348,7 +350,25 @@ void Definition::writeDocAnchorsToTagFile() } } -void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) +bool Definition::_docsAlreadyAdded(const QString &doc) +{ + uchar md5_sig[16]; + QCString sigStr(33); + MD5Buffer((const unsigned char *)doc.data(),doc.length(),md5_sig); + MD5SigToString(md5_sig,sigStr.data(),33); + if (m_impl->docSignatures.find(sigStr)==-1) // new docs, add signature to prevent re-adding it + { + m_impl->docSignatures+=":"+sigStr; + return FALSE; + } + else + { + return TRUE; + } +} + +void Definition::_setDocumentation(const char *d,const char *docFile,int docLine, + bool stripWhiteSpace,bool atTop) { if (d==0) return; //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace); @@ -361,52 +381,82 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine { doc=d; } - //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); - if (m_impl->details==0) + if (!_docsAlreadyAdded(doc)) { - m_impl->details = new DocInfo; + //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); + if (m_impl->details==0) + { + m_impl->details = new DocInfo; + } + if (m_impl->details->doc.isEmpty()) // fresh detailed description + { + m_impl->details->doc = doc; + } + else if (atTop) // another detailed description, append it to the start + { + m_impl->details->doc = doc+"\n\n"+m_impl->details->doc; + } + else // another detailed description, append it to the end + { + m_impl->details->doc += "\n\n"+doc; + } + if (docLine!=-1) // store location if valid + { + m_impl->details->file = docFile; + m_impl->details->line = docLine; + } } - m_impl->details->doc = doc; - m_impl->details->file = docFile; - m_impl->details->line = docLine; } void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) { if (d==0) return; makeResident(); - _setDocumentation(d,docFile,docLine,stripWhiteSpace); + _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE); } #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase) void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine) { - if (b==0) return; static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE"); static bool needsDot = outputLanguage!="Japanese" && outputLanguage!="Chinese" && outputLanguage!="Korean"; - //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); - if (m_impl->brief==0) - { - m_impl->brief = new BriefInfo; - } - m_impl->brief->doc=QCString(b).stripWhiteSpace(); - int bl=m_impl->brief->doc.length(); + QCString brief = b; + brief = brief.stripWhiteSpace(); + if (brief.isEmpty()) return; + int bl = brief.length(); if (bl>0 && needsDot) // add punctuation if needed { - switch(m_impl->brief->doc.at(bl-1)) + switch(brief.at(bl-1)) { case '.': case '!': case '?': break; default: - if (uni_isupper(m_impl->brief->doc.at(0))) m_impl->brief->doc+='.'; + if (uni_isupper(brief.at(0))) brief+='.'; break; } } - m_impl->brief->file = briefFile; - m_impl->brief->line = briefLine; - m_impl->brief->tooltip = parseCommentAsText(m_impl->brief->doc,briefFile,briefLine); + + if (m_impl->brief && !m_impl->brief->doc.isEmpty()) + { + //printf("adding to details\n"); + _setDocumentation(brief,briefFile,briefLine,FALSE,TRUE); + } + else if (!_docsAlreadyAdded(brief)) + { + //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); + if (m_impl->brief==0) + { + m_impl->brief = new BriefInfo; + } + m_impl->brief->doc=brief; + if (briefLine!=-1) + { + m_impl->brief->file = briefFile; + m_impl->brief->line = briefLine; + } + } } void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) @@ -1100,7 +1150,24 @@ QCString Definition::briefDescription() const QCString Definition::briefDescriptionAsTooltip() const { makeResident(); - return m_impl->brief ? m_impl->brief->tooltip : QCString(""); + if (m_impl->brief) + { + if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) + { + static bool reentering=FALSE; + if (!reentering) + { + reentering=TRUE; // prevent requests for tooltips while parsing a tooltip + m_impl->brief->tooltip = parseCommentAsText( + m_impl->brief->doc, + m_impl->brief->file, + m_impl->brief->line); + reentering=FALSE; + } + } + return m_impl->brief->tooltip; + } + return QCString(""); } int Definition::briefLine() const @@ -1245,6 +1312,7 @@ void Definition::flushToDisk() const marshalDocInfo (Doxygen::symbolStorage,m_impl->details); marshalBriefInfo (Doxygen::symbolStorage,m_impl->brief); marshalBodyInfo (Doxygen::symbolStorage,m_impl->body); + marshalQCString (Doxygen::symbolStorage,m_impl->docSignatures); marshalQCString (Doxygen::symbolStorage,m_impl->localName); marshalQCString (Doxygen::symbolStorage,m_impl->qualifiedName); marshalQCString (Doxygen::symbolStorage,m_impl->ref); @@ -1274,6 +1342,7 @@ void Definition::loadFromDisk() const m_impl->details = unmarshalDocInfo (Doxygen::symbolStorage); m_impl->brief = unmarshalBriefInfo (Doxygen::symbolStorage); m_impl->body = unmarshalBodyInfo (Doxygen::symbolStorage); + m_impl->docSignatures = unmarshalQCString (Doxygen::symbolStorage); m_impl->localName = unmarshalQCString (Doxygen::symbolStorage); m_impl->qualifiedName = unmarshalQCString (Doxygen::symbolStorage); m_impl->ref = unmarshalQCString (Doxygen::symbolStorage); diff --git a/src/definition.h b/src/definition.h index 0b8b95e..2bbc682 100644 --- a/src/definition.h +++ b/src/definition.h @@ -310,7 +310,8 @@ class Definition : public DefinitionIntf, public LockableObj void _writeSourceRefList(OutputList &ol,const char *scopeName, const QCString &text,MemberSDict *members,bool); void _setBriefDescription(const char *b,const char *briefFile,int briefLine); - void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace); + void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace,bool atTop); + bool _docsAlreadyAdded(const QString &doc); DefinitionImpl *m_impl; // internal structure holding all private data QCString m_name; bool m_isSymbol; diff --git a/src/docparser.cpp b/src/docparser.cpp index e9d16af..dff6940 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -68,23 +68,7 @@ static const char *sectionLevelToName[] = //--------------------------------------------------------------------------- -// global variables during a call to validatingParseDoc -static bool g_hasParamCommand; -static bool g_hasReturnCommand; -static MemberDef * g_memberDef; -static QDict<void> g_paramsFound; -static bool g_isExample; -static QCString g_exampleName; -static SectionDict *g_sectionDict; - -static QCString g_searchUrl; - -// include file state -static QString g_includeFileText; -static uint g_includeFileOffset; -static uint g_includeFileLength; - -// parser state +// Parser state: global variables during a call to validatingParseDoc static QString g_context; static bool g_inSeeBlock; static bool g_insideHtmlLink; @@ -95,6 +79,20 @@ static QList<Definition> g_copyStack; static QString g_fileName; static QString g_relPath; +static bool g_hasParamCommand; +static bool g_hasReturnCommand; +static MemberDef * g_memberDef; +static QDict<void> g_paramsFound; +static bool g_isExample; +static QCString g_exampleName; +static SectionDict * g_sectionDict; +static QCString g_searchUrl; + +static QString g_includeFileText; +static uint g_includeFileOffset; +static uint g_includeFileLength; + +// parser's context to store all global variables struct DocParserContext { QString context; @@ -104,9 +102,23 @@ struct DocParserContext QStack<DocStyleChange> styleStack; QStack<DocStyleChange> initialStyleStack; QList<Definition> copyStack; - MemberDef *memberDef; QString fileName; QString relPath; + + bool hasParamCommand; + bool hasReturnCommand; + MemberDef * memberDef; + QDict<void> paramsFound; + bool isExample; + QCString exampleName; + SectionDict *sectionDict; + QCString searchUrl; + + QString includeFileText; + uint includeFileOffset; + uint includeFileLength; + + TokenInfo *token; }; static QStack<DocParserContext> g_parserStack; @@ -115,6 +127,10 @@ static QStack<DocParserContext> g_parserStack; static void docParserPushContext() { + //QCString indent; + //indent.fill(' ',g_parserStack.count()*2+2); + //printf("%sdocParserPushContext() count=%d\n",indent.data(),g_nodeStack.count()); + doctokenizerYYpushContext(); DocParserContext *ctx = new DocParserContext; ctx->context = g_context; @@ -126,6 +142,23 @@ static void docParserPushContext() ctx->copyStack = g_copyStack; ctx->fileName = g_fileName; ctx->relPath = g_relPath; + + ctx->hasParamCommand = g_hasParamCommand; + ctx->hasReturnCommand = g_hasReturnCommand; + ctx->memberDef = g_memberDef; + ctx->paramsFound = g_paramsFound; + ctx->isExample = g_isExample; + ctx->exampleName = g_exampleName; + ctx->sectionDict = g_sectionDict; + ctx->searchUrl = g_searchUrl; + + ctx->includeFileText = g_includeFileText; + ctx->includeFileOffset = g_includeFileOffset; + ctx->includeFileLength = g_includeFileLength; + + ctx->token = g_token; + g_token = new TokenInfo; + g_parserStack.push(ctx); } @@ -141,8 +174,29 @@ static void docParserPopContext() g_copyStack = ctx->copyStack; g_fileName = ctx->fileName; g_relPath = ctx->relPath; + + g_hasParamCommand = ctx->hasParamCommand; + g_hasReturnCommand = ctx->hasReturnCommand; + g_memberDef = ctx->memberDef; + g_paramsFound = ctx->paramsFound; + g_isExample = ctx->isExample; + g_exampleName = ctx->exampleName; + g_sectionDict = ctx->sectionDict; + g_searchUrl = ctx->searchUrl; + + g_includeFileText = ctx->includeFileText; + g_includeFileOffset = ctx->includeFileOffset; + g_includeFileLength = ctx->includeFileLength; + + delete g_token; + g_token = ctx->token; + delete ctx; doctokenizerYYpopContext(); + + //QCString indent; + //indent.fill(' ',g_parserStack.count()*2+2); + //printf("%sdocParserPopContext() count=%d\n",indent.data(),g_nodeStack.count()); } //--------------------------------------------------------------------------- @@ -5876,7 +5930,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, // md?md->name().data():"<none>"); //printf("========== validating %s at line %d\n",fileName,startLine); //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input); - g_token = new TokenInfo; + //g_token = new TokenInfo; + + // store parser state so we can re-enter this function if needed + docParserPushContext(); if (ctx && (ctx->definitionType()==Definition::TypeClass || @@ -5999,10 +6056,12 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, doctokenizerYYlineno=startLine; doctokenizerYYinit(input,g_fileName); + // build abstract syntax tree DocRoot *root = new DocRoot(md!=0,singleLine); root->parse(); + if (Debug::isFlagSet(Debug::PrintTree)) { // pretty print the result @@ -6011,24 +6070,29 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, delete v; } + checkUndocumentedParams(); detectNoDocumentedParams(); - delete g_token; - // TODO: These should be called at the end of the program. //doctokenizerYYcleanup(); //Mappers::cmdMapper->freeInstance(); //Mappers::htmlTagMapper->freeInstance(); + // restore original parser state + docParserPopContext(); + return root; } DocNode *validatingParseText(const char *input) { + // store parser state so we can re-enter this function if needed + docParserPushContext(); + //printf("------------ input ---------\n%s\n" // "------------ end input -----\n",input); - g_token = new TokenInfo; + //g_token = new TokenInfo; g_context = ""; g_fileName = "<parseText>"; g_relPath = ""; @@ -6068,8 +6132,8 @@ DocNode *validatingParseText(const char *input) } } - delete g_token; - + // restore original parser state + docParserPopContext(); return txt; } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 54ace8a..49ea331 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -488,6 +488,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) if ((gd=Doxygen::groupSDict->find(root->name))) { +#if 0 if ( root->groupDocType==Entry::GROUPDOC_NORMAL ) { warn(root->fileName,root->startLine, @@ -496,6 +497,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) root->name.data()); } else +#endif { if ( !gd->hasGroupTitle() ) gd->setGroupTitle( root->type ); @@ -503,12 +505,10 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) warn( root->fileName,root->startLine, "group %s: ignoring title \"%s\" that does not match old title \"%s\"\n", root->name.data(), root->type.data(), gd->groupTitle() ); - if ( gd->briefDescription().isEmpty() ) + //if ( gd->briefDescription().isEmpty() ) gd->setBriefDescription(root->brief,root->briefFile,root->briefLine); - if ( !root->doc.stripWhiteSpace().isEmpty() ) - gd->setDocumentation( gd->documentation().isEmpty() ? root->doc : - gd->documentation() + "\n\n" + root->doc, - root->docFile, root->docLine ); + //if ( !root->doc.stripWhiteSpace().isEmpty() ) + gd->setDocumentation( root->doc, root->docFile, root->docLine ); gd->addSectionsToDefinition(root->anchors); gd->setRefItems(root->sli); //addGroupToGroups(root,gd); @@ -637,6 +637,7 @@ static void buildFileList(EntryNav *rootNav) //printf("**************** root->name=%s fd=%p\n",root->name.data(),fd); if (fd && !ambig) { +#if 0 if ((!root->doc.isEmpty() && !fd->documentation().isEmpty()) || (!root->brief.isEmpty() && !fd->briefDescription().isEmpty())) { @@ -648,6 +649,7 @@ static void buildFileList(EntryNav *rootNav) ); } else +#endif { //printf("Adding documentation!\n"); // using FALSE in setDocumentation is small hack to make sure a file @@ -1088,6 +1090,7 @@ static void addClassToContext(EntryNav *rootNav) // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data()); // cd->setTemplateArguments(tArgList); //} +#if 0 if (!root->doc.isEmpty() || !root->brief.isEmpty() || (root->bodyLine!=-1 && Config_getBool("SOURCE_BROWSER")) ) @@ -1103,9 +1106,11 @@ static void addClassToContext(EntryNav *rootNav) ); } else if (!root->doc.isEmpty()) +#endif { cd->setDocumentation(root->doc,root->docFile,root->docLine); } +#if 0 if (!root->brief.isEmpty() && !cd->briefDescription().isEmpty()) { warn( @@ -1116,6 +1121,7 @@ static void addClassToContext(EntryNav *rootNav) ); } else if (!root->brief.isEmpty()) +#endif { cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); } @@ -1125,7 +1131,9 @@ static void addClassToContext(EntryNav *rootNav) cd->setBodyDef(fd); } //cd->setName(fullName); // change name to match docs +#if 0 } +#endif if (cd->templateArguments()==0) { @@ -1360,13 +1368,13 @@ static void buildNamespaceList(EntryNav *rootNav) //printf("** buildNamespaceList(%s)\n",root->name.data()); - QCString fullName = root->name; + QCString fName = root->name; if (root->section==Entry::PACKAGEDOC_SEC) { - fullName=substitute(fullName,".","::"); + fName=substitute(fName,".","::"); } - - fullName = stripAnonymousNamespaceScope(fullName); + + QCString fullName = stripAnonymousNamespaceScope(fName); if (!fullName.isEmpty()) { //printf("Found namespace %s in %s at line %d\n",root->name.data(), @@ -1374,13 +1382,16 @@ static void buildNamespaceList(EntryNav *rootNav) NamespaceDef *nd; if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace { +#if 0 if (!root->doc.isEmpty() || !root->brief.isEmpty()) // block contains docs { if (nd->documentation().isEmpty() && !root->doc.isEmpty()) { +#endif nd->setDocumentation(root->doc,root->docFile,root->docLine); nd->setName(fullName); // change name to match docs nd->addSectionsToDefinition(root->anchors); +#if 0 } else if (!nd->documentation().isEmpty() && !root->doc.isEmpty()) { @@ -1392,7 +1403,9 @@ static void buildNamespaceList(EntryNav *rootNav) } if (nd->briefDescription().isEmpty() && !root->brief.isEmpty()) { +#endif nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); +#if 0 nd->setName(fullName); // change name to match docs } else if (!nd->briefDescription().isEmpty() && !root->brief.isEmpty()) @@ -1404,6 +1417,7 @@ static void buildNamespaceList(EntryNav *rootNav) ); } } +#endif // file definition containing the namespace nd FileDef *fd=rootNav->fileDef(); @@ -2199,7 +2213,8 @@ static int findFunctionPtr(const QCString &type,int *pLength=0) if (!type.isEmpty() && // return type is non-empty (i=re.match(type,0,&l))!=-1 && // contains (...*...) type.find("operator")==-1 && // not an operator - type.find(")(")==-1 // not a function pointer return type + (type.find(")(")==-1 || type.find("typedef ")!=-1) + // not a function pointer return type ) { if (pLength) *pLength=l; @@ -2392,6 +2407,7 @@ static void buildVarList(EntryNav *rootNav) else { int i=isFuncPtr; + if (i==-1) i=findFunctionPtr(root->type); // for typedefs isFuncPtr is not yet set if (i!=-1) // function pointer { int ai = root->type.find('[',i); @@ -2847,10 +2863,16 @@ static void buildFunctionList(EntryNav *rootNav) { NamespaceDef *mnd = md->getNamespaceDef(); NamespaceDef *rnd = 0; - if (!rootNav->parent()->name().isEmpty()) + //printf("root namespace=%s\n",rootNav->parent()->name().data()); + QCString fullScope = scope; + QCString parentScope = rootNav->parent()->name(); + if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope)) { - rnd = getResolvedNamespace(rootNav->parent()->name()); + if (!scope.isEmpty()) fullScope.prepend("::"); + fullScope.prepend(parentScope); } + //printf("fullScope=%s\n",fullScope.data()); + rnd = getResolvedNamespace(fullScope); FileDef *mfd = md->getFileDef(); QCString nsName,rnsName; if (mnd) nsName = mnd->name().copy(); @@ -2870,6 +2892,7 @@ static void buildFunctionList(EntryNav *rootNav) gd = Doxygen::groupSDict->find(root->groups->first()->groupname.data()); } //printf("match!\n"); + //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data()); // see if we need to create a new member found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and @@ -2893,9 +2916,6 @@ static void buildFunctionList(EntryNav *rootNav) // merge documentation if (md->documentation().isEmpty() && !root->doc.isEmpty()) { - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); ArgumentList *argList = new ArgumentList; stringToArgumentList(root->args,argList); if (root->proto) @@ -2908,21 +2928,28 @@ 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); if (md->briefDescription().isEmpty() && !root->brief.isEmpty()) { - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); 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); @@ -4648,6 +4675,8 @@ static void addMemberDocs(EntryNav *rootNav, //printf("Adding docs md->docs=`%s' root->docs=`%s'!\n", // md->documentation().data(),root->doc.data()); // documentation outside a compound overrides the documentation inside it + +#if 0 if ( /* !md->isStatic() && !root->stat && do not replace doc of a static */ ( md->documentation().isEmpty() || /* no docs yet */ @@ -4656,6 +4685,7 @@ static void addMemberDocs(EntryNav *rootNav, ) ) && !root->doc.isEmpty() ) +#endif { //printf("overwrite!\n"); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -4666,12 +4696,14 @@ static void addMemberDocs(EntryNav *rootNav, // md->briefDescription().data(),root->brief.data()); // brief descriptions inside a compound override the documentation // outside it +#if 0 if ( /* !md->isStatic() && !root->stat && do not replace doc of static */ ( md->briefDescription().isEmpty() || /* no docs yet */ !rootNav->parent()->name().isEmpty() /* member of a class */ ) && !root->brief.isEmpty() ) +#endif { //printf("overwrite!\n"); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -5715,6 +5747,7 @@ static void findMember(EntryNav *rootNav, // root->argList ? (int)root->argList->count() : -1); // new related (member) function +#if 0 // removed as it doesn't handle related template functions correctly ArgumentList *tArgList = getTemplateArgumentsFromName(scopeName+"::"+funcName,root->tArgLists); MemberDef *md=new MemberDef( @@ -5722,7 +5755,37 @@ static void findMember(EntryNav *rootNav, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,TRUE, mtype,tArgList,funcArgs.isEmpty() ? 0 : root->argList); +#endif + // first note that we pass: + // (root->tArgLists ? root->tArgLists->last() : 0) + // for the template arguments fo the new "member." + // this accurately reflects the template arguments of + // the related function, which don't have to do with + // those of the related class. + MemberDef *md=new MemberDef( + root->fileName,root->startLine, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,TRUE, + mtype, + (root->tArgLists ? root->tArgLists->last() : 0), + funcArgs.isEmpty() ? 0 : root->argList); + // + // we still have the problem that + // MemberDef::writeDocumentation() in memberdef.cpp + // writes the template argument list for the class, + // as if this member is a member of the class. + // fortunately, MemberDef::writeDocumentation() has + // a special mechanism that allows us to totally + // override the set of template argument lists that + // are printed. We use that and set it to the + // template argument lists of the related function. + // + md->setDefinitionTemplateParameterLists(root->tArgLists); + md->setTagInfo(rootNav->tagInfo()); + + + //printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n", // funcName.data(),funcDecl.data(),root->bodyLine); @@ -6541,7 +6604,9 @@ static void findEnumDocumentation(EntryNav *rootNav) if (cd && cd->name()==className && md->isEnumerate()) { // documentation outside a compound overrides the documentation inside it +#if 0 if (!md->documentation() || rootNav->parent()->name().isEmpty()) +#endif { md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); @@ -6549,7 +6614,9 @@ static void findEnumDocumentation(EntryNav *rootNav) // brief descriptions inside a compound override the documentation // outside it +#if 0 if (!md->briefDescription() || !rootNav->parent()->name().isEmpty()) +#endif { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } @@ -7374,12 +7441,16 @@ static void findDefineDocumentation(EntryNav *rootNav) { if (md->memberType()==MemberDef::Define) { +#if 0 if (md->documentation().isEmpty()) +#endif { md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); } +#if 0 if (md->briefDescription().isEmpty()) +#endif { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } @@ -7416,12 +7487,16 @@ static void findDefineDocumentation(EntryNav *rootNav) if (fd && fd->absFilePath()==root->fileName) // doc and define in the same file assume they belong together. { +#if 0 if (md->documentation().isEmpty()) +#endif { md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); } +#if 0 if (md->briefDescription().isEmpty()) +#endif { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 356c7b4..d7257f1 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -184,7 +184,8 @@ void LatexGenerator::init() } else // use pdflatex for higher quality output { - t << "all: clean refman.pdf" << endl << endl; + t << "all: clean refman.pdf" << endl << endl + << "pdf: refman.pdf" << endl << endl; t << "refman.pdf: refman.tex" << endl; t << "\tpdflatex refman.tex" << endl; t << "\tmakeindex refman.idx" << endl; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index bc8c76e..14d1c2d 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -150,7 +150,7 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd, // or use the following to put the function pointer as it appears in // the prototype. - // bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp; + //bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp; if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute { @@ -455,9 +455,9 @@ void MemberDefImpl::init(Definition *def, initLines=0; type=t; if (mt==MemberDef::Typedef) type.stripPrefix("typedef "); - type.stripPrefix("struct "); - type.stripPrefix("class " ); - type.stripPrefix("union " ); + // type.stripPrefix("struct "); + // type.stripPrefix("class " ); + // type.stripPrefix("union " ); type=removeRedundantWhiteSpace(type); args=a; args=removeRedundantWhiteSpace(args); @@ -970,10 +970,11 @@ bool MemberDef::isBriefSectionVisible() const makeResident(); LockingPtr<MemberDef> lock(this,this); MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId]; + //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info); //QCString *pMemGrp = Doxygen::memberDocDict[grpId]; bool hasDocs = hasDocumentation() || // part of a documented member group - (m_impl->grpId!=-1 && info && !info->doc.isEmpty()); + (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty())); // only include static members with file/namespace scope if // explicitly enabled in the config file @@ -1033,9 +1034,9 @@ bool MemberDef::isBriefSectionVisible() const ); //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d" - // "visibleIfPrivate=%d visibleIfDocVirtual=%d visibltIfNotDefaultCDTor=%d " + // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d " // "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented, - // visibleIfEnabled,visibleIfPrivate,visibleIfDocVirtual,visibleIfNotDefaultCDTor, + // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor, // visibleIfFriendCompound); bool visible = visibleIfStatic && visibleIfDocumented && @@ -1222,7 +1223,7 @@ void MemberDef::writeDeclaration(OutputList &ol, } else { - ltype = ltype.left(i) + " { ... } " + ltype.right(ltype.length()-i-l); + ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l)); linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); } } @@ -1575,7 +1576,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } // get member name - QCString doxyName=name().copy(); + QCString doxyName=name(); // prepend scope if there is any. TODO: make this optional for C only docs if (scopeName) doxyName.prepend((QCString)scopeName+"::"); QCString doxyArgs=argsString(); diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 6bb14af..3f04712 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -67,6 +67,7 @@ void MemberList::countDecMembers(bool countEnumValues) MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { + //printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible()); if (md->isBriefSectionVisible()) { switch(md->memberType()) @@ -177,8 +178,12 @@ void MemberList::writePlainDeclarations(OutputList &ol, { //printf("----- writePlainDeclaration() ----\n"); countDecMembers(); - if (numDecMembers()==0) return; // no members in this list - //printf("----> writePlainDeclaration() numDecMembers()=%d\n", + if (numDecMembers()==0) + { + //printf(" --> no members!\n"); + return; // no members in this list + } + //printf(" --> writePlainDeclaration() numDecMembers()=%d\n", // numDecMembers()); ol.pushGeneratorState(); diff --git a/src/pyscanner.l b/src/pyscanner.l index ed3f10b..5b5f6cb 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -1000,7 +1000,7 @@ STARTDOCSYMS ^{B}"##"/[^#] // prepend scope in case of nested classes if (current_root->section&Entry::SCOPE_MASK) { - printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data()); + //printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data()); current->name.prepend(current_root->name+"::"); } diff --git a/src/scanner.l b/src/scanner.l index 09c52fb..584f1b2 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -114,6 +114,7 @@ static bool insideD = FALSE; //!< processing D code? static bool insidePHP = FALSE; //!< processing PHP code? static bool insideObjC = FALSE; //!< processing Objective C code? static bool insideCli = FALSE; //!< processing C++/CLI code? +static bool insideJS = FALSE; //!< processing JavaScript code? static bool insideCppQuote = FALSE; static bool insideProtocolList = FALSE; @@ -330,6 +331,7 @@ static void setContext() insideD = langExt==SrcLangExt_D; insidePHP = langExt==SrcLangExt_PHP; insideObjC = langExt==SrcLangExt_ObjC; + insideJS = langExt==SrcLangExt_JS; if ( insidePHP ) { useOverrideCommands = TRUE; @@ -506,6 +508,23 @@ static void addKnRArgInfo(const QCString &type,const QCString &name, } //----------------------------------------------------------------------------- + + +void fixArgumentListForJavaScript(ArgumentList *al) +{ + if (al==0) return; + ArgumentListIterator ali(*al); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + if (!a->type.isEmpty() && a->name.isEmpty()) + { // a->type is actually the (typeless) parameter name, so move it + a->name=a->type; + a->type.resize(0); + } + } +} + /* ----------------------------------------------------------------- */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); @@ -750,6 +769,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) unput(*yytext); BEGIN( FindMembers ); } +<FindMembers>"<?php" { // PHP code with unsupported extension? + insidePHP = TRUE; + } <FindMembersPHP>"<?"("php"?) { // PHP code start BEGIN( FindMembers ); } @@ -902,7 +924,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } <CliPropertyType>"{" { curlyCount=0; - printf("event: '%s' '%s'\n",current->type.data(),current->name.data()); + //printf("event: '%s' '%s'\n",current->type.data(),current->name.data()); BEGIN( CSAccessorDecl ); } <CliPropertyType>";" { @@ -1762,13 +1784,21 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) insideTryBlock=FALSE; BEGIN(TryFunctionBlock); } + else if (insideJS && strcmp(yytext,"var")==0) + { // javascript variable + current->type="var"; + } + else if (insideJS && strcmp(yytext,"function")==0) + { // javascript function + current->type="function"; + } else { if (YY_START==FindMembers) { addType( current ) ; } - bool javaLike = insideJava || insideCS || insideD || insidePHP; + bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; if (javaLike && strcmp(yytext,"public")==0) { current->protection = Public; @@ -1781,6 +1811,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) { current->protection = Private; } + else if (javaLike && strcmp(yytext,"static")==0) + { + if (YY_START==FindMembers) + current->name = yytext; + else + current->name += yytext; + current->stat = TRUE; + } else { if (YY_START==FindMembers) @@ -2866,7 +2904,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || - insideJava || insidePHP || insideCS || insideD + insideJava || insidePHP || insideCS || insideD || insideJS ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); @@ -2902,6 +2940,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) BEGIN( TypedefName ); } } +<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword + lineCount(); + current->type.prepend(yytext); + } <TypedefName>{ID} { if (current->section == Entry::ENUM_SEC) { @@ -3285,6 +3327,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); + if (insideJS) + { + fixArgumentListForJavaScript(current->argList); + } handleParametersCommentBlocks(current->argList); /* remember the current documentation block, since @@ -4193,7 +4239,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) roundCount=0; BEGIN(SkipUnionSwitch); } - else if ((insideJava || insidePHP) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) + else if ((insideJava || insidePHP || insideJS) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) { current->type.resize(0); baseProt=Public; @@ -4362,7 +4408,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) { if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces { - current->name.sprintf("@%d",anonNSCount); + if (Config_getBool("EXTRACT_ANON_NSPACES")) // use visible name + { + current->name="anonymous_namespace{"+stripPath(current->fileName)+"}"; + } + else // use invisible name + { + current->name.sprintf("@%d",anonNSCount); + } } else { @@ -4573,12 +4626,23 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) //printf("Start doc block at %d\n",yyLineNr); removeSlashes=(yytext[1]=='/'); tmpDocType=-1; +#if 0 if (YY_START!=SkipCurly) { current->doc.resize(0); + } +#endif + if (!current->doc.isEmpty()) + { + current->doc+="\n\n"; + } + else + { current->docLine = yyLineNr; current->docFile = yyFileName; } +// + lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) { @@ -4597,6 +4661,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->briefLine = yyLineNr; current->briefFile = yyFileName; } +#if 0 if (!docBlockInBody) { current->doc.resize(0); @@ -4605,6 +4670,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->brief.resize(0); } } +#endif startCommentBlock(FALSE); BEGIN( DocBlock ); } @@ -4631,6 +4697,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->briefLine = yyLineNr; current->briefFile = yyFileName; } +#if 0 if (!docBlockInBody) { current->doc.resize(0); @@ -4639,16 +4706,19 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->brief.resize(0); } } +#endif startCommentBlock(FALSE); BEGIN( DocBlock ); } <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" { +#if 0 if (YY_START!=SkipCurly) { current->brief.resize(0); current->briefFile=yyFileName; current->briefLine=yyLineNr; } +#endif tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) @@ -4663,16 +4733,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) docBlockInBody = YY_START==SkipCurly; docBlockAutoBrief = FALSE; docBlock.resize(0); - startCommentBlock(TRUE); + startCommentBlock(current->brief.isEmpty()); BEGIN( DocLine ); } <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] { +#if 0 if (YY_START!=SkipCurly) { current->brief.resize(0); current->briefFile=yyFileName; current->briefLine=yyLineNr; } +#endif tmpDocType=-1; lastDocContext = YY_START; if (current_root->section & Entry::SCOPE_MASK) @@ -4687,7 +4759,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) docBlockInBody = YY_START==SkipCurly; docBlockAutoBrief = FALSE; docBlock.resize(0); - startCommentBlock(TRUE); + startCommentBlock(current->brief.isEmpty()); BEGIN( DocLine ); } <FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? { @@ -4777,7 +4849,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } <DocLine>[^\n]*/"\n" { // whole line docBlock+=yytext; - handleCommentBlock(docBlock,TRUE); + handleCommentBlock(docBlock,current->brief.isEmpty()); BEGIN( docBlockContext ); } @@ -5148,7 +5220,7 @@ static void parseCompounds(Entry *rt) BEGIN( FindMembers ) ; current_root = ce ; yyFileName = ce->fileName; - setContext(); + //setContext(); yyLineNr = ce->startLine ; insideObjC = ce->objc; //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); @@ -5160,15 +5232,12 @@ static void parseCompounds(Entry *rt) // set default protection based on the compound type if( ce->section==Entry::CLASS_SEC ) // class { - if ( - ce->fileName.right(4)==".php" || - ce->fileName.right(4)==".inc" || - ce->fileName.right(2)==".d" - ) + + if (insidePHP || insideD || insideJS) { current->protection = protection = Public ; } - else if (ce->fileName.right(5)==".java") + else if (insideJava) { current->protection = protection = Package ; } diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp index 9e5cd21..88afcb2 100644 --- a/src/textdocvisitor.cpp +++ b/src/textdocvisitor.cpp @@ -73,7 +73,7 @@ void TextDocVisitor::filter(const char *str) { case '\n': m_t << " "; break; case '"': m_t << """; break; - case '\'': m_t << "'"; break; + case '\'': m_t << "'"; break; case '<': m_t << "<"; break; case '>': m_t << ">"; break; case '&': m_t << "&"; break; diff --git a/src/util.cpp b/src/util.cpp index fde2dab..5ab4a29 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -163,8 +163,8 @@ QCString removeAnonymousScopes(const QCString &s) return result; } -// replace anonymous scopes with __anonymous__ -QCString replaceAnonymousScopes(const QCString &s) +// replace anonymous scopes with __anonymous__ or replacement if provided +QCString replaceAnonymousScopes(const QCString &s,const char *replacement) { QCString result; if (s.isEmpty()) return result; @@ -174,7 +174,14 @@ QCString replaceAnonymousScopes(const QCString &s) while ((i=re.match(s,p,&l))!=-1) { result+=s.mid(p,i-p); - result+="__anonymous__"; + if (replacement) + { + result+=replacement; + } + else + { + result+="__anonymous__"; + } p=i+l; } result+=s.right(sl-p); @@ -4556,6 +4563,8 @@ QCString escapeCharsInString(const char *name,bool allowDots) case '!': result+="_9"; break; case ',': result+="_00"; break; case ' ': result+="_01"; break; + case '{': result+="_02"; break; + case '}': result+="_03"; break; default: if (caseSenseNames || !isupper(c)) { @@ -4654,6 +4663,7 @@ QCString convertNameToFile(const char *name,bool allowDots) #endif result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir)); } + //printf("*** convertNameToFile(%s)->%s\n",name,result.data()); return result; } @@ -4821,12 +4831,6 @@ QCString stripScope(const char *name) } -/*! Convert nibble (range 0..15) to hex char */ -//static char nibbleToHex(int n) -//{ -// return (n < 10) ? ('0'+n) : ('a'+n-10); -//} - /*! Converts a string to an XML-encoded string */ QCString convertToXML(const char *s) { @@ -4843,19 +4847,7 @@ QCString convertToXML(const char *s) case '&': result+="&"; break; case '\'': result+="'"; break; case '"': result+="""; break; - default: - //if (c<0) - //{ <- this doesn't work for languages that use - // characters with codes beyond 255 - // result+=(QCString)"&#x" + - // nibbleToHex((((uchar)c)>>4)&0xf)+ - // nibbleToHex(c&0xf)+";"; - //} - //else - //{ - result+=c; - //} - break; + default: result+=c; break; } } return result; @@ -4864,7 +4856,23 @@ QCString convertToXML(const char *s) /*! Converts a string to a HTML-encoded string */ QCString convertToHtml(const char *s) { - return convertToXML(s); + QCString result; + if (s==0) return result; + const char *p=s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '<': result+="<"; break; + case '>': result+=">"; break; + case '&': result+="&"; break; + case '\'': result+="'"; break; + case '"': result+="""; break; + default: result+=c; break; + } + } + return result; } /*! Returns the standard string that is generated when the \\overload @@ -5304,7 +5312,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo) { // append documentation block to the page. - pd->setDocumentation(pd->documentation()+"\n\n"+doc,fileName,startLine); + pd->setDocumentation(doc,fileName,startLine); //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pi,name); } else // new page @@ -5999,8 +6007,8 @@ SrcLangExt getLanguageFromFileName(const QCString fileName) extLookup.insert(".odl", new int(SrcLangExt_IDL)); extLookup.insert(".ddl", new int(SrcLangExt_IDL)); extLookup.insert(".java", new int(SrcLangExt_Java)); - extLookup.insert(".jsl", new int(SrcLangExt_Java)); - extLookup.insert(".as", new int(SrcLangExt_Java)); + extLookup.insert(".as", new int(SrcLangExt_JS)); + extLookup.insert(".js", new int(SrcLangExt_JS)); extLookup.insert(".cs", new int(SrcLangExt_CSharp)); extLookup.insert(".d", new int(SrcLangExt_D)); extLookup.insert(".php", new int(SrcLangExt_PHP)); @@ -92,6 +92,7 @@ enum SrcLangExt SrcLangExt_PHP = 0x080, SrcLangExt_ObjC = 0x100, SrcLangExt_Cpp = 0x200, + SrcLangExt_JS = 0x400, }; //-------------------------------------------------------------------- @@ -215,7 +216,7 @@ int getPrefixIndex(const QCString &name); QCString removeAnonymousScopes(const QCString &s); -QCString replaceAnonymousScopes(const QCString &s); +QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0); void initClassHierarchy(ClassSDict *cl); |