diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2005-04-21 21:10:51 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2005-04-21 21:10:51 (GMT) |
commit | 4a8c2f5c896a1883a0611d972952a68498002ae5 (patch) | |
tree | 81218085d3e6e15b1ce6c418734013d48e9deda8 /src/util.cpp | |
parent | 570375c30adbdb66714d465d849b18e0df9dd6e6 (diff) | |
download | Doxygen-4a8c2f5c896a1883a0611d972952a68498002ae5.zip Doxygen-4a8c2f5c896a1883a0611d972952a68498002ae5.tar.gz Doxygen-4a8c2f5c896a1883a0611d972952a68498002ae5.tar.bz2 |
Release-1.4.2-20050421
Diffstat (limited to 'src/util.cpp')
-rw-r--r-- | src/util.cpp | 123 |
1 files changed, 111 insertions, 12 deletions
diff --git a/src/util.cpp b/src/util.cpp index 7c6e298..dd012aa 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1046,25 +1046,47 @@ ClassDef *getResolvedClassRec(Definition *scope, return 0; } + bool hasUsingStatements = + (fileScope && ((fileScope->getUsedNamespaces() && + fileScope->getUsedNamespaces()->count()>0) || + (fileScope->getUsedClasses() && + fileScope->getUsedClasses()->count()>0)) + ); // Since it is often the case that the same name is searched in the same // scope over an over again (especially for the linked source code generation) // we use a cache to collect previous results. This is possible since the // result of a lookup is deterministic. As the key we use the concatenated // scope, the name to search for and the explicit scope prefix. The speedup // achieved by this simple cache can be enormous. - QCString key=scope->name()+"+"+name+"+"+explicitScopePart; + int scopeNameLen = scope->name().length()+1; + int nameLen = name.length()+1; + int explicitPartLen = explicitScopePart.length(); + int fileScopeLen = hasUsingStatements ? 1+fileScope->name().length() : 0; + + // below is a more efficient coding of + // QCString key=scope->name()+"+"+name+"+"+explicitScopePart; + QCString key(scopeNameLen+nameLen+explicitPartLen+fileScopeLen+1); + char *p=key.data(); + qstrcpy(p,scope->name()); *(p+scopeNameLen-1)='+'; + p+=scopeNameLen; + qstrcpy(p,name); *(p+nameLen-1)='+'; + p+=nameLen; + qstrcpy(p,explicitScopePart); + p+=explicitPartLen; + // if a file scope is given and it contains using statements we should // also use the file part in the key (as a class name can be in // two different namespaces and a using statement in a file can select // one of them). - if (fileScope && ((fileScope->getUsedNamespaces() && - fileScope->getUsedNamespaces()->count()>0) || - (fileScope->getUsedClasses() && - fileScope->getUsedClasses()->count()>0)) - ) + if (hasUsingStatements) { - key+="+"+fileScope->name(); + // below is a more efficient coding of + // key+="+"+fileScope->name(); + *p++='+'; + qstrcpy(p,fileScope->name()); + p+=fileScopeLen-1; } + *p='\0'; LookupInfo *pval=Doxygen::lookupCache.find(key); //printf("Searching for %s result=%p\n",key.data(),pval); @@ -3490,6 +3512,7 @@ bool resolveRef(/* in */ const char *scName, QCString linkToText(const char *link,bool isFileName) { + static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); QCString result=link; if (!result.isEmpty()) { @@ -3502,7 +3525,7 @@ QCString linkToText(const char *link,bool isFileName) { result=result.right(result.length()-2); } - if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + if (optimizeOutputJava) { result=substitute(result,"::","."); } @@ -3769,21 +3792,49 @@ QCString substitute(const char *s,const char *src,const char *dst) //---------------------------------------------------------------------- +struct FindFileCacheElem +{ + FindFileCacheElem(FileDef *fd,bool ambig) : fileDef(fd), isAmbig(ambig) {} + FileDef *fileDef; + bool isAmbig; +}; + +static QCache<FindFileCacheElem> g_findFileDefCache(5000); + FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) { ambig=FALSE; + if (n==0) return 0; + + QCString key; + key.sprintf("%p:",fnDict); + key+=n; + + g_findFileDefCache.setAutoDelete(TRUE); + FindFileCacheElem *cachedResult = g_findFileDefCache.find(key); + if (cachedResult) + { + ambig = cachedResult->isAmbig; + return cachedResult->fileDef; + } + else + { + cachedResult = new FindFileCacheElem(0,FALSE); + } + QCString name=convertToQCString(QDir::cleanDirPath(n)); QCString path; - if (name.isEmpty()) return 0; - int slashPos=QMAX(name.findRev('/'),name.findRev('\\')); + int slashPos; + FileName *fn; + if (name.isEmpty()) goto exit; + slashPos=QMAX(name.findRev('/'),name.findRev('\\')); if (slashPos!=-1) { path=name.left(slashPos+1); name=name.right(name.length()-slashPos-1); } //printf("findFileDef path=`%s' name=`%s'\n",path.data(),name.data()); - if (name.isEmpty()) return 0; - FileName *fn; + if (name.isEmpty()) goto exit; if ((fn=(*fnDict)[name])) { if (fn->count()==1) @@ -3791,6 +3842,8 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) FileDef *fd = fn->getFirst(); if (path.isEmpty() || fd->getPath().right(path.length())==path) { + cachedResult->fileDef = fd; + g_findFileDefCache.insert(key,cachedResult); return fd; } } @@ -3809,9 +3862,14 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) } } ambig=(count>1); + cachedResult->isAmbig = ambig; + cachedResult->fileDef = lastMatch; + g_findFileDefCache.insert(key,cachedResult); return lastMatch; } } +exit: + g_findFileDefCache.insert(key,cachedResult); return 0; } @@ -5276,3 +5334,44 @@ bool findAndRemoveWord(QCString &s,const QCString &word) return FALSE; } +/** Special version of QCString::stripWhiteSpace() that only strips + * empty lines. + */ +QCString stripLeadingAndTrailingEmptyLines(const QCString &s) +{ + const char *p = s.data(); + if (p==0) return 0; + + // search for leading empty lines + int i=0,li=-1,l=s.length(); + char c; + while ((c=*p++)) + { + if (c==' ' || c=='\t' || c=='\r') i++; + else if (c=='\n') i++,li=i; + else break; + } + + // search for trailing empty lines + int b=l-1,bi=-1; + p=s.data()+b; + while (b>=0) + { + c=*--p; + if (c==' ' || c=='\t' || c=='\r') b--; + else if (c=='\n') bi=b,b--; + else break; + } + + // return whole string if no leading or trailing lines where found + if (li==-1 && bi==-1) return s; + + // return substring + if (bi==-1) bi=l; + if (li==-1) li=0; + if (bi<=li) return 0; // only empty lines + return s.mid(li,bi-li); +} + + + |