📄 util.cpp
字号:
return Doxygen::namespaceSDict[name]; }}ClassDef *getResolvedClass( Definition *scope, const char *n, bool *pIsTypeDef, QCString *pTemplSpec ){ //printf("getResolvedClass(%s,%s)\n",scope ? scope->name().data() : "<none>", n); QCString name = n; if (name.isEmpty()) return 0; if (scope==0) scope=Doxygen::globalScope; int i = name.findRev("::"); QCString subst; if (i!=-1) { subst = resolveTypeDef(scope,name.right(name.length()-i-2)); } else { subst = resolveTypeDef(scope,name); } //printf(" typedef subst=`%s'\n",subst.data()); if (!subst.isEmpty()) { // strip * and & from n int ip=subst.length()-1; while (ip>=0 && (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ')) ip--; subst=subst.left(ip+1); if (pIsTypeDef) *pIsTypeDef=TRUE; //printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data()); if (subst==name) // avoid resolving typedef struct foo foo; { return Doxygen::classSDict.find(name); } int count=0; // recursion detection guard QCString newSubst; QCString typeName = subst; if (i!=-1) typeName.prepend(name.left(i)+"::"); while (!(newSubst=resolveTypeDef(scope,typeName)).isEmpty() && count<10) { if (typeName==newSubst) { ClassDef *cd = Doxygen::classSDict.find(subst); // for breaking typedef struct A A; //printf(" getClass: exit `%s' %p\n",subst.data(),cd); return cd; } subst=newSubst; // strip * and & from n int ip=subst.length()-1; while (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ') ip--; subst=subst.left(ip+1); //printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data()); typeName=newSubst; if (i!=-1) typeName.prepend(name.left(i)+"::"); count++; } if (count==10) { warn_cont("Warning: possible recursive typedef dependency detected for %s!\n",n); return Doxygen::classSDict.find(name); } else { int i; ClassDef *cd = Doxygen::classSDict.find(typeName); //printf(" getClass: subst %s->%s cd=%p\n",name.data(),typeName.data(),cd); if (cd==0 && (i=typeName.find('<'))>0) // try unspecialized version as well { if (pTemplSpec) *pTemplSpec = typeName.right(typeName.length()-i); return Doxygen::classSDict.find(typeName.left(i)); } else { return cd; } } } else { if (pIsTypeDef) *pIsTypeDef=FALSE; return Doxygen::classSDict.find(name); }}static bool findOperator(const QCString &s,int i){ int b = s.findRev("operator",i); if (b==-1) return FALSE; // not found b+=8; while (b<i) // check if there are only spaces inbetween // the operator and the > { if (!isspace(s.at(b))) return FALSE; b++; } return TRUE;}static const char constScope[] = { 'c', 'o', 'n', 's', 't', ':' };QCString removeRedundantWhiteSpace(const QCString &s){ if (s.isEmpty()) return s; QCString result; uint i; uint l=s.length(); uint csp=0; for (i=0;i<l;i++) { char c=s.at(i); if (csp<6 && c==constScope[csp]) csp++; else csp=0; if (i<l-2 && c=='<' && // current char is a < (isId(s.at(i+1)) || isspace(s.at(i+1))) && // next 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 } else if (i>0 && c=='>' && // current char is a > (isId(s.at(i-1)) || isspace(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 } else if (i>0 && i<l-1 && c==',' && !isspace(s.at(i-1)) && isId(s.at(i+1))) { result+=", "; } else if (i>0 && isId(s.at(i)) && s.at(i-1)==')') { result+=' '; result+=s.at(i); } else if (c==':' && csp==6) { result+=" :"; csp=0; } else if (!isspace(c) || ( i!=0 && i!=l-1 && (isId(s.at(i-1)) || s.at(i-1)==')' || s.at(i-1)==',' || s.at(i-1)=='>' || s.at(i-1)==']') && isId(s.at(i+1)) ) ) { if (c=='*' || c=='&' || c=='@') { uint rl=result.length(); if (rl>0 && (isId(result.at(rl-1)) || result.at(rl-1)=='>')) result+=' '; } result+=c; } } //printf("removeRedundantWhiteSpace(`%s')=`%s'\n",s.data(),result.data()); return result;} bool rightScopeMatch(const QCString &scope, const QCString &name){ return (name==scope || // equal (scope.right(name.length())==name && // substring scope.at(scope.length()-name.length()-1)==':' // scope ) );}bool leftScopeMatch(const QCString &scope, const QCString &name){ return (name==scope || // equal (scope.left(name.length())==name && // substring scope.at(name.length())==':' // scope ) );}void linkifyText(const TextGeneratorIntf &out,const char *scName,const char *name,const char *text,bool autoBreak,bool external){ //printf("scope=`%s' name=`%s' Text: `%s'\n",scName,name,text); static QRegExp regExp("[a-z_A-Z][a-z_A-Z0-9:]*"); QCString txtStr=text; int strLen = txtStr.length(); //printf("linkifyText strtxt=%s strlen=%d\n",txtStr.data(),strLen); int matchLen; int index=0; int newIndex; int skipIndex=0; int floatingIndex=0; if (strLen==0) return; // read a word from the text string while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1) { // add non-word part to the result floatingIndex+=newIndex-skipIndex; if (strLen>30 && floatingIndex>25 && autoBreak) // try to insert a split point { QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex); int splitLength = splitText.length(); int i=splitText.find('<'); if (i==-1) i=splitText.find(','); if (i==-1) i=splitText.find(' '); if (i!=-1) // add a link-break at i in case of Html output { out.writeString(splitText.left(i+1)); out.writeBreak(); out.writeString(splitText.right(splitLength-i-1)); } else { out.writeString(splitText); } floatingIndex=splitLength-i-1; } else { //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex)); out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex)); } // get word from string QCString word=txtStr.mid(newIndex,matchLen); ClassDef *cd=0; FileDef *fd=0; MemberDef *md=0; NamespaceDef *nd=0; GroupDef *gd=0; QCString scopeName=scName; QCString searchName=name; //printf("word=`%s' scopeName=`%s' searchName=`%s'\n", // word.data(),scopeName.data(),searchName.data() // ); // check if `word' is a documented class name if (!word.isEmpty() && !rightScopeMatch(word,searchName) && !rightScopeMatch(scopeName,word) ) { //printf("Searching...\n"); int scopeOffset=scopeName.length(); bool found=FALSE; do // for each scope (starting with full scope and going to empty scope) { QCString fullName = word.copy(); if (scopeOffset>0) { fullName.prepend(scopeName.left(scopeOffset)+"::"); } //printf("Trying class %s\n",fullName.data()); if ((cd=getClass(fullName))) { // add link to the result if (external ? cd->isLinkable() : cd->isLinkableInProject()) { //ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,word); out.writeLink(cd->getReference(),cd->getOutputFileBase(),0,word); found=TRUE; } } if (scopeOffset==0) { scopeOffset=-1; } else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1) { scopeOffset=0; } } while (!found && scopeOffset>=0); //if (!found) printf("Trying to link %s in %s\n",word.data(),scName); if (!found && getDefs(scName,word,0,md,cd,fd,nd,gd) && (md->isTypedef() || md->isEnumerate() || md->isReference() || md->isVariable() ) && (external ? md->isLinkable() : md->isLinkableInProject()) ) { //printf("Found ref\n"); Definition *d=0; if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd; if (d && (external ? d->isLinkable() : d->isLinkableInProject())) { //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(), // md->anchor(),word); out.writeLink(d->getReference(),d->getOutputFileBase(), md->anchor(),word); found=TRUE; } } if (!found) // add word to the result { //ol.docify(word); out.writeString(word); } } else { //ol.docify(word); out.writeString(word); } // set next start point in the string skipIndex=index=newIndex+matchLen; floatingIndex+=matchLen; } // add last part of the string to the result. //ol.docify(txtStr.right(txtStr.length()-skipIndex)); out.writeString(txtStr.right(txtStr.length()-skipIndex));}void writeExample(OutputList &ol,ExampleSDict *ed){ QCString exampleLine=theTranslator->trWriteList(ed->count()); //bool latexEnabled = ol.isEnabled(OutputGenerator::Latex); //bool manEnabled = ol.isEnabled(OutputGenerator::Man); //bool htmlEnabled = ol.isEnabled(OutputGenerator::Html); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes while ((newIndex=marker.match(exampleLine,index,&matchLen))!=-1) { bool ok; parseText(ol,exampleLine.mid(index,newIndex-index)); uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok); Example *e=ed->at(entryIndex); if (ok && e) { ol.pushGeneratorState(); //if (latexEnabled) ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); // link for Html / man ol.writeObjectLink(0,e->file,e->anchor,e->name); ol.popGeneratorState(); ol.pushGeneratorState(); //if (latexEnabled) ol.enable(OutputGenerator::Latex); ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Html); // link for Latex / pdf with anchor because the sources // are not hyperlinked (not possible with a verbatim environment). ol.writeObjectLink(0,e->file,0,e->name); //if (manEnabled) ol.enable(OutputGenerator::Man); //if (htmlEnabled) ol.enable(OutputGenerator::Html); ol.popGeneratorState(); } index=newIndex+matchLen; } parseText(ol,exampleLine.right(exampleLine.length()-index)); ol.writeString(".");}QCString argListToString(ArgumentList *al){ QCString result; if (al==0) return result; Argument *a=al->first(); result+="("; while (a) { if (!a->name.isEmpty() || !a->array.isEmpty()) { result+= a->type+" "+a->name+a->array; } else { result+= a->type; } if (!a->defval.isEmpty()) { result+="="+a->defval; } a = al->next(); if (a) result+=", "; } result+=")"; if (al->constSpecifier) result+=" const"; if (al->volatileSpecifier) result+=" volatile"; return removeRedundantWhiteSpace(result);}QCString tempArgListToString(ArgumentList *al){ QCString result; if (!al || al->count()==0) return result; result="<"; Argument *a=al->first(); while (a) { if (!a->name.isEmpty()) // add template argument name { result+=a->name; } else // extract name from type { int i=a->type.length()-1; while (i>=0 && isId(a->type.at(i))) i--; if (i>0) { result+=a->type.right(a->type.length()-i-1); } } a=al->next(); if (a) result+=", "; } result+=">"; return removeRedundantWhiteSpace(result);}// compute the HTML anchors for a list of membersvoid setAnchors(char id,MemberList *ml,int groupId){ int count=0; MemberListIterator mli(*ml); MemberDef *md; for (;(md=mli.current());++mli) { if (!md->isReference()) { QCString anchor; if (groupId==-1) anchor.sprintf("%c%d",id,count++); else anchor.sprintf("%c%d_%d",id,groupId,count++); //printf("Member %s anchor %s\n",md->name(),anchor.data()); md->setAnchor(anchor); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -