Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/src/definition.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
1/******************************************************************************
2 *
3 * $Id: index.cpp,v 1.30 1999/03/06 22:15:39 root Exp $
4 *
5 * Copyright (C) 1997-2011 by Dimitri van Heesch.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
12 *
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
15 *
16 */
17
18#include "qtbc.h"
19#include <ctype.h>
20#include <qregexp.h>
21#include "md5.h"
22#include <stdio.h>
23#include <stdlib.h>
24#include <assert.h>
25#include "config.h"
26#include "definition.h"
27#include "doxygen.h"
28#include "language.h"
29#include "message.h"
30#include "outputlist.h"
31#include "code.h"
32#include "util.h"
33#include "groupdef.h"
34#include "pagedef.h"
35#include "section.h"
36#include "htags.h"
37#include "parserintf.h"
38#include "marshal.h"
39#include "debug.h"
40
41#define START_MARKER 0x4445465B // DEF[
42#define END_MARKER 0x4445465D // DEF]
43
44//-----------------------------------------------------------------------------------------
45
46class DefinitionImpl
47{
48 public:
49 DefinitionImpl();
50 ~DefinitionImpl();
51 void init(const char *df,int dl,
52 const char *n);
53
54 SectionDict *sectionDict; // dictionary of all sections, not accessible
55
56 MemberSDict *sourceRefByDict;
57 MemberSDict *sourceRefsDict;
58 QList<ListItemInfo> *xrefListItems;
59 GroupList *partOfGroups;
60
61 DocInfo *details; // not exported
62 DocInfo *inbodyDocs; // not exported
63 BriefInfo *brief; // not exported
64 BodyInfo *body; // not exported
65 QCString docSignatures;
66
67 QCString localName; // local (unqualified) name of the definition
68 // in the future m_name should become m_localName
69 QCString qualifiedName;
70 QCString ref; // reference to external documentation
71
72 bool hidden;
73 bool isArtificial;
74
75 Definition *outerScope; // not owner
76
77 // where the item was found
78 QCString defFileName;
79 int defLine;
80 QCString defFileExt;
81};
82
83DefinitionImpl::DefinitionImpl()
84 : sectionDict(0), sourceRefByDict(0), sourceRefsDict(0),
85 xrefListItems(0), partOfGroups(0),
86 details(0), inbodyDocs(0), brief(0), body(0),
87 outerScope(0)
88{
89}
90
91DefinitionImpl::~DefinitionImpl()
92{
93 delete sectionDict;
94 delete sourceRefByDict;
95 delete sourceRefsDict;
96 delete partOfGroups;
97 delete xrefListItems;
98 delete brief;
99 delete details;
100 delete body;
101 delete inbodyDocs;
102}
103
104void DefinitionImpl::init(const char *df,int dl,
105 const char *n)
106{
107 defFileName = df;
108 int lastDot = defFileName.findRev('.');
109 if (lastDot!=-1)
110 {
111 defFileExt = defFileName.mid(lastDot);
112 }
113 defLine = dl;
114 QCString name = n;
115 if (name!="<globalScope>")
116 {
117 //extractNamespaceName(m_name,m_localName,ns);
118 localName=stripScope(n);
119 }
120 else
121 {
122 localName=n;
123 }
124 //printf("m_localName=%s\n",m_localName.data());
125
126 brief = 0;
127 details = 0;
128 body = 0;
129 inbodyDocs = 0;
130 sourceRefByDict = 0;
131 sourceRefsDict = 0;
132 sectionDict = 0,
133 outerScope = Doxygen::globalScope;
134 partOfGroups = 0;
135 xrefListItems = 0;
136 hidden = FALSE;
137 isArtificial = FALSE;
138}
139
140//-----------------------------------------------------------------------------------------
141
142static bool matchExcludedSymbols(const char *name)
143{
144 static QStrList &exclSyms = Config_getList("EXCLUDE_SYMBOLS");
145 if (exclSyms.count()==0) return FALSE; // nothing specified
146 const char *pat = exclSyms.first();
147 QCString symName = name;
148 while (pat)
149 {
150 QCString pattern = pat;
151 bool forceStart=FALSE;
152 bool forceEnd=FALSE;
153 if (pattern.at(0)=='^')
154 pattern=pattern.mid(1),forceStart=TRUE;
155 if (pattern.at(pattern.length()-1)=='$')
156 pattern=pattern.left(pattern.length()-1),forceEnd=TRUE;
157 if (pattern.find('*')!=-1) // wildcard mode
158 {
159 QRegExp re(substitute(pattern,"*",".*"),TRUE);
160 int i,pl;
161 i = re.match(symName,0,&pl);
162 //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data());
163 if (i!=-1) // wildcard match
164 {
165 int sl=symName.length();
166 // check if it is a whole word match
167 if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) &&
168 (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd))
169 )
170 {
171 //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
172 return TRUE;
173 }
174 }
175 }
176 else if (!pattern.isEmpty()) // match words
177 {
178 int i = symName.find(pattern);
179 if (i!=-1) // we have a match!
180 {
181 int pl=pattern.length();
182 int sl=symName.length();
183 // check if it is a whole word match
184 if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) &&
185 (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd))
186 )
187 {
188 //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
189 return TRUE;
190 }
191 }
192 }
193 pat = exclSyms.next();
194 }
195 //printf("--> name=%s: no match\n",name);
196 return FALSE;
197}
198
199void Definition::addToMap(const char *name,Definition *d)
200{
201 bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
202 QCString symbolName = name;
203 int index=computeQualifiedIndex(symbolName);
204 if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
205 if (!symbolName.isEmpty())
206 {
207 //printf("******* adding symbol `%s' (%p)\n",symbolName.data(),d);
208 DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
209 //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di);
210 if (di==0) // new Symbol
211 {
212 //printf(" new symbol!\n");
213 Doxygen::symbolMap->insert(symbolName,d);
214 }
215 else // existing symbol
216 {
217 //printf(" existing symbol: ");
218 if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols
219 {
220 //printf("adding to exiting list\n");
221 DefinitionList *dl = (DefinitionList*)di;
222 dl->append(d);
223 }
224 else // going from one to two symbols
225 {
226 Doxygen::symbolMap->take(symbolName);
227 DefinitionList *dl = new DefinitionList;
228 //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d);
229 dl->append((Definition*)di);
230 dl->append(d);
231 Doxygen::symbolMap->insert(symbolName,dl);
232 }
233 }
234
235 // auto resize if needed
236 static int sizeIndex=9;
237 if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex])
238 {
239 Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]);
240 }
241
242 d->_setSymbolName(symbolName);
243 }
244}
245
246void Definition::removeFromMap(Definition *d)
247{
248 QString symbolName = d->m_symbolName;
249 if (!symbolName.isEmpty())
250 {
251 //printf("******* removing symbol `%s' (%p)\n",symbolName.data(),d);
252 DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
253 if (di)
254 {
255 if (di!=d) // symbolName not unique
256 {
257 //printf(" removing from list: %p!\n",di);
258 DefinitionList *dl = (DefinitionList*)di;
259 bool b = dl->removeRef(d);
260 ASSERT(b==TRUE);
261 if (dl->isEmpty())
262 {
263 Doxygen::symbolMap->take(symbolName);
264 }
265 }
266 else // symbolName unique
267 {
268 //printf(" removing symbol %p\n",di);
269 Doxygen::symbolMap->take(symbolName);
270 }
271 }
272 }
273}
274
275Definition::Definition(const char *df,int dl,
276 const char *name,const char *b,
277 const char *d,bool isSymbol)
278{
279 m_name = name;
280 m_impl = new DefinitionImpl;
281 m_impl->init(df,dl,name);
282 m_isSymbol = isSymbol;
283 if (isSymbol) addToMap(name,this);
284 _setBriefDescription(b,df,dl);
285 _setDocumentation(d,df,dl,TRUE,FALSE);
286 if (matchExcludedSymbols(name))
287 {
288 m_impl->hidden = TRUE;
289 }
290}
291
292Definition::~Definition()
293{
294 if (m_isSymbol)
295 {
296 removeFromMap(this);
297 }
298 if (m_impl)
299 {
300 delete m_impl;
301 m_impl=0;
302 }
303}
304
305void Definition::setName(const char *name)
306{
307 if (name==0) return;
308 m_name = name;
309}
310
311void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList)
312{
313 if (!anchorList) return;
314 makeResident();
315 //printf("%s: addSectionsToDefinition(%d)\n",name().data(),anchorList->count());
316 SectionInfo *si=anchorList->first();
317 while (si)
318 {
319 //printf("Add section `%s' to definition `%s'\n",
320 // si->label.data(),name().data());
321 SectionInfo *gsi=Doxygen::sectionDict.find(si->label);
322 if (gsi==0)
323 {
324 gsi = new SectionInfo(*si);
325 Doxygen::sectionDict.insert(si->label,gsi);
326 }
327 if (m_impl->sectionDict==0)
328 {
329 m_impl->sectionDict = new SectionDict(17);
330 }
331 if (m_impl->sectionDict->find(gsi->label)==0)
332 {
333 m_impl->sectionDict->insert(gsi->label,gsi);
334 gsi->definition = this;
335 }
336 si=anchorList->next();
337 }
338}
339
340void Definition::writeDocAnchorsToTagFile()
341{
342 makeResident();
343 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict)
344 {
345 //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_sectionDict->count());
346 QDictIterator<SectionInfo> sdi(*m_impl->sectionDict);
347 SectionInfo *si;
348 for (;(si=sdi.current());++sdi)
349 {
350 if (!si->generated)
351 {
352 //printf("write an entry!\n");
353 if (definitionType()==TypeMember) Doxygen::tagFile << " ";
354 Doxygen::tagFile << " <docanchor file=\""
355 << si->fileName << "\">" << si->label
356 << "</docanchor>" << endl;
357 }
358 }
359 }
360}
361
362bool Definition::_docsAlreadyAdded(const QCString &doc)
363{
364 uchar md5_sig[16];
365 QCString sigStr(33);
366 // to avoid mismatches due to differences in indenting, we first remove
367 // double whitespaces...
368 QCString docStr = doc.simplifyWhiteSpace();
369 MD5Buffer((const unsigned char *)docStr.data(),docStr.length(),md5_sig);
370 MD5SigToString(md5_sig,sigStr.data(),33);
371 if (m_impl->docSignatures.find(sigStr)==-1) // new docs, add signature to prevent re-adding it
372 {
373 m_impl->docSignatures+=":"+sigStr;
374 return FALSE;
375 }
376 else
377 {
378 return TRUE;
379 }
380}
381
382void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,
383 bool stripWhiteSpace,bool atTop)
384{
385 if (d==0) return;
386 //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace);
387 QCString doc = d;
388 if (stripWhiteSpace)
389 {
390 doc = stripLeadingAndTrailingEmptyLines(doc);
391 }
392 else // don't strip whitespace
393 {
394 doc=d;
395 }
396 if (!_docsAlreadyAdded(doc))
397 {
398 //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data());
399 if (m_impl->details==0)
400 {
401 m_impl->details = new DocInfo;
402 }
403 if (m_impl->details->doc.isEmpty()) // fresh detailed description
404 {
405 m_impl->details->doc = doc;
406 }
407 else if (atTop) // another detailed description, append it to the start
408 {
409 m_impl->details->doc = doc+"\n\n"+m_impl->details->doc;
410 }
411 else // another detailed description, append it to the end
412 {
413 m_impl->details->doc += "\n\n"+doc;
414 }
415 if (docLine!=-1) // store location if valid
416 {
417 m_impl->details->file = docFile;
418 m_impl->details->line = docLine;
419 }
420 else
421 {
422 m_impl->details->file = docFile;
423 m_impl->details->line = 1;
424 }
425 }
426}
427
428void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
429{
430 if (d==0) return;
431 makeResident();
432 _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE);
433}
434
435#define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase)
436
437// do a UTF-8 aware search for the last real character and return TRUE
438// if that is a multibyte one.
439static bool lastCharIsMultibyte(const QCString &s)
440{
441 int l = s.length();
442 int p = 0;
443 int pp = -1;
444 while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p;
445 if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE;
446 return TRUE;
447}
448
449void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine)
450{
451 static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE");
452 static bool needsDot = outputLanguage!="Japanese" &&
453 outputLanguage!="Chinese" &&
454 outputLanguage!="Korean";
455 QCString brief = b;
456 brief = brief.stripWhiteSpace();
457 if (brief.isEmpty()) return;
458 int bl = brief.length();
459 if (bl>0 && needsDot) // add punctuation if needed
460 {
461 int c = brief.at(bl-1);
462 switch(c)
463 {
464 case '.': case '!': case '?': case '>': case ':': case ')': break;
465 default:
466 if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.';
467 break;
468 }
469 }
470
471 if (m_impl->brief && !m_impl->brief->doc.isEmpty())
472 {
473 //printf("adding to details\n");
474 _setDocumentation(brief,briefFile,briefLine,FALSE,TRUE);
475 }
476 else if (!_docsAlreadyAdded(brief))
477 {
478 //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine);
479 if (m_impl->brief==0)
480 {
481 m_impl->brief = new BriefInfo;
482 }
483 m_impl->brief->doc=brief;
484 if (briefLine!=-1)
485 {
486 m_impl->brief->file = briefFile;
487 m_impl->brief->line = briefLine;
488 }
489 else
490 {
491 m_impl->brief->file = briefFile;
492 m_impl->brief->line = 1;
493 }
494 }
495}
496
497void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine)
498{
499 if (b==0) return;
500 makeResident();
501 _setBriefDescription(b,briefFile,briefLine);
502}
503
504void Definition::_setInbodyDocumentation(const char *doc,const char *inbodyFile,int inbodyLine)
505{
506 if (m_impl->inbodyDocs==0)
507 {
508 m_impl->inbodyDocs = new DocInfo;
509 }
510 if (m_impl->inbodyDocs->doc.isEmpty()) // fresh inbody docs
511 {
512 m_impl->inbodyDocs->doc = doc;
513 m_impl->inbodyDocs->file = inbodyFile;
514 m_impl->inbodyDocs->line = inbodyLine;
515 }
516 else // another inbody documentation fragment, append this to the end
517 {
518 m_impl->inbodyDocs->doc += QCString("\n\n")+doc;
519 }
520}
521
522void Definition::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
523{
524 if (d==0) return;
525 makeResident();
526 _setInbodyDocumentation(d,inbodyFile,inbodyLine);
527}
528
529/*! Reads a fragment of code from file \a fileName starting at
530 * line \a startLine and ending at line \a endLine (inclusive). The fragment is
531 * stored in \a result. If FALSE is returned the code fragment could not be
532 * found.
533 *
534 * The file is scanned for a opening bracket ('{') from \a startLine onward
535 * The line actually containing the bracket is returned via startLine.
536 * The file is scanned for a closing bracket ('}') from \a endLine backward.
537 * The line actually containing the bracket is returned via endLine.
538 * Note that for VHDL code the bracket search is not done.
539 */
540static bool readCodeFragment(const char *fileName,
541 int &startLine,int &endLine,QCString &result)
542{
543 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
544 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
545 //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine);
546 if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name
547 QCString filter = getFileFilter(fileName,TRUE);
548 FILE *f=0;
549 bool usePipe = !filter.isEmpty() && filterSourceFiles;
550 if (!usePipe) // no filter given or wanted
551 {
552 f = portable_fopen(fileName,"r");
553 }
554 else // use filter
555 {
556 QCString cmd=filter+" \""+fileName+"\"";
557 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
558 f = portable_popen(cmd,"r");
559 }
560 bool found=vhdlOpt; // for VHDL no bracket search is possible
561 if (f)
562 {
563 int c=0;
564 int col=0;
565 int lineNr=1;
566 // skip until the startLine has reached
567 while (lineNr<startLine && !feof(f))
568 {
569 while ((c=fgetc(f))!='\n' && c!=EOF) /* skip */;
570 lineNr++;
571 }
572 if (!feof(f))
573 {
574 // skip until the opening bracket or lonely : is found
575 char cn=0;
576 while (lineNr<=endLine && !feof(f) && !found)
577 {
578 int pc=0;
579 while ((c=fgetc(f))!='{' && c!=':' && c!=EOF)
580 {
581 //printf("parsing char `%c'\n",c);
582 if (c=='\n')
583 {
584 lineNr++,col=0;
585 }
586 else if (c=='\t')
587 {
588 col+=Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
589 }
590 else if (pc=='/' && c=='/') // skip single line comment
591 {
592 while ((c=fgetc(f))!='\n' && c!=EOF) pc=c;
593 if (c=='\n') lineNr++,col=0;
594 }
595 else if (pc=='/' && c=='*') // skip C style comment
596 {
597 while (((c=fgetc(f))!='/' || pc!='*') && c!=EOF)
598 {
599 if (c=='\n') lineNr++,col=0;
600 pc=c;
601 }
602 }
603 else
604 {
605 col++;
606 }
607 pc = c;
608 }
609 if (c==':')
610 {
611 cn=fgetc(f);
612 if (cn!=':') found=TRUE;
613 }
614 else if (c=='{')
615 {
616 found=TRUE;
617 }
618 }
619 //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr);
620 if (found)
621 {
622 // For code with more than one line,
623 // fill the line with spaces until we are at the right column
624 // so that the opening brace lines up with the closing brace
625 if (endLine!=startLine)
626 {
627 QCString spaces;
628 spaces.fill(' ',col);
629 result+=spaces;
630 }
631 // copy until end of line
632 result+=c;
633 if (c==':')
634 {
635 result+=cn;
636 if (cn=='\n') lineNr++;
637 }
638 startLine=lineNr;
639 const int maxLineLength=4096;
640 char lineStr[maxLineLength];
641 do
642 {
643 //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine);
644 int size_read;
645 do
646 {
647 // read up to maxLineLength-1 bytes, the last byte being zero
648 char *p = fgets(lineStr, maxLineLength,f);
649 //printf(" read %s",p);
650 if (p)
651 {
652 size_read=qstrlen(p);
653 }
654 else // nothing read
655 {
656 size_read=-1;
657 lineStr[0]='\0';
658 }
659 result+=lineStr;
660 } while (size_read == (maxLineLength-1));
661
662 lineNr++;
663 } while (lineNr<=endLine && !feof(f));
664
665 // strip stuff after closing bracket
666 int newLineIndex = result.findRev('\n');
667 int braceIndex = result.findRev('}');
668 if (braceIndex > newLineIndex)
669 {
670 result.truncate(braceIndex+1);
671 }
672 endLine=lineNr-1;
673 }
674 }
675 if (usePipe)
676 {
677 portable_pclose(f);
678 }
679 else
680 {
681 fclose(f);
682 }
683 }
684 result = transcodeCharacterStringToUTF8(result);
685 return found;
686}
687
688/*! Write a reference to the source code defining this definition */
689void Definition::writeSourceDef(OutputList &ol,const char *)
690{
691 static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
692 static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
693 makeResident();
694 ol.pushGeneratorState();
695 //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef);
696 if (sourceBrowser &&
697 m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->fileDef)
698 {
699 QCString refText = theTranslator->trDefinedAtLineInSourceFile();
700 int lineMarkerPos = refText.find("@0");
701 int fileMarkerPos = refText.find("@1");
702 if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this.
703 {
704 QCString lineStr,anchorStr;
705 lineStr.sprintf("%d",m_impl->body->startLine);
706 anchorStr.sprintf(Htags::useHtags ? "L%d" : "l%05d",m_impl->body->startLine);
707 ol.startParagraph();
708 if (lineMarkerPos<fileMarkerPos) // line marker before file marker
709 {
710 // write text left from linePos marker
711 ol.parseText(refText.left(lineMarkerPos));
712 ol.pushGeneratorState();
713 ol.disable(OutputGenerator::RTF);
714 ol.disable(OutputGenerator::Man);
715 if (!latexSourceCode)
716 {
717 ol.disable(OutputGenerator::Latex);
718 }
719 // write line link (HTML, LaTeX optionally)
720 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(),
721 anchorStr,lineStr);
722 ol.enableAll();
723 ol.disable(OutputGenerator::Html);
724 if (latexSourceCode)
725 {
726 ol.disable(OutputGenerator::Latex);
727 }
728 // write normal text (Man/RTF, Latex optionally)
729 ol.docify(lineStr);
730 ol.popGeneratorState();
731
732 // write text between markers
733 ol.parseText(refText.mid(lineMarkerPos+2,
734 fileMarkerPos-lineMarkerPos-2));
735
736 ol.pushGeneratorState();
737 ol.disable(OutputGenerator::RTF);
738 ol.disable(OutputGenerator::Man);
739 if (!latexSourceCode)
740 {
741 ol.disable(OutputGenerator::Latex);
742 }
743 // write line link (HTML, LaTeX optionally)
744 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(),
745 0,m_impl->body->fileDef->name());
746 ol.enableAll();
747 ol.disable(OutputGenerator::Html);
748 if (latexSourceCode)
749 {
750 ol.disable(OutputGenerator::Latex);
751 }
752 // write normal text (Man/RTF, Latex optionally)
753 ol.docify(m_impl->body->fileDef->name());
754 ol.popGeneratorState();
755
756 // write text right from file marker
757 ol.parseText(refText.right(
758 refText.length()-fileMarkerPos-2));
759 }
760 else // file marker before line marker
761 {
762 // write text left from file marker
763 ol.parseText(refText.left(fileMarkerPos));
764 ol.pushGeneratorState();
765 ol.disable(OutputGenerator::RTF);
766 ol.disable(OutputGenerator::Man);
767 if (!latexSourceCode)
768 {
769 ol.disable(OutputGenerator::Latex);
770 }
771 // write file link (HTML only)
772 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(),
773 0,m_impl->body->fileDef->name());
774 ol.enableAll();
775 ol.disable(OutputGenerator::Html);
776 if (latexSourceCode)
777 {
778 ol.disable(OutputGenerator::Latex);
779 }
780 // write normal text (Latex/Man only)
781 ol.docify(m_impl->body->fileDef->name());
782 ol.popGeneratorState();
783
784 // write text between markers
785 ol.parseText(refText.mid(fileMarkerPos+2,
786 lineMarkerPos-fileMarkerPos-2));
787
788 ol.pushGeneratorState();
789 ol.disable(OutputGenerator::RTF);
790 ol.disable(OutputGenerator::Man);
791 if (!latexSourceCode)
792 {
793 ol.disable(OutputGenerator::Latex);
794 }
795 ol.disableAllBut(OutputGenerator::Html);
796 // write line link (HTML only)
797 ol.writeObjectLink(0,m_impl->body->fileDef->getSourceFileBase(),
798 anchorStr,lineStr);
799 ol.enableAll();
800 ol.disable(OutputGenerator::Html);
801 if (latexSourceCode)
802 {
803 ol.disable(OutputGenerator::Latex);
804 }
805 // write normal text (Latex/Man only)
806 ol.docify(lineStr);
807 ol.popGeneratorState();
808
809 // write text right from linePos marker
810 ol.parseText(refText.right(
811 refText.length()-lineMarkerPos-2));
812 }
813 ol.endParagraph();
814 }
815 else
816 {
817 err("error: translation error: invalid markers in trDefinedInSourceFile()\n");
818 }
819 }
820 ol.popGeneratorState();
821}
822
823void Definition::setBodySegment(int bls,int ble)
824{
825 //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data());
826 makeResident();
827 if (m_impl->body==0) m_impl->body = new BodyInfo;
828 m_impl->body->startLine=bls;
829 m_impl->body->endLine=ble;
830}
831
832void Definition::setBodyDef(FileDef *fd)
833{
834 makeResident();
835 if (m_impl->body==0) m_impl->body = new BodyInfo;
836 m_impl->body->fileDef=fd;
837}
838
839/*! Write code of this definition into the documentation */
840void Definition::writeInlineCode(OutputList &ol,const char *scopeName)
841{
842 makeResident();
843 ol.pushGeneratorState();
844 //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(),
845 // m_startBodyLine,m_endBodyLine,m_bodyDef);
846 if (Config_getBool("INLINE_SOURCES") &&
847 m_impl->body && m_impl->body->startLine!=-1 &&
848 m_impl->body->endLine>=m_impl->body->startLine && m_impl->body->fileDef)
849 {
850 QCString codeFragment;
851 int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine;
852 if (readCodeFragment(m_impl->body->fileDef->absFilePath(),
853 actualStart,actualEnd,codeFragment)
854 )
855 {
856 //printf("Adding code fragement '%s' ext='%s'\n",
857 // codeFragment.data(),m_impl->defFileExt.data());
858 ParserInterface *pIntf = Doxygen::parserManager->getParser(m_impl->defFileExt);
859 pIntf->resetCodeParserState();
860 //printf("Read:\n`%s'\n\n",codeFragment.data());
861 MemberDef *thisMd = 0;
862 if (definitionType()==TypeMember) thisMd = (MemberDef *)this;
863 ol.startCodeFragment();
864 pIntf->parseCode(ol, // codeOutIntf
865 scopeName, // scope
866 codeFragment, // input
867 FALSE, // isExample
868 0, // exampleName
869 m_impl->body->fileDef, // fileDef
870 actualStart, // startLine
871 actualEnd, // endLine
872 TRUE, // inlineFragment
873 thisMd, // memberDef
874 FALSE // show line numbers
875 );
876 ol.endCodeFragment();
877 }
878 }
879 ol.popGeneratorState();
880}
881
882/*! Write a reference to the source code fragments in which this
883 * definition is used.
884 */
885void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
886 const QCString &text,MemberSDict *members,bool /*funcOnly*/)
887{
888 static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
889 static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
890 static bool refLinkSource = Config_getBool("REFERENCES_LINK_SOURCE");
891 ol.pushGeneratorState();
892 if (members)
893 {
894 ol.startParagraph();
895 ol.parseText(text);
896 ol.docify(" ");
897
898 QCString ldefLine=theTranslator->trWriteList(members->count());
899
900 QRegExp marker("@[0-9]+");
901 int index=0,newIndex,matchLen;
902 // now replace all markers in inheritLine with links to the classes
903 while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1)
904 {
905 bool ok;
906 ol.parseText(ldefLine.mid(index,newIndex-index));
907 uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
908 MemberDef *md=members->at(entryIndex);
909 if (ok && md)
910 {
911 QCString scope=md->getScopeString();
912 QCString name=md->name();
913 //printf("class=%p scope=%s scopeName=%s\n",md->getClassDef(),scope.data(),scopeName);
914 if (!scope.isEmpty() && scope!=scopeName)
915 {
916 if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
917 {
918 name.prepend(scope+".");
919 }
920 else
921 {
922 name.prepend(scope+"::");
923 }
924 }
925 if (!md->isObjCMethod() &&
926 (md->isFunction() || md->isSlot() ||
927 md->isPrototype() || md->isSignal()
928 )
929 )
930 {
931 name+="()";
932 }
933 //Definition *d = md->getOutputFileBase();
934 //if (d==Doxygen::globalScope) d=md->getBodyDef();
935 if (sourceBrowser &&
936 !(md->isLinkable() && !refLinkSource) &&
937 md->getStartBodyLine()!=-1 &&
938 md->getBodyDef()
939 )
940 {
941 //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope);
942 // for HTML write a real link
943 ol.pushGeneratorState();
944 //ol.disableAllBut(OutputGenerator::Html);
945
946 ol.disable(OutputGenerator::RTF);
947 ol.disable(OutputGenerator::Man);
948 if (!latexSourceCode)
949 {
950 ol.disable(OutputGenerator::Latex);
951 }
952 QCString lineStr,anchorStr;
953 anchorStr.sprintf("l%05d",md->getStartBodyLine());
954 //printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data());
955 ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name);
956 ol.popGeneratorState();
957
958 // for the other output formats just mention the name
959 ol.pushGeneratorState();
960 ol.disable(OutputGenerator::Html);
961 if (latexSourceCode)
962 {
963 ol.disable(OutputGenerator::Latex);
964 }
965 ol.docify(name);
966 ol.popGeneratorState();
967 }
968 else if (md->isLinkable() /*&& d && d->isLinkable()*/)
969 {
970 // for HTML write a real link
971 ol.pushGeneratorState();
972 //ol.disableAllBut(OutputGenerator::Html);
973 ol.disable(OutputGenerator::RTF);
974 ol.disable(OutputGenerator::Man);
975 if (!latexSourceCode)
976 {
977 ol.disable(OutputGenerator::Latex);
978 }
979
980 ol.writeObjectLink(md->getReference(),
981 md->getOutputFileBase(),
982 md->anchor(),name);
983 ol.popGeneratorState();
984
985 // for the other output formats just mention the name
986 ol.pushGeneratorState();
987 ol.disable(OutputGenerator::Html);
988 if (latexSourceCode)
989 {
990 ol.disable(OutputGenerator::Latex);
991 }
992 ol.docify(name);
993 ol.popGeneratorState();
994 }
995 else
996 {
997 ol.docify(name);
998 }
999 }
1000 index=newIndex+matchLen;
1001 }
1002 ol.parseText(ldefLine.right(ldefLine.length()-index));
1003 ol.writeString(".");
1004 ol.endParagraph();
1005 }
1006 ol.popGeneratorState();
1007}
1008
1009void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName)
1010{
1011 makeResident();
1012 if (Config_getBool("REFERENCED_BY_RELATION"))
1013 {
1014 _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE);
1015 }
1016}
1017
1018void Definition::writeSourceRefs(OutputList &ol,const char *scopeName)
1019{
1020 makeResident();
1021 if (Config_getBool("REFERENCES_RELATION"))
1022 {
1023 _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE);
1024 }
1025}
1026
1027bool Definition::hasDocumentation() const
1028{
1029 static bool extractAll = Config_getBool("EXTRACT_ALL");
1030 //static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1031 makeResident();
1032 bool hasDocs =
1033 (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs
1034 (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description
1035 (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty()) || // has inbody docs
1036 extractAll //|| // extract everything
1037 // (sourceBrowser && m_impl->body &&
1038 // m_impl->body->startLine!=-1 && m_impl->body->fileDef)
1039 ; // link to definition
1040 return hasDocs;
1041}
1042
1043bool Definition::hasUserDocumentation() const
1044{
1045 makeResident();
1046 bool hasDocs =
1047 (m_impl->details && !m_impl->details->doc.isEmpty()) ||
1048 (m_impl->brief && !m_impl->brief->doc.isEmpty()) ||
1049 (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty());
1050 return hasDocs;
1051}
1052
1053void Definition::addSourceReferencedBy(MemberDef *md)
1054{
1055 if (md)
1056 {
1057 makeResident();
1058 QCString name = md->name();
1059 QCString scope = md->getScopeString();
1060
1061 if (!scope.isEmpty())
1062 {
1063 name.prepend(scope+"::");
1064 }
1065
1066 if (m_impl->sourceRefByDict==0)
1067 {
1068 m_impl->sourceRefByDict = new MemberSDict;
1069 }
1070 if (m_impl->sourceRefByDict->find(name)==0)
1071 {
1072 m_impl->sourceRefByDict->inSort(name,md);
1073 }
1074 }
1075}
1076
1077void Definition::addSourceReferences(MemberDef *md)
1078{
1079 if (md)
1080 {
1081 QCString name = md->name();
1082 QCString scope = md->getScopeString();
1083 makeResident();
1084
1085 if (!scope.isEmpty())
1086 {
1087 name.prepend(scope+"::");
1088 }
1089
1090 if (m_impl->sourceRefsDict==0)
1091 {
1092 m_impl->sourceRefsDict = new MemberSDict;
1093 }
1094 if (m_impl->sourceRefsDict->find(name)==0)
1095 {
1096 m_impl->sourceRefsDict->inSort(name,md);
1097 }
1098 }
1099}
1100
1101Definition *Definition::findInnerCompound(const char *)
1102{
1103 return 0;
1104}
1105
1106void Definition::addInnerCompound(Definition *)
1107{
1108 err("error: Definition::addInnerCompound() called\n");
1109}
1110
1111QCString Definition::qualifiedName() const
1112{
1113 static int count=0;
1114 count++;
1115 makeResident();
1116 if (!m_impl->qualifiedName.isEmpty())
1117 {
1118 count--;
1119 return m_impl->qualifiedName;
1120 }
1121#if 0
1122 if (count>20)
1123 {
1124 printf("Definition::qualifiedName() Infinite recursion detected! Type=%d\n",definitionType());
1125 printf("Trace:\n");
1126 Definition *d = (Definition *)this;
1127 for (int i=0;d && i<20;i++)
1128 {
1129 printf(" %s\n",d->name().data());
1130 d = d->getOuterScope();
1131 }
1132 }
1133#endif
1134
1135 //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data());
1136 if (m_impl->outerScope==0)
1137 {
1138 if (m_impl->localName=="<globalScope>")
1139 {
1140 count--;
1141 return "";
1142 }
1143 else
1144 {
1145 count--;
1146 return m_impl->localName;
1147 }
1148 }
1149
1150 if (m_impl->outerScope->name()=="<globalScope>")
1151 {
1152 m_impl->qualifiedName = m_impl->localName;
1153 }
1154 else
1155 {
1156 m_impl->qualifiedName = m_impl->outerScope->qualifiedName()+"::"+m_impl->localName;
1157 }
1158 //printf("end %s::qualifiedName()=%s\n",name().data(),m_impl->qualifiedName.data());
1159 count--;
1160 return m_impl->qualifiedName;
1161};
1162
1163void Definition::setOuterScope(Definition *d)
1164{
1165 makeResident();
1166 if (m_impl->outerScope!=d)
1167 {
1168 m_impl->qualifiedName.resize(0); // flush cached scope name
1169 m_impl->outerScope = d;
1170 }
1171 m_impl->hidden = m_impl->hidden || d->isHidden();
1172}
1173
1174QCString Definition::localName() const
1175{
1176 makeResident();
1177 return m_impl->localName;
1178}
1179
1180void Definition::makePartOfGroup(GroupDef *gd)
1181{
1182 makeResident();
1183 if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList;
1184 m_impl->partOfGroups->append(gd);
1185}
1186
1187void Definition::setRefItems(const QList<ListItemInfo> *sli)
1188{
1189 //printf("%s::setRefItems()\n",name().data());
1190 if (sli)
1191 {
1192 makeResident();
1193 // deep copy the list
1194 if (m_impl->xrefListItems==0)
1195 {
1196 m_impl->xrefListItems=new QList<ListItemInfo>;
1197 m_impl->xrefListItems->setAutoDelete(TRUE);
1198 }
1199 QListIterator<ListItemInfo> slii(*sli);
1200 ListItemInfo *lii;
1201 for (slii.toFirst();(lii=slii.current());++slii)
1202 {
1203 m_impl->xrefListItems->append(new ListItemInfo(*lii));
1204 }
1205 }
1206}
1207
1208void Definition::mergeRefItems(Definition *d)
1209{
1210 //printf("%s::mergeRefItems()\n",name().data());
1211 LockingPtr< QList<ListItemInfo> > xrefList = d->xrefListItems();
1212 if (xrefList!=0)
1213 {
1214 makeResident();
1215 // deep copy the list
1216 if (m_impl->xrefListItems==0)
1217 {
1218 m_impl->xrefListItems=new QList<ListItemInfo>;
1219 m_impl->xrefListItems->setAutoDelete(TRUE);
1220 }
1221 QListIterator<ListItemInfo> slii(*xrefList);
1222 ListItemInfo *lii;
1223 for (slii.toFirst();(lii=slii.current());++slii)
1224 {
1225 if (_getXRefListId(lii->type)==-1)
1226 {
1227 m_impl->xrefListItems->append(new ListItemInfo(*lii));
1228 }
1229 }
1230 }
1231}
1232
1233int Definition::_getXRefListId(const char *listName) const
1234{
1235 makeResident();
1236 if (m_impl->xrefListItems)
1237 {
1238 QListIterator<ListItemInfo> slii(*m_impl->xrefListItems);
1239 ListItemInfo *lii;
1240 for (slii.toFirst();(lii=slii.current());++slii)
1241 {
1242 if (strcmp(lii->type,listName)==0)
1243 {
1244 return lii->itemId;
1245 }
1246 }
1247 }
1248 return -1;
1249}
1250
1251LockingPtr< QList<ListItemInfo> > Definition::xrefListItems() const
1252{
1253 makeResident();
1254 return LockingPtr< QList<ListItemInfo> >(this,m_impl->xrefListItems);
1255}
1256
1257
1258QCString Definition::convertNameToFile(const char *name,bool allowDots) const
1259{
1260 makeResident();
1261 if (!m_impl->ref.isEmpty())
1262 {
1263 return name;
1264 }
1265 else
1266 {
1267 return ::convertNameToFile(name,allowDots);
1268 }
1269}
1270
1271QCString Definition::pathFragment() const
1272{
1273 makeResident();
1274 QCString result;
1275 if (m_impl->outerScope && m_impl->outerScope!=Doxygen::globalScope)
1276 {
1277 result = m_impl->outerScope->pathFragment();
1278 }
1279 if (isLinkable())
1280 {
1281 if (!result.isEmpty()) result+="/";
1282 if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
1283 {
1284 result+=((const GroupDef*)this)->groupTitle();
1285 }
1286 else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
1287 {
1288 result+=((const PageDef*)this)->title();
1289 }
1290 else
1291 {
1292 result+=m_impl->localName;
1293 }
1294 }
1295 else
1296 {
1297 result+=m_impl->localName;
1298 }
1299 return result;
1300}
1301
1302void Definition::writePathFragment(OutputList &ol) const
1303{
1304 makeResident();
1305 if (m_impl->outerScope && m_impl->outerScope!=Doxygen::globalScope)
1306 {
1307 m_impl->outerScope->writePathFragment(ol);
1308 }
1309 ol.writeString(" <li class=\"navelem\">");
1310 if (isLinkable())
1311 {
1312 if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
1313 {
1314 ol.writeObjectLink(getReference(),getOutputFileBase(),0,((const GroupDef*)this)->groupTitle());
1315 }
1316 else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
1317 {
1318 ol.writeObjectLink(getReference(),getOutputFileBase(),0,((const PageDef*)this)->title());
1319 }
1320 else if (definitionType()==Definition::TypeClass)
1321 {
1322 QCString name = m_impl->localName;
1323 if (name.right(2)=="-p" || name.right(2)=="-g")
1324 {
1325 name = name.left(name.length()-2);
1326 }
1327 ol.writeObjectLink(getReference(),getOutputFileBase(),0,name);
1328 }
1329 else
1330 {
1331 ol.writeObjectLink(getReference(),getOutputFileBase(),0,m_impl->localName);
1332 }
1333 }
1334 else
1335 {
1336 ol.startBold();
1337 ol.docify(m_impl->localName);
1338 ol.endBold();
1339 }
1340 ol.writeString(" </li>\n");
1341}
1342
1343void Definition::writeNavigationPath(OutputList &ol) const
1344{
1345 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1346 static bool hasCustomFooter = !Config_getString("HTML_FOOTER").isEmpty();
1347
1348 ol.pushGeneratorState();
1349 ol.disableAllBut(OutputGenerator::Html);
1350
1351 if (generateTreeView)
1352 {
1353 ol.writeString("</div>\n");
1354 }
1355
1356 ol.writeString(" <div id=\"nav-path\" class=\"navpath\">\n");
1357 ol.writeString(" <ul>\n");
1358 writePathFragment(ol);
1359 if (!hasCustomFooter && generateTreeView) // write the doxygen logo as part of the navigation bar
1360 {
1361 ol.writeString(" <li class=\"footer\">");
1362 ol.writeLogo();
1363 ol.writeString("</li>\n");
1364 }
1365 if (!hasCustomFooter || !generateTreeView)
1366 {
1367 ol.writeString(" </ul>\n");
1368 ol.writeString(" </div>\n");
1369 }
1370
1371 ol.popGeneratorState();
1372}
1373
1374QCString Definition::symbolName() const
1375{
1376 return m_symbolName;
1377}
1378
1379//----------------------
1380
1381QCString Definition::documentation() const
1382{
1383 makeResident();
1384 return m_impl->details ? m_impl->details->doc : QCString("");
1385}
1386
1387int Definition::docLine() const
1388{
1389 makeResident();
1390 return m_impl->details ? m_impl->details->line : 1;
1391}
1392
1393QCString Definition::docFile() const
1394{
1395 makeResident();
1396 return m_impl->details ? m_impl->details->file : QCString("<"+m_name+">");
1397}
1398
1399//----------------------
1400
1401QCString Definition::briefDescription() const
1402{
1403 makeResident();
1404 return m_impl->brief ? m_impl->brief->doc : QCString("");
1405}
1406
1407QCString Definition::briefDescriptionAsTooltip() const
1408{
1409 makeResident();
1410 if (m_impl->brief)
1411 {
1412 if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty())
1413 {
1414 static bool reentering=FALSE;
1415 if (!reentering)
1416 {
1417 MemberDef *md = definitionType()==TypeMember ? (MemberDef*)this : 0;
1418 const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this;
1419 reentering=TRUE; // prevent requests for tooltips while parsing a tooltip
1420 m_impl->brief->tooltip = parseCommentAsText(
1421 scope,md,
1422 m_impl->brief->doc,
1423 m_impl->brief->file,
1424 m_impl->brief->line);
1425 reentering=FALSE;
1426 }
1427 }
1428 return m_impl->brief->tooltip;
1429 }
1430 return QCString("");
1431}
1432
1433int Definition::briefLine() const
1434{
1435 makeResident();
1436 return m_impl->brief ? m_impl->brief->line : 1;
1437}
1438
1439QCString Definition::briefFile() const
1440{
1441 makeResident();
1442 return m_impl->brief ? m_impl->brief->file : QCString("<"+m_name+">");
1443}
1444
1445//----------------------
1446
1447QCString Definition::inbodyDocumentation() const
1448{
1449 makeResident();
1450 return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString("");
1451}
1452
1453int Definition::inbodyLine() const
1454{
1455 makeResident();
1456 return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1;
1457}
1458
1459QCString Definition::inbodyFile() const
1460{
1461 makeResident();
1462 return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_name+">");
1463}
1464
1465
1466//----------------------
1467
1468QCString Definition::getDefFileName() const
1469{
1470 makeResident();
1471 return m_impl->defFileName;
1472}
1473
1474QCString Definition::getDefFileExtension() const
1475{
1476 makeResident();
1477 return m_impl->defFileExt;
1478}
1479
1480int Definition::getDefLine() const
1481{
1482 makeResident();
1483 return m_impl->defLine;
1484}
1485
1486bool Definition::isHidden() const
1487{
1488 makeResident();
1489 return m_impl->hidden;
1490}
1491
1492bool Definition::isVisibleInProject() const
1493{
1494 return isLinkableInProject() && !m_impl->hidden;
1495}
1496
1497bool Definition::isVisible() const
1498{
1499 return isLinkable() && !m_impl->hidden;
1500}
1501
1502bool Definition::isArtificial() const
1503{
1504 return m_impl->isArtificial;
1505}
1506
1507QCString Definition::getReference() const
1508{
1509 makeResident();
1510 return m_impl->ref;
1511}
1512
1513bool Definition::isReference() const
1514{
1515 makeResident();
1516 return !m_impl->ref.isEmpty();
1517}
1518
1519int Definition::getStartBodyLine() const
1520{
1521 makeResident();
1522 return m_impl->body ? m_impl->body->startLine : -1;
1523}
1524
1525int Definition::getEndBodyLine() const
1526{
1527 makeResident();
1528 return m_impl->body ? m_impl->body->endLine : -1;
1529}
1530
1531FileDef *Definition::getBodyDef()
1532{
1533 makeResident();
1534 return m_impl->body ? m_impl->body->fileDef : 0;
1535}
1536
1537LockingPtr<GroupList> Definition::partOfGroups() const
1538{
1539 makeResident();
1540 return LockingPtr<GroupList>(this,m_impl->partOfGroups);
1541}
1542
1543Definition *Definition::getOuterScope() const
1544{
1545 makeResident();
1546 return m_impl->outerScope;
1547}
1548
1549LockingPtr<MemberSDict> Definition::getReferencesMembers() const
1550{
1551 makeResident();
1552 return LockingPtr<MemberSDict>(this,m_impl->sourceRefsDict);
1553}
1554
1555LockingPtr<MemberSDict> Definition::getReferencedByMembers() const
1556{
1557 makeResident();
1558 return LockingPtr<MemberSDict>(this,m_impl->sourceRefByDict);
1559}
1560
1561void Definition::setReference(const char *r)
1562{
1563 makeResident();
1564 m_impl->ref=r;
1565}
1566
1567void Definition::_setSymbolName(const QCString &name)
1568{
1569 m_symbolName=name;
1570}
1571
1572void Definition::setHidden(bool b)
1573{
1574 makeResident();
1575 m_impl->hidden = m_impl->hidden || b;
1576}
1577
1578void Definition::setArtificial(bool b)
1579{
1580 makeResident();
1581 m_impl->isArtificial = b;
1582}
1583
1584void Definition::setLocalName(const QCString name)
1585{
1586 makeResident();
1587 m_impl->localName=name;
1588}
1589
1590void Definition::makeResident() const
1591{
1592}
1593
1594
1595void Definition::flushToDisk() const
1596{
1597 //printf("%p: Definition::flushToDisk()\n",this);
1598 Definition *that = (Definition *)this;
1599 //printf("Definition::flushToDisk(): pos=%d\n",(int)m_storagePos);
1600 marshalUInt(Doxygen::symbolStorage,START_MARKER);
1601 marshalSectionDict (Doxygen::symbolStorage,m_impl->sectionDict);
1602 marshalMemberSDict (Doxygen::symbolStorage,m_impl->sourceRefByDict);
1603 marshalMemberSDict (Doxygen::symbolStorage,m_impl->sourceRefsDict);
1604 marshalItemInfoList (Doxygen::symbolStorage,m_impl->xrefListItems);
1605 marshalGroupList (Doxygen::symbolStorage,m_impl->partOfGroups);
1606 marshalDocInfo (Doxygen::symbolStorage,m_impl->details);
1607 marshalDocInfo (Doxygen::symbolStorage,m_impl->inbodyDocs);
1608 marshalBriefInfo (Doxygen::symbolStorage,m_impl->brief);
1609 marshalBodyInfo (Doxygen::symbolStorage,m_impl->body);
1610 marshalQCString (Doxygen::symbolStorage,m_impl->docSignatures);
1611 marshalQCString (Doxygen::symbolStorage,m_impl->localName);
1612 marshalQCString (Doxygen::symbolStorage,m_impl->qualifiedName);
1613 marshalQCString (Doxygen::symbolStorage,m_impl->ref);
1614 marshalBool (Doxygen::symbolStorage,m_impl->hidden);
1615 marshalBool (Doxygen::symbolStorage,m_impl->isArtificial);
1616 marshalObjPointer (Doxygen::symbolStorage,m_impl->outerScope);
1617 marshalQCString (Doxygen::symbolStorage,m_impl->defFileName);
1618 marshalInt (Doxygen::symbolStorage,m_impl->defLine);
1619 marshalQCString (Doxygen::symbolStorage,m_impl->defFileExt);
1620 marshalUInt(Doxygen::symbolStorage,END_MARKER);
1621 delete that->m_impl;
1622 that->m_impl = 0;
1623}
1624
1625void Definition::loadFromDisk() const
1626{
1627 //printf("%p: Definition::loadFromDisk()\n",this);
1628 Definition *that = (Definition *)this;
1629 assert(m_impl==0);
1630 that->m_impl = new DefinitionImpl;
1631 uint marker = unmarshalUInt(Doxygen::symbolStorage);
1632 assert(marker==START_MARKER);
1633 m_impl->sectionDict = unmarshalSectionDict (Doxygen::symbolStorage);
1634 m_impl->sourceRefByDict = unmarshalMemberSDict (Doxygen::symbolStorage);
1635 m_impl->sourceRefsDict = unmarshalMemberSDict (Doxygen::symbolStorage);
1636 m_impl->xrefListItems = unmarshalItemInfoList (Doxygen::symbolStorage);
1637 m_impl->partOfGroups = unmarshalGroupList (Doxygen::symbolStorage);
1638 m_impl->details = unmarshalDocInfo (Doxygen::symbolStorage);
1639 m_impl->inbodyDocs = unmarshalDocInfo (Doxygen::symbolStorage);
1640 m_impl->brief = unmarshalBriefInfo (Doxygen::symbolStorage);
1641 m_impl->body = unmarshalBodyInfo (Doxygen::symbolStorage);
1642 m_impl->docSignatures = unmarshalQCString (Doxygen::symbolStorage);
1643 m_impl->localName = unmarshalQCString (Doxygen::symbolStorage);
1644 m_impl->qualifiedName = unmarshalQCString (Doxygen::symbolStorage);
1645 m_impl->ref = unmarshalQCString (Doxygen::symbolStorage);
1646 m_impl->hidden = unmarshalBool (Doxygen::symbolStorage);
1647 m_impl->isArtificial = unmarshalBool (Doxygen::symbolStorage);
1648 m_impl->outerScope = (Definition *)unmarshalObjPointer (Doxygen::symbolStorage);
1649 m_impl->defFileName = unmarshalQCString (Doxygen::symbolStorage);
1650 m_impl->defLine = unmarshalInt (Doxygen::symbolStorage);
1651 m_impl->defFileExt = unmarshalQCString (Doxygen::symbolStorage);
1652 marker = unmarshalUInt(Doxygen::symbolStorage);
1653 assert(marker==END_MARKER);
1654}
1655
1656

Archive Download this file

Revision: 1322