00001 /****************************************************************************** 00002 * 00003 * $Id: index.cpp,v 1.30 1999/03/06 22:15:39 root Exp $ 00004 * 00005 * Copyright (C) 1997-2008 by Dimitri van Heesch. 00006 * 00007 * Permission to use, copy, modify, and distribute this software and its 00008 * documentation under the terms of the GNU General Public License is hereby 00009 * granted. No representations are made about the suitability of this software 00010 * for any purpose. It is provided "as is" without express or implied warranty. 00011 * See the GNU General Public License for more details. 00012 * 00013 * Documents produced by Doxygen are derivative works derived from the 00014 * input used in their production; they are not affected by this license. 00015 * 00016 */ 00017 00018 #include "qtbc.h" 00019 #include <ctype.h> 00020 #include <qregexp.h> 00021 #include <md5.h> 00022 #include <stdio.h> 00023 #include <stdlib.h> 00024 #include <assert.h> 00025 #include "config.h" 00026 #include "definition.h" 00027 #include "doxygen.h" 00028 #include "language.h" 00029 #include "message.h" 00030 #include "outputlist.h" 00031 #include "code.h" 00032 #include "util.h" 00033 #include "groupdef.h" 00034 #include "pagedef.h" 00035 #include "section.h" 00036 #include "htags.h" 00037 #include "parserintf.h" 00038 #include "marshal.h" 00039 #include "debug.h" 00040 00041 #define START_MARKER 0x4445465B // DEF[ 00042 #define END_MARKER 0x4445465D // DEF] 00043 00044 //----------------------------------------------------------------------------------------- 00045 00046 class DefinitionImpl 00047 { 00048 public: 00049 DefinitionImpl(); 00050 ~DefinitionImpl(); 00051 void init(const char *df,int dl, 00052 const char *n); 00053 00054 SectionDict *sectionDict; // dictionary of all sections, not accessible 00055 00056 MemberSDict *sourceRefByDict; 00057 MemberSDict *sourceRefsDict; 00058 QList<ListItemInfo> *xrefListItems; 00059 GroupList *partOfGroups; 00060 00061 DocInfo *details; // not exported 00062 BriefInfo *brief; // not exported 00063 BodyInfo *body; // not exported 00064 QCString docSignatures; 00065 00066 QCString localName; // local (unqualified) name of the definition 00067 // in the future m_name should become m_localName 00068 QCString qualifiedName; 00069 QCString ref; // reference to external documentation 00070 00071 bool hidden; 00072 bool isArtificial; 00073 00074 Definition *outerScope; // not owner 00075 00076 // where the item was found 00077 QCString defFileName; 00078 int defLine; 00079 QCString defFileExt; 00080 }; 00081 00082 DefinitionImpl::DefinitionImpl() 00083 : sectionDict(0), sourceRefByDict(0), sourceRefsDict(0), 00084 xrefListItems(0), partOfGroups(0), 00085 details(0), brief(0), body(0), 00086 outerScope(0) 00087 { 00088 } 00089 00090 DefinitionImpl::~DefinitionImpl() 00091 { 00092 delete sectionDict; 00093 delete sourceRefByDict; 00094 delete sourceRefsDict; 00095 delete partOfGroups; 00096 delete xrefListItems; 00097 delete brief; 00098 delete details; 00099 delete body; 00100 } 00101 00102 void DefinitionImpl::init(const char *df,int dl, 00103 const char *n) 00104 { 00105 defFileName = df; 00106 int lastDot = defFileName.findRev('.'); 00107 if (lastDot!=-1) 00108 { 00109 defFileExt = defFileName.mid(lastDot); 00110 } 00111 defLine = dl; 00112 QCString name = n; 00113 if (name!="<globalScope>") 00114 { 00115 //extractNamespaceName(m_name,m_localName,ns); 00116 localName=stripScope(n); 00117 } 00118 else 00119 { 00120 localName=n; 00121 } 00122 //printf("m_localName=%s\n",m_localName.data()); 00123 00124 brief = 0; 00125 details = 0; 00126 body = 0; 00127 sourceRefByDict=0; 00128 sourceRefsDict=0; 00129 sectionDict=0, 00130 outerScope=Doxygen::globalScope; 00131 partOfGroups=0; 00132 xrefListItems=0; 00133 hidden = FALSE; 00134 isArtificial = FALSE; 00135 } 00136 00137 //----------------------------------------------------------------------------------------- 00138 00139 static bool matchExcludedSymbols(const char *name) 00140 { 00141 static QStrList &exclSyms = Config_getList("EXCLUDE_SYMBOLS"); 00142 if (exclSyms.count()==0) return FALSE; // nothing specified 00143 const char *pat = exclSyms.first(); 00144 QCString symName = name; 00145 while (pat) 00146 { 00147 QCString pattern = pat; 00148 bool forceStart=FALSE; 00149 bool forceEnd=FALSE; 00150 if (pattern.at(0)=='^') 00151 pattern=pattern.mid(1),forceStart=TRUE; 00152 if (pattern.at(pattern.length()-1)=='$') 00153 pattern=pattern.left(pattern.length()-1),forceEnd=TRUE; 00154 if (pattern.find('*')!=-1) // wildcard mode 00155 { 00156 QRegExp re(substitute(pattern,"*",".*"),TRUE); 00157 int i,pl; 00158 i = re.match(symName,0,&pl); 00159 //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data()); 00160 if (i!=-1) // wildcard match 00161 { 00162 int sl=symName.length(); 00163 // check if it is a whole word match 00164 if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) && 00165 (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd)) 00166 ) 00167 { 00168 //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); 00169 return TRUE; 00170 } 00171 } 00172 } 00173 else if (!pattern.isEmpty()) // match words 00174 { 00175 int i = symName.find(pattern); 00176 if (i!=-1) // we have a match! 00177 { 00178 int pl=pattern.length(); 00179 int sl=symName.length(); 00180 // check if it is a whole word match 00181 if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) && 00182 (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd)) 00183 ) 00184 { 00185 //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); 00186 return TRUE; 00187 } 00188 } 00189 } 00190 pat = exclSyms.next(); 00191 } 00192 //printf("--> name=%s: no match\n",name); 00193 return FALSE; 00194 } 00195 00196 void Definition::addToMap(const char *name,Definition *d) 00197 { 00198 QCString symbolName = name; 00199 int index=computeQualifiedIndex(symbolName); 00200 if (index!=-1) symbolName=symbolName.mid(index+2); 00201 if (!symbolName.isEmpty()) 00202 { 00203 //printf("******* adding symbol `%s' (%p)\n",symbolName.data(),d); 00204 DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); 00205 //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di); 00206 if (di==0) // new Symbol 00207 { 00208 //printf(" new symbol!\n"); 00209 Doxygen::symbolMap->insert(symbolName,d); 00210 } 00211 else // existing symbol 00212 { 00213 //printf(" existing symbol: "); 00214 if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols 00215 { 00216 //printf("adding to exiting list\n"); 00217 DefinitionList *dl = (DefinitionList*)di; 00218 dl->append(d); 00219 } 00220 else // going from one to two symbols 00221 { 00222 Doxygen::symbolMap->take(symbolName); 00223 DefinitionList *dl = new DefinitionList; 00224 //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d); 00225 dl->append((Definition*)di); 00226 dl->append(d); 00227 Doxygen::symbolMap->insert(symbolName,dl); 00228 } 00229 } 00230 00231 // auto resize if needed 00232 static int sizeIndex=9; 00233 if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex]) 00234 { 00235 Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]); 00236 } 00237 00238 d->_setSymbolName(symbolName); 00239 } 00240 } 00241 00242 void Definition::removeFromMap(Definition *d) 00243 { 00244 QCString symbolName = d->symbolName(); 00245 int index=computeQualifiedIndex(symbolName); 00246 if (index!=-1) symbolName=symbolName.mid(index+2); 00247 if (!symbolName.isEmpty()) 00248 { 00249 //printf("******* removing symbol `%s' (%p)\n",symbolName.data(),d); 00250 DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); 00251 if (di) 00252 { 00253 ASSERT(di!=0); 00254 if (di!=d) // symbolName not unique 00255 { 00256 //printf(" removing from list: %p!\n",di); 00257 DefinitionList *dl = (DefinitionList*)di; 00258 bool b = dl->removeRef(d); 00259 ASSERT(b==TRUE); 00260 if (dl->isEmpty()) 00261 { 00262 Doxygen::symbolMap->take(symbolName); 00263 } 00264 } 00265 else // symbolName unique 00266 { 00267 //printf(" removing symbol %p\n",di); 00268 Doxygen::symbolMap->take(symbolName); 00269 } 00270 } 00271 } 00272 } 00273 00274 Definition::Definition(const char *df,int dl, 00275 const char *name,const char *b, 00276 const char *d,bool isSymbol) 00277 { 00278 m_name = name; 00279 m_impl = new DefinitionImpl; 00280 m_impl->init(df,dl,name); 00281 m_isSymbol = isSymbol; 00282 if (isSymbol) addToMap(name,this); 00283 _setBriefDescription(b,df,dl); 00284 _setDocumentation(d,df,dl,TRUE,FALSE); 00285 if (matchExcludedSymbols(name)) 00286 { 00287 m_impl->hidden = TRUE; 00288 } 00289 } 00290 00291 Definition::~Definition() 00292 { 00293 if (m_isSymbol) 00294 { 00295 removeFromMap(this); 00296 } 00297 if (m_impl) 00298 { 00299 delete m_impl; 00300 m_impl=0; 00301 } 00302 } 00303 00304 void Definition::setName(const char *name) 00305 { 00306 if (name==0) return; 00307 m_name = name; 00308 #if 0 00309 makeResident(); 00310 if (m_isSymbol) 00311 { 00312 removeFromMap(this); 00313 } 00314 if (m_name!="<globalScope>") 00315 { 00316 //extractNamespaceName(m_name,m_localName,ns); 00317 m_impl->localName=stripScope(m_name); 00318 } 00319 else 00320 { 00321 m_impl->localName=m_name; 00322 } 00323 if (m_isSymbol) 00324 { 00325 addToMap(m_name,this); 00326 } 00327 #endif 00328 } 00329 00330 void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) 00331 { 00332 if (!anchorList) return; 00333 makeResident(); 00334 //printf("%s: addSectionsToDefinition(%d)\n",name().data(),anchorList->count()); 00335 SectionInfo *si=anchorList->first(); 00336 while (si) 00337 { 00338 //printf("Add section `%s' to definition `%s'\n", 00339 // si->label.data(),name().data()); 00340 SectionInfo *gsi=Doxygen::sectionDict.find(si->label); 00341 if (gsi==0) 00342 { 00343 gsi = new SectionInfo(*si); 00344 Doxygen::sectionDict.insert(si->label,gsi); 00345 } 00346 if (m_impl->sectionDict==0) 00347 { 00348 m_impl->sectionDict = new SectionDict(17); 00349 } 00350 if (m_impl->sectionDict->find(gsi->label)==0) 00351 { 00352 m_impl->sectionDict->insert(gsi->label,gsi); 00353 gsi->definition = this; 00354 } 00355 si=anchorList->next(); 00356 } 00357 } 00358 00359 void Definition::writeDocAnchorsToTagFile() 00360 { 00361 makeResident(); 00362 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict) 00363 { 00364 //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_sectionDict->count()); 00365 QDictIterator<SectionInfo> sdi(*m_impl->sectionDict); 00366 SectionInfo *si; 00367 for (;(si=sdi.current());++sdi) 00368 { 00369 if (!si->generated) 00370 { 00371 //printf("write an entry!\n"); 00372 if (definitionType()==TypeMember) Doxygen::tagFile << " "; 00373 Doxygen::tagFile << " <docanchor file=\"" 00374 << si->fileName << "\">" << si->label 00375 << "</docanchor>" << endl; 00376 } 00377 } 00378 } 00379 } 00380 00381 bool Definition::_docsAlreadyAdded(const QString &doc) 00382 { 00383 uchar md5_sig[16]; 00384 QCString sigStr(33); 00385 MD5Buffer((const unsigned char *)doc.data(),doc.length(),md5_sig); 00386 MD5SigToString(md5_sig,sigStr.data(),33); 00387 if (m_impl->docSignatures.find(sigStr)==-1) // new docs, add signature to prevent re-adding it 00388 { 00389 m_impl->docSignatures+=":"+sigStr; 00390 return FALSE; 00391 } 00392 else 00393 { 00394 return TRUE; 00395 } 00396 } 00397 00398 void Definition::_setDocumentation(const char *d,const char *docFile,int docLine, 00399 bool stripWhiteSpace,bool atTop) 00400 { 00401 if (d==0) return; 00402 //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace); 00403 QCString doc = d; 00404 if (stripWhiteSpace) 00405 { 00406 doc = stripLeadingAndTrailingEmptyLines(doc); 00407 } 00408 else // don't strip whitespace 00409 { 00410 doc=d; 00411 } 00412 if (!_docsAlreadyAdded(doc)) 00413 { 00414 //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); 00415 if (m_impl->details==0) 00416 { 00417 m_impl->details = new DocInfo; 00418 } 00419 if (m_impl->details->doc.isEmpty()) // fresh detailed description 00420 { 00421 m_impl->details->doc = doc; 00422 } 00423 else if (atTop) // another detailed description, append it to the start 00424 { 00425 m_impl->details->doc = doc+"\n\n"+m_impl->details->doc; 00426 } 00427 else // another detailed description, append it to the end 00428 { 00429 m_impl->details->doc += "\n\n"+doc; 00430 } 00431 if (docLine!=-1) // store location if valid 00432 { 00433 m_impl->details->file = docFile; 00434 m_impl->details->line = docLine; 00435 } 00436 } 00437 } 00438 00439 void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) 00440 { 00441 if (d==0) return; 00442 makeResident(); 00443 _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE); 00444 } 00445 00446 #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase) 00447 00448 void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine) 00449 { 00450 static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE"); 00451 static bool needsDot = outputLanguage!="Japanese" && 00452 outputLanguage!="Chinese" && 00453 outputLanguage!="Korean"; 00454 QCString brief = b; 00455 brief = brief.stripWhiteSpace(); 00456 if (brief.isEmpty()) return; 00457 int bl = brief.length(); 00458 if (bl>0 && needsDot) // add punctuation if needed 00459 { 00460 switch(brief.at(bl-1)) 00461 { 00462 case '.': case '!': case '?': break; 00463 default: 00464 if (uni_isupper(brief.at(0))) brief+='.'; 00465 break; 00466 } 00467 } 00468 00469 if (m_impl->brief && !m_impl->brief->doc.isEmpty()) 00470 { 00471 //printf("adding to details\n"); 00472 _setDocumentation(brief,briefFile,briefLine,FALSE,TRUE); 00473 } 00474 else if (!_docsAlreadyAdded(brief)) 00475 { 00476 //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); 00477 if (m_impl->brief==0) 00478 { 00479 m_impl->brief = new BriefInfo; 00480 } 00481 m_impl->brief->doc=brief; 00482 if (briefLine!=-1) 00483 { 00484 m_impl->brief->file = briefFile; 00485 m_impl->brief->line = briefLine; 00486 } 00487 } 00488 } 00489 00490 void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) 00491 { 00492 if (b==0) return; 00493 makeResident(); 00494 _setBriefDescription(b,briefFile,briefLine); 00495 } 00496 00508 static bool readCodeFragment(const char *fileName, 00509 int &startLine,int &endLine,QCString &result) 00510 { 00511 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); 00512 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES"); 00513 //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine); 00514 if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name 00515 QCString filter = getFileFilter(fileName); 00516 FILE *f=0; 00517 bool usePipe = !filter.isEmpty() && filterSourceFiles; 00518 if (!usePipe) // no filter given or wanted 00519 { 00520 f = fopen(fileName,"r"); 00521 } 00522 else // use filter 00523 { 00524 QCString cmd=filter+" \""+fileName+"\""; 00525 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data()); 00526 f = portable_popen(cmd,"r"); 00527 } 00528 bool found=vhdlOpt; // for VHDL no bracket search is possible 00529 if (f) 00530 { 00531 int c=0; 00532 int col=0; 00533 int lineNr=1; 00534 // skip until the startLine has reached 00535 while (lineNr<startLine && !feof(f)) 00536 { 00537 while ((c=fgetc(f))!='\n' && c!=EOF) /* skip */; 00538 lineNr++; 00539 } 00540 if (!feof(f)) 00541 { 00542 // skip until the opening bracket or lonely : is found 00543 char cn=0; 00544 while (lineNr<=endLine && !feof(f) && !found) 00545 { 00546 while ((c=fgetc(f))!='{' && c!=':' && c!=EOF) 00547 { 00548 //printf("parsing char `%c'\n",c); 00549 if (c=='\n') 00550 { 00551 lineNr++,col=0; 00552 } 00553 else if (c=='\t') 00554 { 00555 col+=Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE")); 00556 } 00557 else 00558 { 00559 col++; 00560 } 00561 } 00562 if (c==':') 00563 { 00564 cn=fgetc(f); 00565 if (cn!=':') found=TRUE; 00566 } 00567 else if (c=='{') 00568 { 00569 found=TRUE; 00570 } 00571 } 00572 //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr); 00573 if (found) 00574 { 00575 // For code with more than one line, 00576 // fill the line with spaces until we are at the right column 00577 // so that the opening brace lines up with the closing brace 00578 if (endLine!=startLine) 00579 { 00580 QCString spaces; 00581 spaces.fill(' ',col); 00582 result+=spaces; 00583 } 00584 // copy until end of line 00585 result+=c; 00586 if (c==':') result+=cn; 00587 startLine=lineNr; 00588 const int maxLineLength=4096; 00589 char lineStr[maxLineLength]; 00590 do 00591 { 00592 //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine); 00593 int size_read; 00594 do 00595 { 00596 // read up to maxLineLength-1 bytes, the last byte being zero 00597 char *p = fgets(lineStr, maxLineLength,f); 00598 //printf(" read %s",p); 00599 if (p) 00600 { 00601 size_read=qstrlen(p); 00602 } 00603 else 00604 { 00605 size_read=-1; 00606 } 00607 result+=lineStr; 00608 } while (size_read == (maxLineLength-1)); 00609 00610 lineNr++; 00611 } while (lineNr<=endLine && !feof(f)); 00612 00613 // strip stuff after closing bracket 00614 int newLineIndex = result.findRev('\n'); 00615 int braceIndex = result.findRev('}'); 00616 if (braceIndex > newLineIndex) 00617 { 00618 result.truncate(braceIndex+1); 00619 } 00620 endLine=lineNr-1; 00621 } 00622 } 00623 if (usePipe) 00624 { 00625 portable_pclose(f); 00626 } 00627 else 00628 { 00629 fclose(f); 00630 } 00631 } 00632 result = transcodeCharacterStringToUTF8(result); 00633 return found; 00634 } 00635 00637 void Definition::writeSourceDef(OutputList &ol,const char *) 00638 { 00639 makeResident(); 00640 ol.pushGeneratorState(); 00641 //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef); 00642 if (Config_getBool("SOURCE_BROWSER") && 00643 m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->fileDef) 00644 { 00645 QCString refText = theTranslator->trDefinedAtLineInSourceFile(); 00646 int lineMarkerPos = refText.find("@0"); 00647 int fileMarkerPos = refText.find("@1"); 00648 if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this. 00649 { 00650 QCString lineStr,anchorStr; 00651 lineStr.sprintf("%d",m_impl->body->startLine); 00652 anchorStr.sprintf(Htags::useHtags ? "L%d" : "l%05d",m_impl->body->startLine); 00653 ol.startParagraph(); 00654 if (lineMarkerPos<fileMarkerPos) // line marker before file marker 00655 { 00656 // write text left from linePos marker 00657 ol.parseText(refText.left(lineMarkerPos)); 00658 ol.disableAllBut(OutputGenerator::Html); 00659 // write line link (HTML only) 00660 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(), 00661 anchorStr,lineStr); 00662 ol.enableAll(); 00663 ol.disable(OutputGenerator::Html); 00664 // write normal text (Latex/Man only) 00665 ol.docify(lineStr); 00666 ol.enableAll(); 00667 00668 // write text between markers 00669 ol.parseText(refText.mid(lineMarkerPos+2, 00670 fileMarkerPos-lineMarkerPos-2)); 00671 00672 ol.disableAllBut(OutputGenerator::Html); 00673 // write file link (HTML only) 00674 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(), 00675 0,m_impl->body->fileDef->name()); 00676 ol.enableAll(); 00677 ol.disable(OutputGenerator::Html); 00678 // write normal text (Latex/Man only) 00679 ol.docify(m_impl->body->fileDef->name()); 00680 ol.enableAll(); 00681 00682 // write text right from file marker 00683 ol.parseText(refText.right( 00684 refText.length()-fileMarkerPos-2)); 00685 } 00686 else // file marker before line marker 00687 { 00688 // write text left from file marker 00689 ol.parseText(refText.left(fileMarkerPos)); 00690 ol.disableAllBut(OutputGenerator::Html); 00691 // write file link (HTML only) 00692 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(), 00693 0,m_impl->body->fileDef->name()); 00694 ol.enableAll(); 00695 ol.disable(OutputGenerator::Html); 00696 // write normal text (Latex/Man only) 00697 ol.docify(m_impl->body->fileDef->name()); 00698 ol.enableAll(); 00699 00700 // write text between markers 00701 ol.parseText(refText.mid(fileMarkerPos+2, 00702 lineMarkerPos-fileMarkerPos-2)); 00703 00704 ol.disableAllBut(OutputGenerator::Html); 00705 // write line link (HTML only) 00706 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(), 00707 anchorStr,lineStr); 00708 ol.enableAll(); 00709 ol.disable(OutputGenerator::Html); 00710 // write normal text (Latex/Man only) 00711 ol.docify(lineStr); 00712 ol.enableAll(); 00713 00714 // write text right from linePos marker 00715 ol.parseText(refText.right( 00716 refText.length()-lineMarkerPos-2)); 00717 } 00718 ol.endParagraph(); 00719 } 00720 else 00721 { 00722 err("Error: translation error: invalid markers in trDefinedInSourceFile()\n"); 00723 } 00724 } 00725 ol.popGeneratorState(); 00726 } 00727 00728 void Definition::setBodySegment(int bls,int ble) 00729 { 00730 makeResident(); 00731 //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data()); 00732 if (m_impl->body==0) m_impl->body = new BodyInfo; 00733 m_impl->body->startLine=bls; 00734 m_impl->body->endLine=ble; 00735 } 00736 00737 void Definition::setBodyDef(FileDef *fd) 00738 { 00739 makeResident(); 00740 if (m_impl->body==0) m_impl->body = new BodyInfo; 00741 m_impl->body->fileDef=fd; 00742 } 00743 00745 void Definition::writeInlineCode(OutputList &ol,const char *scopeName) 00746 { 00747 makeResident(); 00748 ol.pushGeneratorState(); 00749 //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(), 00750 // m_startBodyLine,m_endBodyLine,m_bodyDef); 00751 if (Config_getBool("INLINE_SOURCES") && 00752 m_impl->body && m_impl->body->startLine!=-1 && 00753 m_impl->body->endLine>=m_impl->body->startLine && m_impl->body->fileDef) 00754 { 00755 QCString codeFragment; 00756 int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine; 00757 if (readCodeFragment(m_impl->body->fileDef->absFilePath(), 00758 actualStart,actualEnd,codeFragment) 00759 ) 00760 { 00761 //printf("Adding code fragement '%s' ext='%s'\n", 00762 // codeFragment.data(),m_impl->defFileExt.data()); 00763 ParserInterface *pIntf = Doxygen::parserManager->getParser(m_impl->defFileExt); 00764 pIntf->resetCodeParserState(); 00765 //printf("Read:\n`%s'\n\n",codeFragment.data()); 00766 MemberDef *thisMd = 0; 00767 if (definitionType()==TypeMember) thisMd = (MemberDef *)this; 00768 ol.startCodeFragment(); 00769 pIntf->parseCode(ol, // codeOutIntf 00770 scopeName, // scope 00771 codeFragment, // input 00772 FALSE, // isExample 00773 0, // exampleName 00774 m_impl->body->fileDef, // fileDef 00775 actualStart, // startLine 00776 actualEnd, // endLine 00777 TRUE, // inlineFragment 00778 thisMd // memberDef 00779 ); 00780 ol.endCodeFragment(); 00781 ol.newParagraph(); 00782 } 00783 } 00784 ol.popGeneratorState(); 00785 } 00786 00790 void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, 00791 const QCString &text,MemberSDict *members,bool /*funcOnly*/) 00792 { 00793 ol.pushGeneratorState(); 00794 if (/*Config_getBool("SOURCE_BROWSER") &&*/ members) 00795 { 00796 ol.startParagraph(); 00797 ol.parseText(text); 00798 ol.docify(" "); 00799 00800 QCString ldefLine=theTranslator->trWriteList(members->count()); 00801 00802 QRegExp marker("@[0-9]+"); 00803 int index=0,newIndex,matchLen; 00804 // now replace all markers in inheritLine with links to the classes 00805 while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1) 00806 { 00807 bool ok; 00808 ol.parseText(ldefLine.mid(index,newIndex-index)); 00809 uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); 00810 MemberDef *md=members->at(entryIndex); 00811 if (ok && md) 00812 { 00813 QCString scope=md->getScopeString(); 00814 QCString name=md->name(); 00815 //printf("class=%p scope=%s scopeName=%s\n",md->getClassDef(),scope.data(),scopeName); 00816 if (!scope.isEmpty() && scope!=scopeName) 00817 { 00818 if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) 00819 { 00820 name.prepend(scope+"."); 00821 } 00822 else 00823 { 00824 name.prepend(scope+"::"); 00825 } 00826 } 00827 if (!md->isObjCMethod() && 00828 (md->isFunction() || md->isSlot() || 00829 md->isPrototype() || md->isSignal() 00830 ) 00831 ) name+="()"; 00832 //Definition *d = md->getOutputFileBase(); 00833 //if (d==Doxygen::globalScope) d=md->getBodyDef(); 00834 if (!(md->isLinkable() && !Config_getBool("REFERENCES_LINK_SOURCE")) && md->getStartBodyLine()!=-1 && md->getBodyDef()) 00835 { 00836 //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope); 00837 // for HTML write a real link 00838 ol.pushGeneratorState(); 00839 ol.disableAllBut(OutputGenerator::Html); 00840 QCString lineStr,anchorStr; 00841 anchorStr.sprintf("l%05d",md->getStartBodyLine()); 00842 //printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data()); 00843 ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name); 00844 ol.popGeneratorState(); 00845 00846 // for the other output formats just mention the name 00847 ol.pushGeneratorState(); 00848 ol.disable(OutputGenerator::Html); 00849 ol.docify(name); 00850 ol.popGeneratorState(); 00851 } 00852 else if (md->isLinkable() /*&& d && d->isLinkable()*/) 00853 { 00854 // for HTML write a real link 00855 ol.pushGeneratorState(); 00856 ol.disableAllBut(OutputGenerator::Html); 00857 ol.writeObjectLink(md->getReference(), 00858 md->getOutputFileBase(), 00859 md->anchor(),name); 00860 ol.popGeneratorState(); 00861 00862 // for the other output formats just mention the name 00863 ol.pushGeneratorState(); 00864 ol.disable(OutputGenerator::Html); 00865 ol.docify(name); 00866 ol.popGeneratorState(); 00867 } 00868 else 00869 { 00870 ol.docify(name); 00871 } 00872 } 00873 index=newIndex+matchLen; 00874 } 00875 ol.parseText(ldefLine.right(ldefLine.length()-index)); 00876 ol.writeString("."); 00877 ol.endParagraph(); 00878 } 00879 ol.popGeneratorState(); 00880 } 00881 00882 void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName) 00883 { 00884 makeResident(); 00885 if (Config_getBool("REFERENCED_BY_RELATION")) 00886 { 00887 _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE); 00888 } 00889 } 00890 00891 void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) 00892 { 00893 makeResident(); 00894 if (Config_getBool("REFERENCES_RELATION")) 00895 { 00896 _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE); 00897 } 00898 } 00899 00900 bool Definition::hasDocumentation() const 00901 { 00902 static bool extractAll = Config_getBool("EXTRACT_ALL"); 00903 //static bool sourceBrowser = Config_getBool("SOURCE_BROWSER"); 00904 makeResident(); 00905 bool hasDocs = 00906 (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs 00907 (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description 00908 extractAll //|| // extract everything 00909 // (sourceBrowser && m_impl->body && 00910 // m_impl->body->startLine!=-1 && m_impl->body->fileDef) 00911 ; // link to definition 00912 return hasDocs; 00913 } 00914 00915 bool Definition::hasUserDocumentation() const 00916 { 00917 makeResident(); 00918 bool hasDocs = 00919 (m_impl->details && !m_impl->details->doc.isEmpty()) || 00920 (m_impl->brief && !m_impl->brief->doc.isEmpty()); 00921 return hasDocs; 00922 } 00923 00924 void Definition::addSourceReferencedBy(MemberDef *md) 00925 { 00926 if (md) 00927 { 00928 makeResident(); 00929 QCString name = md->name(); 00930 QCString scope = md->getScopeString(); 00931 00932 if (!scope.isEmpty()) 00933 { 00934 name.prepend(scope+"::"); 00935 } 00936 00937 if (m_impl->sourceRefByDict==0) 00938 { 00939 m_impl->sourceRefByDict = new MemberSDict; 00940 } 00941 if (m_impl->sourceRefByDict->find(name)==0) 00942 { 00943 m_impl->sourceRefByDict->inSort(name,md); 00944 } 00945 } 00946 } 00947 00948 void Definition::addSourceReferences(MemberDef *md) 00949 { 00950 if (md) 00951 { 00952 QCString name = md->name(); 00953 QCString scope = md->getScopeString(); 00954 makeResident(); 00955 00956 if (!scope.isEmpty()) 00957 { 00958 name.prepend(scope+"::"); 00959 } 00960 00961 if (m_impl->sourceRefsDict==0) 00962 { 00963 m_impl->sourceRefsDict = new MemberSDict; 00964 } 00965 if (m_impl->sourceRefsDict->find(name)==0) 00966 { 00967 m_impl->sourceRefsDict->inSort(name,md); 00968 } 00969 } 00970 } 00971 00972 Definition *Definition::findInnerCompound(const char *) 00973 { 00974 return 0; 00975 } 00976 00977 void Definition::addInnerCompound(Definition *) 00978 { 00979 err("Error: Definition::addInnerCompound() called\n"); 00980 } 00981 00982 QCString Definition::qualifiedName() const 00983 { 00984 static int count=0; 00985 count++; 00986 makeResident(); 00987 if (!m_impl->qualifiedName.isEmpty()) 00988 { 00989 count--; 00990 return m_impl->qualifiedName; 00991 } 00992 #if 0 00993 if (count>20) 00994 { 00995 printf("Definition::qualifiedName() Infinite recursion detected! Type=%d\n",definitionType()); 00996 printf("Trace:\n"); 00997 Definition *d = (Definition *)this; 00998 for (int i=0;d && i<20;i++) 00999 { 01000 printf(" %s\n",d->name().data()); 01001 d = d->getOuterScope(); 01002 } 01003 } 01004 #endif 01005 01006 //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data()); 01007 if (m_impl->outerScope==0) 01008 { 01009 if (m_impl->localName=="<globalScope>") 01010 { 01011 count--; 01012 return ""; 01013 } 01014 else 01015 { 01016 count--; 01017 return m_impl->localName; 01018 } 01019 } 01020 01021 if (m_impl->outerScope->name()=="<globalScope>") 01022 { 01023 m_impl->qualifiedName = m_impl->localName.copy(); 01024 } 01025 else 01026 { 01027 m_impl->qualifiedName = m_impl->outerScope->qualifiedName()+"::"+m_impl->localName; 01028 } 01029 //printf("end %s::qualifiedName()=%s\n",name().data(),m_impl->qualifiedName.data()); 01030 count--; 01031 return m_impl->qualifiedName; 01032 }; 01033 01034 void Definition::setOuterScope(Definition *d) 01035 { 01036 makeResident(); 01037 if (m_impl->outerScope!=d) 01038 { 01039 m_impl->qualifiedName.resize(0); // flush cached scope name 01040 m_impl->outerScope = d; 01041 } 01042 m_impl->hidden = m_impl->hidden || d->isHidden(); 01043 } 01044 01045 QCString Definition::localName() const 01046 { 01047 makeResident(); 01048 return m_impl->localName; 01049 } 01050 01051 void Definition::makePartOfGroup(GroupDef *gd) 01052 { 01053 makeResident(); 01054 if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList; 01055 m_impl->partOfGroups->append(gd); 01056 } 01057 01058 void Definition::setRefItems(const QList<ListItemInfo> *sli) 01059 { 01060 if (sli) 01061 { 01062 makeResident(); 01063 // deep copy the list 01064 if (m_impl->xrefListItems==0) 01065 { 01066 m_impl->xrefListItems=new QList<ListItemInfo>; 01067 m_impl->xrefListItems->setAutoDelete(TRUE); 01068 } 01069 QListIterator<ListItemInfo> slii(*sli); 01070 ListItemInfo *lii; 01071 for (slii.toFirst();(lii=slii.current());++slii) 01072 { 01073 m_impl->xrefListItems->append(new ListItemInfo(*lii)); 01074 } 01075 } 01076 } 01077 01078 void Definition::mergeRefItems(Definition *d) 01079 { 01080 LockingPtr< QList<ListItemInfo> > xrefList = d->xrefListItems(); 01081 if (xrefList!=0) 01082 { 01083 makeResident(); 01084 // deep copy the list 01085 if (m_impl->xrefListItems==0) 01086 { 01087 m_impl->xrefListItems=new QList<ListItemInfo>; 01088 m_impl->xrefListItems->setAutoDelete(TRUE); 01089 } 01090 QListIterator<ListItemInfo> slii(*xrefList); 01091 ListItemInfo *lii; 01092 for (slii.toFirst();(lii=slii.current());++slii) 01093 { 01094 if (_getXRefListId(lii->type)==-1) 01095 { 01096 m_impl->xrefListItems->append(new ListItemInfo(*lii)); 01097 } 01098 } 01099 } 01100 } 01101 01102 int Definition::_getXRefListId(const char *listName) const 01103 { 01104 makeResident(); 01105 if (m_impl->xrefListItems) 01106 { 01107 QListIterator<ListItemInfo> slii(*m_impl->xrefListItems); 01108 ListItemInfo *lii; 01109 for (slii.toFirst();(lii=slii.current());++slii) 01110 { 01111 if (strcmp(lii->type,listName)==0) 01112 { 01113 return lii->itemId; 01114 } 01115 } 01116 } 01117 return -1; 01118 } 01119 01120 LockingPtr< QList<ListItemInfo> > Definition::xrefListItems() const 01121 { 01122 makeResident(); 01123 return LockingPtr< QList<ListItemInfo> >(this,m_impl->xrefListItems); 01124 } 01125 01126 01127 QCString Definition::convertNameToFile(const char *name,bool allowDots) const 01128 { 01129 makeResident(); 01130 if (!m_impl->ref.isEmpty()) 01131 { 01132 return name; 01133 } 01134 else 01135 { 01136 return ::convertNameToFile(name,allowDots); 01137 } 01138 } 01139 01140 void Definition::writePathFragment(OutputList &ol) const 01141 { 01142 makeResident(); 01143 if (m_impl->outerScope && m_impl->outerScope!=Doxygen::globalScope) 01144 { 01145 m_impl->outerScope->writePathFragment(ol); 01146 if (m_impl->outerScope->definitionType()==Definition::TypeClass || 01147 m_impl->outerScope->definitionType()==Definition::TypeNamespace) 01148 { 01149 if (Config_getBool("OPTIMIZE_OUTPUT_JAVA") || 01150 Config_getBool("OPTIMIZE_OUTPUT_VHDL") 01151 ) 01152 { 01153 ol.writeString("."); 01154 } 01155 else 01156 { 01157 ol.writeString("::"); 01158 } 01159 } 01160 else 01161 { 01162 ol.writeString(" "); 01163 ol.writeString("»"); 01164 ol.writeString(" "); 01165 } 01166 } 01167 if (isLinkable()) 01168 { 01169 if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle()) 01170 { 01171 ol.writeObjectLink(getReference(),getOutputFileBase(),0,((const GroupDef*)this)->groupTitle()); 01172 } 01173 else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty()) 01174 { 01175 ol.writeObjectLink(getReference(),getOutputFileBase(),0,((const PageDef*)this)->title()); 01176 } 01177 else 01178 { 01179 ol.writeObjectLink(getReference(),getOutputFileBase(),0,m_impl->localName); 01180 } 01181 } 01182 else 01183 { 01184 ol.startBold(); 01185 ol.docify(m_impl->localName); 01186 ol.endBold(); 01187 } 01188 } 01189 01190 void Definition::writeNavigationPath(OutputList &ol) const 01191 { 01192 ol.pushGeneratorState(); 01193 ol.disableAllBut(OutputGenerator::Html); 01194 01195 ol.writeString(" <div class=\"navpath\">"); 01196 writePathFragment(ol); 01197 ol.writeString("\n </div>\n"); 01198 01199 ol.popGeneratorState(); 01200 } 01201 01202 QCString Definition::symbolName() const 01203 { 01204 return m_symbolName; 01205 } 01206 01207 QCString Definition::documentation() const 01208 { 01209 makeResident(); 01210 return m_impl->details ? m_impl->details->doc : QCString(""); 01211 } 01212 01213 int Definition::docLine() const 01214 { 01215 makeResident(); 01216 return m_impl->details ? m_impl->details->line : 1; 01217 } 01218 01219 QCString Definition::docFile() const 01220 { 01221 makeResident(); 01222 return m_impl->details ? m_impl->details->file : QCString("<"+m_name+">"); 01223 } 01224 01225 QCString Definition::briefDescription() const 01226 { 01227 makeResident(); 01228 return m_impl->brief ? m_impl->brief->doc : QCString(""); 01229 } 01230 01231 QCString Definition::briefDescriptionAsTooltip() const 01232 { 01233 makeResident(); 01234 if (m_impl->brief) 01235 { 01236 if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) 01237 { 01238 static bool reentering=FALSE; 01239 if (!reentering) 01240 { 01241 reentering=TRUE; // prevent requests for tooltips while parsing a tooltip 01242 m_impl->brief->tooltip = parseCommentAsText( 01243 m_impl->brief->doc, 01244 m_impl->brief->file, 01245 m_impl->brief->line); 01246 reentering=FALSE; 01247 } 01248 } 01249 return m_impl->brief->tooltip; 01250 } 01251 return QCString(""); 01252 } 01253 01254 int Definition::briefLine() const 01255 { 01256 makeResident(); 01257 return m_impl->brief ? m_impl->brief->line : 1; 01258 } 01259 01260 QCString Definition::briefFile() const 01261 { 01262 makeResident(); 01263 return m_impl->brief ? m_impl->brief->file : QCString("<"+m_name+">"); 01264 } 01265 01266 QCString Definition::getDefFileName() const 01267 { 01268 makeResident(); 01269 return m_impl->defFileName; 01270 } 01271 01272 QCString Definition::getDefFileExtension() const 01273 { 01274 makeResident(); 01275 return m_impl->defFileExt; 01276 } 01277 01278 int Definition::getDefLine() const 01279 { 01280 makeResident(); 01281 return m_impl->defLine; 01282 } 01283 01284 bool Definition::isHidden() const 01285 { 01286 makeResident(); 01287 return m_impl->hidden; 01288 } 01289 01290 bool Definition::isVisibleInProject() const 01291 { 01292 return isLinkableInProject() && !m_impl->hidden; 01293 } 01294 01295 bool Definition::isVisible() const 01296 { 01297 return isLinkable() && !m_impl->hidden; 01298 } 01299 01300 bool Definition::isArtificial() const 01301 { 01302 return m_impl->isArtificial; 01303 } 01304 01305 QCString Definition::getReference() const 01306 { 01307 makeResident(); 01308 return m_impl->ref; 01309 } 01310 01311 bool Definition::isReference() const 01312 { 01313 makeResident(); 01314 return !m_impl->ref.isEmpty(); 01315 } 01316 01317 int Definition::getStartBodyLine() const 01318 { 01319 makeResident(); 01320 return m_impl->body ? m_impl->body->startLine : -1; 01321 } 01322 01323 int Definition::getEndBodyLine() const 01324 { 01325 makeResident(); 01326 return m_impl->body ? m_impl->body->endLine : -1; 01327 } 01328 01329 FileDef *Definition::getBodyDef() 01330 { 01331 makeResident(); 01332 return m_impl->body ? m_impl->body->fileDef : 0; 01333 } 01334 01335 LockingPtr<GroupList> Definition::partOfGroups() const 01336 { 01337 makeResident(); 01338 return LockingPtr<GroupList>(this,m_impl->partOfGroups); 01339 } 01340 01341 Definition *Definition::getOuterScope() const 01342 { 01343 makeResident(); 01344 return m_impl->outerScope; 01345 } 01346 01347 LockingPtr<MemberSDict> Definition::getReferencesMembers() const 01348 { 01349 makeResident(); 01350 return LockingPtr<MemberSDict>(this,m_impl->sourceRefsDict); 01351 } 01352 01353 LockingPtr<MemberSDict> Definition::getReferencedByMembers() const 01354 { 01355 makeResident(); 01356 return LockingPtr<MemberSDict>(this,m_impl->sourceRefByDict); 01357 } 01358 01359 void Definition::setReference(const char *r) 01360 { 01361 makeResident(); 01362 m_impl->ref=r; 01363 } 01364 01365 void Definition::_setSymbolName(const QCString &name) 01366 { 01367 m_symbolName=name; 01368 } 01369 01370 void Definition::setHidden(bool b) 01371 { 01372 makeResident(); 01373 m_impl->hidden = m_impl->hidden || b; 01374 } 01375 01376 void Definition::setArtificial(bool b) 01377 { 01378 makeResident(); 01379 m_impl->isArtificial = b; 01380 } 01381 01382 void Definition::setLocalName(const QCString name) 01383 { 01384 makeResident(); 01385 m_impl->localName=name; 01386 } 01387 01388 void Definition::makeResident() const 01389 { 01390 } 01391 01392 01393 void Definition::flushToDisk() const 01394 { 01395 //printf("%p: Definition::flushToDisk()\n",this); 01396 Definition *that = (Definition *)this; 01397 //printf("Definition::flushToDisk(): pos=%d\n",(int)m_storagePos); 01398 marshalUInt(Doxygen::symbolStorage,START_MARKER); 01399 marshalSectionDict (Doxygen::symbolStorage,m_impl->sectionDict); 01400 marshalMemberSDict (Doxygen::symbolStorage,m_impl->sourceRefByDict); 01401 marshalMemberSDict (Doxygen::symbolStorage,m_impl->sourceRefsDict); 01402 marshalItemInfoList (Doxygen::symbolStorage,m_impl->xrefListItems); 01403 marshalGroupList (Doxygen::symbolStorage,m_impl->partOfGroups); 01404 marshalDocInfo (Doxygen::symbolStorage,m_impl->details); 01405 marshalBriefInfo (Doxygen::symbolStorage,m_impl->brief); 01406 marshalBodyInfo (Doxygen::symbolStorage,m_impl->body); 01407 marshalQCString (Doxygen::symbolStorage,m_impl->docSignatures); 01408 marshalQCString (Doxygen::symbolStorage,m_impl->localName); 01409 marshalQCString (Doxygen::symbolStorage,m_impl->qualifiedName); 01410 marshalQCString (Doxygen::symbolStorage,m_impl->ref); 01411 marshalBool (Doxygen::symbolStorage,m_impl->hidden); 01412 marshalBool (Doxygen::symbolStorage,m_impl->isArtificial); 01413 marshalObjPointer (Doxygen::symbolStorage,m_impl->outerScope); 01414 marshalQCString (Doxygen::symbolStorage,m_impl->defFileName); 01415 marshalInt (Doxygen::symbolStorage,m_impl->defLine); 01416 marshalQCString (Doxygen::symbolStorage,m_impl->defFileExt); 01417 marshalUInt(Doxygen::symbolStorage,END_MARKER); 01418 delete that->m_impl; 01419 that->m_impl = 0; 01420 } 01421 01422 void Definition::loadFromDisk() const 01423 { 01424 //printf("%p: Definition::loadFromDisk()\n",this); 01425 Definition *that = (Definition *)this; 01426 assert(m_impl==0); 01427 that->m_impl = new DefinitionImpl; 01428 uint marker = unmarshalUInt(Doxygen::symbolStorage); 01429 assert(marker==START_MARKER); 01430 m_impl->sectionDict = unmarshalSectionDict (Doxygen::symbolStorage); 01431 m_impl->sourceRefByDict = unmarshalMemberSDict (Doxygen::symbolStorage); 01432 m_impl->sourceRefsDict = unmarshalMemberSDict (Doxygen::symbolStorage); 01433 m_impl->xrefListItems = unmarshalItemInfoList (Doxygen::symbolStorage); 01434 m_impl->partOfGroups = unmarshalGroupList (Doxygen::symbolStorage); 01435 m_impl->details = unmarshalDocInfo (Doxygen::symbolStorage); 01436 m_impl->brief = unmarshalBriefInfo (Doxygen::symbolStorage); 01437 m_impl->body = unmarshalBodyInfo (Doxygen::symbolStorage); 01438 m_impl->docSignatures = unmarshalQCString (Doxygen::symbolStorage); 01439 m_impl->localName = unmarshalQCString (Doxygen::symbolStorage); 01440 m_impl->qualifiedName = unmarshalQCString (Doxygen::symbolStorage); 01441 m_impl->ref = unmarshalQCString (Doxygen::symbolStorage); 01442 m_impl->hidden = unmarshalBool (Doxygen::symbolStorage); 01443 m_impl->isArtificial = unmarshalBool (Doxygen::symbolStorage); 01444 m_impl->outerScope = (Definition *)unmarshalObjPointer (Doxygen::symbolStorage); 01445 m_impl->defFileName = unmarshalQCString (Doxygen::symbolStorage); 01446 m_impl->defLine = unmarshalInt (Doxygen::symbolStorage); 01447 m_impl->defFileExt = unmarshalQCString (Doxygen::symbolStorage); 01448 marker = unmarshalUInt(Doxygen::symbolStorage); 01449 assert(marker==END_MARKER); 01450 } 01451