definition.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  * Copyright (C) 1997-2015 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 <ctype.h>
19 #include <qregexp.h>
20 #include "md5.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include "config.h"
25 #include "definition.h"
26 #include "doxygen.h"
27 #include "language.h"
28 #include "message.h"
29 #include "outputlist.h"
30 #include "code.h"
31 #include "util.h"
32 #include "groupdef.h"
33 #include "pagedef.h"
34 #include "section.h"
35 #include "htags.h"
36 #include "parserintf.h"
37 #include "marshal.h"
38 #include "debug.h"
39 #include "vhdldocgen.h"
40 #include "memberlist.h"
41 #include "namespacedef.h"
42 #include "filedef.h"
43 #include "dirdef.h"
44 
45 #define START_MARKER 0x4445465B // DEF[
46 #define END_MARKER 0x4445465D // DEF]
47 
48 //-----------------------------------------------------------------------------------------
49 
50 
51 /** Private data associated with a Symbol Definition object. */
53 {
54  public:
57  void init(const char *df, const char *n);
58 
59  SectionDict *sectionDict; // dictionary of all sections, not accessible
60 
65 
66  DocInfo *details; // not exported
67  DocInfo *inbodyDocs; // not exported
68  BriefInfo *brief; // not exported
69  BodyInfo *body; // not exported
72 
73  QCString localName; // local (unqualified) name of the definition
74  // in the future m_name should become m_localName
76  QCString ref; // reference to external documentation
77 
78  bool hidden;
80 
81  Definition *outerScope; // not owner
82 
83  // where the item was found
86 
88 
89  QCString id; // clang unique id
90 };
91 
97 {
98 }
99 
101 {
102  delete sectionDict;
103  delete sourceRefByDict;
104  delete sourceRefsDict;
105  delete partOfGroups;
106  delete xrefListItems;
107  delete brief;
108  delete details;
109  delete body;
110  delete inbodyDocs;
111 }
112 
113 void DefinitionImpl::init(const char *df, const char *n)
114 {
115  defFileName = df;
116  int lastDot = defFileName.findRev('.');
117  if (lastDot!=-1)
118  {
119  defFileExt = defFileName.mid(lastDot);
120  }
121  QCString name = n;
122  if (name!="<globalScope>")
123  {
124  //extractNamespaceName(m_name,m_localName,ns);
126  }
127  else
128  {
129  localName=n;
130  }
131  //printf("m_localName=%s\n",m_localName.data());
132 
133  brief = 0;
134  details = 0;
135  body = 0;
136  inbodyDocs = 0;
137  sourceRefByDict = 0;
138  sourceRefsDict = 0;
139  sectionDict = 0,
141  partOfGroups = 0;
142  xrefListItems = 0;
143  hidden = FALSE;
146 }
147 
148 //-----------------------------------------------------------------------------------------
149 
150 static bool matchExcludedSymbols(const char *name)
151 {
152  static QStrList &exclSyms = Config_getList("EXCLUDE_SYMBOLS");
153  if (exclSyms.count()==0) return FALSE; // nothing specified
154  const char *pat = exclSyms.first();
155  QCString symName = name;
156  while (pat)
157  {
158  QCString pattern = pat;
159  bool forceStart=FALSE;
160  bool forceEnd=FALSE;
161  if (pattern.at(0)=='^')
162  pattern=pattern.mid(1),forceStart=TRUE;
163  if (pattern.at(pattern.length()-1)=='$')
164  pattern=pattern.left(pattern.length()-1),forceEnd=TRUE;
165  if (pattern.find('*')!=-1) // wildcard mode
166  {
167  QRegExp re(substitute(pattern,"*",".*"),TRUE);
168  int i,pl;
169  i = re.match(symName,0,&pl);
170  //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data());
171  if (i!=-1) // wildcard match
172  {
173  int sl=symName.length();
174  // check if it is a whole word match
175  if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) &&
176  (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd))
177  )
178  {
179  //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
180  return TRUE;
181  }
182  }
183  }
184  else if (!pattern.isEmpty()) // match words
185  {
186  int i = symName.find(pattern);
187  if (i!=-1) // we have a match!
188  {
189  int pl=pattern.length();
190  int sl=symName.length();
191  // check if it is a whole word match
192  if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) &&
193  (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd))
194  )
195  {
196  //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
197  return TRUE;
198  }
199  }
200  }
201  pat = exclSyms.next();
202  }
203  //printf("--> name=%s: no match\n",name);
204  return FALSE;
205 }
206 
208 {
209  bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
210  QCString symbolName = name;
211  int index=computeQualifiedIndex(symbolName);
212  if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
213  if (!symbolName.isEmpty())
214  {
215  //printf("******* adding symbol `%s' (%p)\n",symbolName.data(),d);
216  DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
217  //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di);
218  if (di==0) // new Symbol
219  {
220  //printf(" new symbol!\n");
221  Doxygen::symbolMap->insert(symbolName,d);
222  }
223  else // existing symbol
224  {
225  //printf(" existing symbol: ");
226  if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols
227  {
228  //printf("adding to exiting list\n");
229  DefinitionList *dl = (DefinitionList*)di;
230  dl->append(d);
231  }
232  else // going from one to two symbols
233  {
234  Doxygen::symbolMap->take(symbolName);
235  DefinitionList *dl = new DefinitionList;
236  //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d);
237  dl->append((Definition*)di);
238  dl->append(d);
239  Doxygen::symbolMap->insert(symbolName,dl);
240  }
241  }
242 
243  // auto resize if needed
244  static int sizeIndex=9;
245  if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex])
246  {
247  Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]);
248  }
249 
250  d->_setSymbolName(symbolName);
251  }
252 }
253 
255 {
256  QCString symbolName = d->m_symbolName;
257  if (!symbolName.isEmpty())
258  {
259  //printf("******* removing symbol `%s' (%p)\n",symbolName.data(),d);
260  DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
261  if (di)
262  {
263  if (di!=d) // symbolName not unique
264  {
265  //printf(" removing from list: %p!\n",di);
266  DefinitionList *dl = (DefinitionList*)di;
267  bool b = dl->removeRef(d);
268  ASSERT(b==TRUE);
269  if (dl->isEmpty())
270  {
271  Doxygen::symbolMap->take(symbolName);
272  }
273  }
274  else // symbolName unique
275  {
276  //printf(" removing symbol %p\n",di);
277  Doxygen::symbolMap->take(symbolName);
278  }
279  }
280  }
281 }
282 
283 Definition::Definition(const char *df,int dl,int dc,
284  const char *name,const char *b,
285  const char *d,bool isSymbol) : m_cookie(0)
286 {
287  m_name = name;
288  m_defLine = dl;
289  m_defColumn = dc;
290  m_impl = new DefinitionImpl;
291  m_impl->init(df,name);
292  m_isSymbol = isSymbol;
293  if (isSymbol) addToMap(name,this);
294  _setBriefDescription(b,df,dl);
295  _setDocumentation(d,df,dl,TRUE,FALSE);
296  if (matchExcludedSymbols(name))
297  {
298  m_impl->hidden = TRUE;
299  }
300 }
301 
303 {
304  m_name = d.m_name;
305  m_defLine = d.m_defLine;
306  m_impl = new DefinitionImpl;
307  *m_impl = *d.m_impl;
308  m_impl->sectionDict = 0;
309  m_impl->sourceRefByDict = 0;
310  m_impl->sourceRefsDict = 0;
311  m_impl->partOfGroups = 0;
312  m_impl->xrefListItems = 0;
313  m_impl->brief = 0;
314  m_impl->details = 0;
315  m_impl->body = 0;
316  m_impl->inbodyDocs = 0;
317  if (d.m_impl->sectionDict)
318  {
319  m_impl->sectionDict = new SectionDict(17);
321  SectionInfo *si;
322  for (it.toFirst();(si=it.current());++it)
323  {
324  m_impl->sectionDict->append(si->label,si);
325  }
326  }
327  if (d.m_impl->sourceRefByDict)
328  {
331  MemberDef *md;
332  for (it.toFirst();(md=it.current());++it)
333  {
334  m_impl->sourceRefByDict->append(it.currentKey(),md);
335  }
336  }
337  if (d.m_impl->sourceRefsDict)
338  {
341  MemberDef *md;
342  for (it.toFirst();(md=it.current());++it)
343  {
344  m_impl->sourceRefsDict->append(it.currentKey(),md);
345  }
346  }
347  if (d.m_impl->partOfGroups)
348  {
350  GroupDef *gd;
351  for (it.toFirst();(gd=it.current());++it)
352  {
353  makePartOfGroup(gd);
354  }
355  }
356  if (d.m_impl->xrefListItems)
357  {
359  }
360  if (d.m_impl->brief)
361  {
362  m_impl->brief = new BriefInfo(*d.m_impl->brief);
363  }
364  if (d.m_impl->details)
365  {
366  m_impl->details = new DocInfo(*d.m_impl->details);
367  }
368  if (d.m_impl->body)
369  {
370  m_impl->body = new BodyInfo(*d.m_impl->body);
371  }
372  if (d.m_impl->inbodyDocs)
373  {
375  }
376 
378  if (m_isSymbol) addToMap(m_name,this);
379 }
380 
382 {
383  if (m_isSymbol)
384  {
385  removeFromMap(this);
386  }
387  if (m_impl)
388  {
389  delete m_impl;
390  m_impl=0;
391  }
392  delete m_cookie;
393  m_cookie=0;
394 }
395 
396 void Definition::setName(const char *name)
397 {
398  if (name==0) return;
399  m_name = name;
400 }
401 
402 void Definition::setId(const char *id)
403 {
404  if (id==0) return;
405  m_impl->id = id;
407  {
408  //printf("Definition::setId '%s'->'%s'\n",id,m_name.data());
409  Doxygen::clangUsrMap->insert(id,this);
410  }
411 }
412 
414 {
415  return m_impl->id;
416 }
417 
419 {
420  if (!anchorList) return;
421  //printf("%s: addSectionsToDefinition(%d)\n",name().data(),anchorList->count());
422  QListIterator<SectionInfo> it(*anchorList);
423  SectionInfo *si;
424  for (;(si=it.current());++it)
425  {
426  //printf("Add section `%s' to definition `%s'\n",
427  // si->label.data(),name().data());
429  //printf("===== label=%s gsi=%p\n",si->label.data(),gsi);
430  if (gsi==0)
431  {
432  gsi = new SectionInfo(*si);
434  }
435  if (m_impl->sectionDict==0)
436  {
437  m_impl->sectionDict = new SectionDict(17);
438  }
439  if (m_impl->sectionDict->find(gsi->label)==0)
440  {
441  m_impl->sectionDict->append(gsi->label,gsi);
442  gsi->definition = this;
443  }
444  }
445 }
446 
448 {
449  //printf("Definition::hasSections(%s) #sections=%d\n",name().data(),
450  // m_impl->sectionDict ? m_impl->sectionDict->count() : 0);
451  if (m_impl->sectionDict==0) return FALSE;
453  SectionInfo *si;
454  for (li.toFirst();(si=li.current());++li)
455  {
456  if (si->type==SectionInfo::Section ||
460  {
461  return TRUE;
462  }
463  }
464  return FALSE;
465 }
466 
468 {
469  if (m_impl->sectionDict==0) return;
470  //printf("Definition::addSectionsToIndex()\n");
472  SectionInfo *si;
473  int level=1;
474  for (li.toFirst();(si=li.current());++li)
475  {
476  if (si->type==SectionInfo::Section ||
480  {
481  //printf(" level=%d title=%s\n",level,si->title.data());
482  int nextLevel = (int)si->type;
483  int i;
484  if (nextLevel>level)
485  {
486  for (i=level;i<nextLevel;i++)
487  {
489  }
490  }
491  else if (nextLevel<level)
492  {
493  for (i=nextLevel;i<level;i++)
494  {
496  }
497  }
498  QCString title = si->title;
499  if (title.isEmpty()) title = si->label;
500  // determine if there is a next level inside this item
501  ++li;
502  bool isDir = ((li.current()) ? (int)(li.current()->type > nextLevel):FALSE);
503  --li;
504  Doxygen::indexList->addContentsItem(isDir,title,
505  getReference(),
507  si->label,
508  FALSE,
509  TRUE);
510  level = nextLevel;
511  }
512  }
513  while (level>1)
514  {
516  level--;
517  }
518 }
519 
521 {
522  if (m_impl->sectionDict)
523  {
524  //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionDict->count());
526  SectionInfo *si;
527  for (;(si=sdi.current());++sdi)
528  {
529  if (!si->generated)
530  {
531  //printf("write an entry!\n");
532  if (definitionType()==TypeMember) tagFile << " ";
533  tagFile << " <docanchor file=\"" << si->fileName << "\"";
534  if (!si->title.isEmpty())
535  {
536  tagFile << " title=\"" << convertToXML(si->title) << "\"";
537  }
538  tagFile << ">" << si->label << "</docanchor>" << endl;
539  }
540  }
541  }
542 }
543 
545 {
546  uchar md5_sig[16];
547  QCString sigStr(33);
548  // to avoid mismatches due to differences in indenting, we first remove
549  // double whitespaces...
550  QCString docStr = doc.simplifyWhiteSpace();
551  MD5Buffer((const unsigned char *)docStr.data(),docStr.length(),md5_sig);
552  MD5SigToString(md5_sig,sigStr.rawData(),33);
553  //printf("%s:_docsAlreadyAdded doc='%s' sig='%s' docSigs='%s'\n",
554  // name().data(),doc.data(),sigStr.data(),sigList.data());
555  if (sigList.find(sigStr)==-1) // new docs, add signature to prevent re-adding it
556  {
557  sigList+=":"+sigStr;
558  return FALSE;
559  }
560  else
561  {
562  return TRUE;
563  }
564 }
565 
566 void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,
567  bool stripWhiteSpace,bool atTop)
568 {
569  //printf("%s::setDocumentation(%s,%s,%d,%d)\n",name().data(),d,docFile,docLine,stripWhiteSpace);
570  if (d==0) return;
571  QCString doc = d;
572  if (stripWhiteSpace)
573  {
574  doc = stripLeadingAndTrailingEmptyLines(doc,docLine);
575  }
576  else // don't strip whitespace
577  {
578  doc=d;
579  }
581  {
582  //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data());
583  if (m_impl->details==0)
584  {
585  m_impl->details = new DocInfo;
586  }
587  if (m_impl->details->doc.isEmpty()) // fresh detailed description
588  {
589  m_impl->details->doc = doc;
590  }
591  else if (atTop) // another detailed description, append it to the start
592  {
593  m_impl->details->doc = doc+"\n\n"+m_impl->details->doc;
594  }
595  else // another detailed description, append it to the end
596  {
597  m_impl->details->doc += "\n\n"+doc;
598  }
599  if (docLine!=-1) // store location if valid
600  {
603  }
604  else
605  {
607  m_impl->details->line = 1;
608  }
609  }
610 }
611 
612 void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
613 {
614  if (d==0) return;
615  _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE);
616 }
617 
618 #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase)
619 
620 // do a UTF-8 aware search for the last real character and return TRUE
621 // if that is a multibyte one.
622 static bool lastCharIsMultibyte(const QCString &s)
623 {
624  int l = s.length();
625  int p = 0;
626  int pp = -1;
627  while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p;
628  if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE;
629  return TRUE;
630 }
631 
632 void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine)
633 {
634  static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE");
635  static bool needsDot = outputLanguage!="Japanese" &&
636  outputLanguage!="Chinese" &&
637  outputLanguage!="Korean";
638  QCString brief = b;
639  brief = brief.stripWhiteSpace();
640  if (brief.isEmpty()) return;
641  int bl = brief.length();
642  if (bl>0 && needsDot) // add punctuation if needed
643  {
644  int c = brief.at(bl-1);
645  switch(c)
646  {
647  case '.': case '!': case '?': case '>': case ':': case ')': break;
648  default:
649  if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.';
650  break;
651  }
652  }
653 
655  {
656  if (m_impl->brief && !m_impl->brief->doc.isEmpty())
657  {
658  //printf("adding to details\n");
659  _setDocumentation(brief,briefFile,briefLine,FALSE,TRUE);
660  }
661  else
662  {
663  //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine);
664  if (m_impl->brief==0)
665  {
666  m_impl->brief = new BriefInfo;
667  }
668  m_impl->brief->doc=brief;
669  if (briefLine!=-1)
670  {
673  }
674  else
675  {
677  m_impl->brief->line = 1;
678  }
679  }
680  }
681  else
682  {
683  //printf("do nothing!\n");
684  }
685 }
686 
687 void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine)
688 {
689  if (b==0) return;
690  _setBriefDescription(b,briefFile,briefLine);
691 }
692 
694 {
695  if (m_impl->inbodyDocs==0)
696  {
697  m_impl->inbodyDocs = new DocInfo;
698  }
699  if (m_impl->inbodyDocs->doc.isEmpty()) // fresh inbody docs
700  {
701  m_impl->inbodyDocs->doc = doc;
704  }
705  else // another inbody documentation fragment, append this to the end
706  {
707  m_impl->inbodyDocs->doc += QCString("\n\n")+doc;
708  }
709 }
710 
712 {
713  if (d==0) return;
714  _setInbodyDocumentation(d,inbodyFile,inbodyLine);
715 }
716 
717 /*! Reads a fragment of code from file \a fileName starting at
718  * line \a startLine and ending at line \a endLine (inclusive). The fragment is
719  * stored in \a result. If FALSE is returned the code fragment could not be
720  * found.
721  *
722  * The file is scanned for a opening bracket ('{') from \a startLine onward
723  * The line actually containing the bracket is returned via startLine.
724  * The file is scanned for a closing bracket ('}') from \a endLine backward.
725  * The line actually containing the bracket is returned via endLine.
726  * Note that for VHDL code the bracket search is not done.
727  */
728 bool readCodeFragment(const char *fileName,
729  int &startLine,int &endLine,QCString &result)
730 {
731  static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
732  static int tabSize = Config_getInt("TAB_SIZE");
733  //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine);
734  if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name
735  QCString filter = getFileFilter(fileName,TRUE);
736  FILE *f=0;
737  bool usePipe = !filter.isEmpty() && filterSourceFiles;
738  SrcLangExt lang = getLanguageFromFileName(fileName);
739  if (!usePipe) // no filter given or wanted
740  {
741  f = portable_fopen(fileName,"r");
742  }
743  else // use filter
744  {
745  QCString cmd=filter+" \""+fileName+"\"";
746  Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
747  f = portable_popen(cmd,"r");
748  }
749  bool found = lang==SrcLangExt_VHDL ||
750  lang==SrcLangExt_Tcl ||
751  lang==SrcLangExt_Python ||
752  lang==SrcLangExt_Fortran;
753  // for VHDL, TCL, Python, and Fortran no bracket search is possible
754  if (f)
755  {
756  int c=0;
757  int col=0;
758  int lineNr=1;
759  // skip until the startLine has reached
760  while (lineNr<startLine && !feof(f))
761  {
762  while ((c=fgetc(f))!='\n' && c!=EOF) /* skip */;
763  lineNr++;
764  if (found && c == '\n') c = '\0';
765  }
766  if (!feof(f))
767  {
768  // skip until the opening bracket or lonely : is found
769  char cn=0;
770  while (lineNr<=endLine && !feof(f) && !found)
771  {
772  int pc=0;
773  while ((c=fgetc(f))!='{' && c!=':' && c!=EOF) // } so vi matching brackets has no problem
774  {
775  //printf("parsing char `%c'\n",c);
776  if (c=='\n')
777  {
778  lineNr++,col=0;
779  }
780  else if (c=='\t')
781  {
782  col+=tabSize - (col%tabSize);
783  }
784  else if (pc=='/' && c=='/') // skip single line comment
785  {
786  while ((c=fgetc(f))!='\n' && c!=EOF) pc=c;
787  if (c=='\n') lineNr++,col=0;
788  }
789  else if (pc=='/' && c=='*') // skip C style comment
790  {
791  while (((c=fgetc(f))!='/' || pc!='*') && c!=EOF)
792  {
793  if (c=='\n') lineNr++,col=0;
794  pc=c;
795  }
796  }
797  else
798  {
799  col++;
800  }
801  pc = c;
802  }
803  if (c==':')
804  {
805  cn=fgetc(f);
806  if (cn!=':') found=TRUE;
807  }
808  else if (c=='{') // } so vi matching brackets has no problem
809  {
810  found=TRUE;
811  }
812  }
813  //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr);
814  if (found)
815  {
816  // For code with more than one line,
817  // fill the line with spaces until we are at the right column
818  // so that the opening brace lines up with the closing brace
819  if (endLine!=startLine)
820  {
821  QCString spaces;
822  spaces.fill(' ',col);
823  result+=spaces;
824  }
825  // copy until end of line
826  if (c) result+=c;
827  startLine=lineNr;
828  if (c==':')
829  {
830  result+=cn;
831  if (cn=='\n') lineNr++;
832  }
833  const int maxLineLength=4096;
834  char lineStr[maxLineLength];
835  do
836  {
837  //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine);
838  int size_read;
839  do
840  {
841  // read up to maxLineLength-1 bytes, the last byte being zero
842  char *p = fgets(lineStr, maxLineLength,f);
843  //printf(" read %s",p);
844  if (p)
845  {
846  size_read=qstrlen(p);
847  }
848  else // nothing read
849  {
850  size_read=-1;
851  lineStr[0]='\0';
852  }
853  result+=lineStr;
854  } while (size_read == (maxLineLength-1));
855 
856  lineNr++;
857  } while (lineNr<=endLine && !feof(f));
858 
859  // strip stuff after closing bracket
860  int newLineIndex = result.findRev('\n');
861  int braceIndex = result.findRev('}');
862  if (braceIndex > newLineIndex)
863  {
864  result.truncate(braceIndex+1);
865  }
866  endLine=lineNr-1;
867  }
868  }
869  if (usePipe)
870  {
871  portable_pclose(f);
872  Debug::print(Debug::FilterOutput, 0, "Filter output\n");
873  Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",qPrint(result));
874  }
875  else
876  {
877  fclose(f);
878  }
879  }
880  result = transcodeCharacterStringToUTF8(result);
881  //fprintf(stderr,"readCodeFragement(%d-%d)=%s\n",startLine,endLine,result.data());
882  return found;
883 }
884 
886 {
887  ASSERT(definitionType()!=Definition::TypeFile); // file overloads this method
888  QCString fn;
889  static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
890  if (sourceBrowser &&
892  {
894  }
895  return fn;
896 }
897 
899 {
900  const int maxAnchorStrLen = 20;
901  char anchorStr[maxAnchorStrLen];
902  anchorStr[0]='\0';
903  if (m_impl->body && m_impl->body->startLine!=-1)
904  {
905  if (Htags::useHtags)
906  {
907  qsnprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->startLine);
908  }
909  else
910  {
911  qsnprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->startLine);
912  }
913  }
914  return anchorStr;
915 }
916 
917 /*! Write a reference to the source code defining this definition */
919 {
920  static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
921  static bool rtfSourceCode = Config_getBool("RTF_SOURCE_CODE");
922  ol.pushGeneratorState();
923  //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef);
925  if (!fn.isEmpty())
926  {
928  int lineMarkerPos = refText.find("@0");
929  int fileMarkerPos = refText.find("@1");
930  if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this.
931  {
932  QCString lineStr;
933  lineStr.sprintf("%d",m_impl->body->startLine);
934  QCString anchorStr = getSourceAnchor();
935  ol.startParagraph();
936  if (lineMarkerPos<fileMarkerPos) // line marker before file marker
937  {
938  // write text left from linePos marker
939  ol.parseText(refText.left(lineMarkerPos));
940  ol.pushGeneratorState();
942  if (!latexSourceCode)
943  {
945  }
946  if (!rtfSourceCode)
947  {
949  }
950  // write line link (HTML, LaTeX optionally, RTF optionally)
951  ol.writeObjectLink(0,fn,anchorStr,lineStr);
952  ol.enableAll();
954  if (latexSourceCode)
955  {
957  }
958  if (rtfSourceCode)
959  {
961  }
962  // write normal text (Man, Latex optionally, RTF optionally)
963  ol.docify(lineStr);
964  ol.popGeneratorState();
965 
966  // write text between markers
967  ol.parseText(refText.mid(lineMarkerPos+2,
968  fileMarkerPos-lineMarkerPos-2));
969 
970  ol.pushGeneratorState();
972  if (!latexSourceCode)
973  {
975  }
976  if (!rtfSourceCode)
977  {
979  }
980  // write file link (HTML, LaTeX optionally, RTF optionally)
981  ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name());
982  ol.enableAll();
984  if (latexSourceCode)
985  {
987  }
988  if (rtfSourceCode)
989  {
991  }
992  // write normal text (Man, Latex optionally, RTF optionally)
993  ol.docify(m_impl->body->fileDef->name());
994  ol.popGeneratorState();
995 
996  // write text right from file marker
997  ol.parseText(refText.right(
998  refText.length()-fileMarkerPos-2));
999  }
1000  else // file marker before line marker
1001  {
1002  // write text left from file marker
1003  ol.parseText(refText.left(fileMarkerPos));
1004  ol.pushGeneratorState();
1006  if (!latexSourceCode)
1007  {
1009  }
1010  if (!rtfSourceCode)
1011  {
1013  }
1014  // write file link (HTML only)
1015  ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name());
1016  ol.enableAll();
1018  if (latexSourceCode)
1019  {
1021  }
1022  if (rtfSourceCode)
1023  {
1025  }
1026  // write normal text (RTF/Latex/Man only)
1027  ol.docify(m_impl->body->fileDef->name());
1028  ol.popGeneratorState();
1029 
1030  // write text between markers
1031  ol.parseText(refText.mid(fileMarkerPos+2,
1032  lineMarkerPos-fileMarkerPos-2));
1033 
1034  ol.pushGeneratorState();
1036  if (!latexSourceCode)
1037  {
1039  }
1040  if (!rtfSourceCode)
1041  {
1043  }
1045  // write line link (HTML only)
1046  ol.writeObjectLink(0,fn,anchorStr,lineStr);
1047  ol.enableAll();
1049  if (latexSourceCode)
1050  {
1052  }
1053  if (rtfSourceCode)
1054  {
1056  }
1057  // write normal text (Latex/Man only)
1058  ol.docify(lineStr);
1059  ol.popGeneratorState();
1060 
1061  // write text right from linePos marker
1062  ol.parseText(refText.right(
1063  refText.length()-lineMarkerPos-2));
1064  }
1065  ol.endParagraph();
1066  }
1067  else
1068  {
1069  err("translation error: invalid markers in trDefinedInSourceFile()\n");
1070  }
1071  }
1072  ol.popGeneratorState();
1073 }
1074 
1075 void Definition::setBodySegment(int bls,int ble)
1076 {
1077  //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data());
1078  if (m_impl->body==0) m_impl->body = new BodyInfo;
1079  m_impl->body->startLine=bls;
1080  m_impl->body->endLine=ble;
1081 }
1082 
1084 {
1085  if (m_impl->body==0) m_impl->body = new BodyInfo;
1086  m_impl->body->fileDef=fd;
1087 }
1088 
1090 {
1091  return m_impl->body && m_impl->body->startLine!=-1 &&
1093  m_impl->body->fileDef;
1094 }
1095 
1096 /*! Write code of this definition into the documentation */
1097 void Definition::writeInlineCode(OutputList &ol,const char *scopeName)
1098 {
1099  static bool inlineSources = Config_getBool("INLINE_SOURCES");
1100  ol.pushGeneratorState();
1101  //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(),
1102  // m_startBodyLine,m_endBodyLine,m_bodyDef);
1103  if (inlineSources && hasSources())
1104  {
1105  QCString codeFragment;
1106  int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine;
1108  actualStart,actualEnd,codeFragment)
1109  )
1110  {
1111  //printf("Adding code fragement '%s' ext='%s'\n",
1112  // codeFragment.data(),m_impl->defFileExt.data());
1114  pIntf->resetCodeParserState();
1115  //printf("Read:\n`%s'\n\n",codeFragment.data());
1116  MemberDef *thisMd = 0;
1117  if (definitionType()==TypeMember) thisMd = (MemberDef *)this;
1118 
1119  ol.startCodeFragment();
1120  pIntf->parseCode(ol, // codeOutIntf
1121  scopeName, // scope
1122  codeFragment, // input
1123  m_impl->lang, // lang
1124  FALSE, // isExample
1125  0, // exampleName
1126  m_impl->body->fileDef, // fileDef
1127  actualStart, // startLine
1128  actualEnd, // endLine
1129  TRUE, // inlineFragment
1130  thisMd, // memberDef
1131  TRUE // show line numbers
1132  );
1133  ol.endCodeFragment();
1134  }
1135  }
1136  ol.popGeneratorState();
1137 }
1138 
1139 /*! Write a reference to the source code fragments in which this
1140  * definition is used.
1141  */
1142 void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
1143  const QCString &text,MemberSDict *members,bool /*funcOnly*/)
1144 {
1145  static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
1146  static bool rtfSourceCode = Config_getBool("RTF_SOURCE_CODE");
1147  static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1148  static bool refLinkSource = Config_getBool("REFERENCES_LINK_SOURCE");
1149  ol.pushGeneratorState();
1150  if (members)
1151  {
1152  members->sort();
1153 
1154  ol.startParagraph();
1155  ol.parseText(text);
1156  ol.docify(" ");
1157 
1158  QCString ldefLine=theTranslator->trWriteList(members->count());
1159 
1160  QRegExp marker("@[0-9]+");
1161  int index=0,newIndex,matchLen;
1162  // now replace all markers in inheritLine with links to the classes
1163  while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1)
1164  {
1165  bool ok;
1166  ol.parseText(ldefLine.mid(index,newIndex-index));
1167  uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1168  MemberDef *md=members->at(entryIndex);
1169  if (ok && md)
1170  {
1172  QCString name=md->name();
1173  //printf("class=%p scope=%s scopeName=%s\n",md->getClassDef(),scope.data(),scopeName);
1174  if (!scope.isEmpty() && scope!=scopeName)
1175  {
1177  }
1178  if (!md->isObjCMethod() &&
1179  (md->isFunction() || md->isSlot() ||
1180  md->isPrototype() || md->isSignal()
1181  )
1182  )
1183  {
1184  name+="()";
1185  }
1186  //Definition *d = md->getOutputFileBase();
1187  //if (d==Doxygen::globalScope) d=md->getBodyDef();
1188  if (sourceBrowser &&
1189  !(md->isLinkable() && !refLinkSource) &&
1190  md->getStartBodyLine()!=-1 &&
1191  md->getBodyDef()
1192  )
1193  {
1194  //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope);
1195  // for HTML write a real link
1196  ol.pushGeneratorState();
1197  //ol.disableAllBut(OutputGenerator::Html);
1198 
1200  if (!latexSourceCode)
1201  {
1203  }
1204  if (!rtfSourceCode)
1205  {
1207  }
1208  const int maxLineNrStr = 10;
1209  char anchorStr[maxLineNrStr];
1210  qsnprintf(anchorStr,maxLineNrStr,"l%05d",md->getStartBodyLine());
1211  //printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data());
1212  ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name);
1213  ol.popGeneratorState();
1214 
1215  // for the other output formats just mention the name
1216  ol.pushGeneratorState();
1218  if (latexSourceCode)
1219  {
1221  }
1222  if (rtfSourceCode)
1223  {
1225  }
1226  ol.docify(name);
1227  ol.popGeneratorState();
1228  }
1229  else if (md->isLinkable() /*&& d && d->isLinkable()*/)
1230  {
1231  // for HTML write a real link
1232  ol.pushGeneratorState();
1233  //ol.disableAllBut(OutputGenerator::Html);
1235  if (!latexSourceCode)
1236  {
1238  }
1239  if (!rtfSourceCode)
1240  {
1242  }
1243 
1244  ol.writeObjectLink(md->getReference(),
1245  md->getOutputFileBase(),
1246  md->anchor(),name);
1247  ol.popGeneratorState();
1248 
1249  // for the other output formats just mention the name
1250  ol.pushGeneratorState();
1252  if (latexSourceCode)
1253  {
1255  }
1256  if (rtfSourceCode)
1257  {
1259  }
1260  ol.docify(name);
1261  ol.popGeneratorState();
1262  }
1263  else
1264  {
1265  ol.docify(name);
1266  }
1267  }
1268  index=newIndex+matchLen;
1269  }
1270  ol.parseText(ldefLine.right(ldefLine.length()-index));
1271  ol.writeString(".");
1272  ol.endParagraph();
1273  }
1274  ol.popGeneratorState();
1275 }
1276 
1277 void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName)
1278 {
1279  if (Config_getBool("REFERENCED_BY_RELATION"))
1280  {
1282  }
1283 }
1284 
1285 void Definition::writeSourceRefs(OutputList &ol,const char *scopeName)
1286 {
1287  if (Config_getBool("REFERENCES_RELATION"))
1288  {
1290  }
1291 }
1292 
1294 {
1295  static bool extractAll = Config_getBool("EXTRACT_ALL");
1296  //static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1297  bool hasDocs =
1298  (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs
1299  (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description
1300  (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty()) || // has inbody docs
1301  extractAll //|| // extract everything
1302  // (sourceBrowser && m_impl->body &&
1303  // m_impl->body->startLine!=-1 && m_impl->body->fileDef)
1304  ; // link to definition
1305  return hasDocs;
1306 }
1307 
1309 {
1310  bool hasDocs =
1311  (m_impl->details && !m_impl->details->doc.isEmpty()) ||
1312  (m_impl->brief && !m_impl->brief->doc.isEmpty()) ||
1314  return hasDocs;
1315 }
1316 
1317 
1319 {
1320  if (md)
1321  {
1322  QCString name = md->name();
1323  QCString scope = md->getScopeString();
1324 
1325  if (!scope.isEmpty())
1326  {
1327  name.prepend(scope+"::");
1328  }
1329 
1330  if (m_impl->sourceRefByDict==0)
1331  {
1333  }
1334  if (m_impl->sourceRefByDict->find(name)==0)
1335  {
1336  m_impl->sourceRefByDict->append(name,md);
1337  }
1338  }
1339 }
1340 
1342 {
1343  if (md)
1344  {
1345  QCString name = md->name();
1346  QCString scope = md->getScopeString();
1347 
1348  if (!scope.isEmpty())
1349  {
1350  name.prepend(scope+"::");
1351  }
1352 
1353  if (m_impl->sourceRefsDict==0)
1354  {
1356  }
1357  if (m_impl->sourceRefsDict->find(name)==0)
1358  {
1359  m_impl->sourceRefsDict->append(name,md);
1360  }
1361  }
1362 }
1363 
1365 {
1366  return 0;
1367 }
1368 
1370 {
1371  err("Definition::addInnerCompound() called\n");
1372 }
1373 
1375 {
1376  //static int count=0;
1377  //count++;
1378  if (!m_impl->qualifiedName.isEmpty())
1379  {
1380  //count--;
1381  return m_impl->qualifiedName;
1382  }
1383 
1384  //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data());
1385  if (m_impl->outerScope==0)
1386  {
1387  if (m_impl->localName=="<globalScope>")
1388  {
1389  //count--;
1390  return "";
1391  }
1392  else
1393  {
1394  //count--;
1395  return m_impl->localName;
1396  }
1397  }
1398 
1399  if (m_impl->outerScope->name()=="<globalScope>")
1400  {
1402  }
1403  else
1404  {
1407  m_impl->localName;
1408  }
1409  //printf("end %s::qualifiedName()=%s\n",name().data(),m_impl->qualifiedName.data());
1410  //count--;
1411  return m_impl->qualifiedName;
1412 }
1413 
1415 {
1416  //printf("%s::setOuterScope(%s)\n",name().data(),d?d->name().data():"<none>");
1418  bool found=false;
1419  // make sure that we are not creating a recursive scope relation.
1420  while (p && !found)
1421  {
1422  found = (p==d);
1423  p = p->m_impl->outerScope;
1424  }
1425  if (!found)
1426  {
1427  m_impl->qualifiedName.resize(0); // flush cached scope name
1428  m_impl->outerScope = d;
1429  }
1430  m_impl->hidden = m_impl->hidden || d->isHidden();
1431 }
1432 
1434 {
1435  return m_impl->localName;
1436 }
1437 
1439 {
1441  m_impl->partOfGroups->append(gd);
1442 }
1443 
1445 {
1446  //printf("%s::setRefItems()\n",name().data());
1447  if (sli)
1448  {
1449  // deep copy the list
1450  if (m_impl->xrefListItems==0)
1451  {
1454  }
1455  QListIterator<ListItemInfo> slii(*sli);
1456  ListItemInfo *lii;
1457  for (slii.toFirst();(lii=slii.current());++slii)
1458  {
1459  m_impl->xrefListItems->append(new ListItemInfo(*lii));
1460  }
1461  }
1462 }
1463 
1465 {
1466  //printf("%s::mergeRefItems()\n",name().data());
1467  QList<ListItemInfo> *xrefList = d->xrefListItems();
1468  if (xrefList!=0)
1469  {
1470  // deep copy the list
1471  if (m_impl->xrefListItems==0)
1472  {
1475  }
1476  QListIterator<ListItemInfo> slii(*xrefList);
1477  ListItemInfo *lii;
1478  for (slii.toFirst();(lii=slii.current());++slii)
1479  {
1480  if (_getXRefListId(lii->type)==-1)
1481  {
1482  m_impl->xrefListItems->append(new ListItemInfo(*lii));
1483  }
1484  }
1485  }
1486 }
1487 
1488 int Definition::_getXRefListId(const char *listName) const
1489 {
1490  if (m_impl->xrefListItems)
1491  {
1493  ListItemInfo *lii;
1494  for (slii.toFirst();(lii=slii.current());++slii)
1495  {
1496  if (qstrcmp(lii->type,listName)==0)
1497  {
1498  return lii->itemId;
1499  }
1500  }
1501  }
1502  return -1;
1503 }
1504 
1506 {
1507  return m_impl->xrefListItems;
1508 }
1509 
1510 
1511 QCString Definition::convertNameToFile(const char *name,bool allowDots) const
1512 {
1513  if (!m_impl->ref.isEmpty())
1514  {
1515  return name;
1516  }
1517  else
1518  {
1519  return ::convertNameToFile(name,allowDots);
1520  }
1521 }
1522 
1524 {
1525  QCString result;
1527  {
1528  result = m_impl->outerScope->pathFragment();
1529  }
1530  if (isLinkable())
1531  {
1532  if (!result.isEmpty()) result+="/";
1533  if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
1534  {
1535  result+=((const GroupDef*)this)->groupTitle();
1536  }
1537  else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
1538  {
1539  result+=((const PageDef*)this)->title();
1540  }
1541  else
1542  {
1543  result+=m_impl->localName;
1544  }
1545  }
1546  else
1547  {
1548  result+=m_impl->localName;
1549  }
1550  return result;
1551 }
1552 
1553 //----------------------------------------------------------------------------------------
1554 
1555 // TODO: move to htmlgen
1556 /*! Returns the string used in the footer for $navpath when
1557  * GENERATE_TREEVIEW is enabled
1558  */
1560 {
1561  QCString result;
1562  Definition *outerScope = getOuterScope();
1563  QCString locName = localName();
1564  if (outerScope && outerScope!=Doxygen::globalScope)
1565  {
1566  result+=outerScope->navigationPathAsString();
1567  }
1568  else if (definitionType()==Definition::TypeFile && ((const FileDef*)this)->getDirDef())
1569  {
1570  result+=((const FileDef*)this)->getDirDef()->navigationPathAsString();
1571  }
1572  result+="<li class=\"navelem\">";
1573  if (isLinkable())
1574  {
1575  if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
1576  {
1577  result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
1578  convertToHtml(((const GroupDef*)this)->groupTitle())+"</a>";
1579  }
1580  else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
1581  {
1582  result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
1583  convertToHtml(((const PageDef*)this)->title())+"</a>";
1584  }
1586  {
1587  QCString name = locName;
1588  if (name.right(2)=="-p" /*|| name.right(2)=="-g"*/)
1589  {
1590  name = name.left(name.length()-2);
1591  }
1592  result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension;
1593  if (!anchor().isEmpty()) result+="#"+anchor();
1594  result+="\">"+convertToHtml(name)+"</a>";
1595  }
1596  else
1597  {
1598  result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
1599  convertToHtml(locName)+"</a>";
1600  }
1601  }
1602  else
1603  {
1604  result+="<b>"+convertToHtml(locName)+"</b>";
1605  }
1606  result+="</li>";
1607  return result;
1608 }
1609 
1610 // TODO: move to htmlgen
1612 {
1613  ol.pushGeneratorState();
1615 
1616  QCString navPath;
1617  navPath += "<div id=\"nav-path\" class=\"navpath\">\n"
1618  " <ul>\n";
1619  navPath += navigationPathAsString();
1620  navPath += " </ul>\n"
1621  "</div>\n";
1622  ol.writeNavigationPath(navPath);
1623 
1624  ol.popGeneratorState();
1625 }
1626 
1627 // TODO: move to htmlgen
1629 {
1630  SectionDict *sectionDict = m_impl->sectionDict;
1631  if (sectionDict==0) return;
1632  ol.pushGeneratorState();
1634  ol.writeString("<div class=\"toc\">");
1635  ol.writeString("<h3>");
1637  ol.writeString("</h3>\n");
1638  ol.writeString("<ul>");
1639  SDict<SectionInfo>::Iterator li(*sectionDict);
1640  SectionInfo *si;
1641  int level=1,l;
1642  char cs[2];
1643  cs[1]='\0';
1644  bool inLi[5]={ FALSE, FALSE, FALSE, FALSE };
1645  for (li.toFirst();(si=li.current());++li)
1646  {
1647  if (si->type==SectionInfo::Section ||
1648  si->type==SectionInfo::Subsection ||
1651  {
1652  //printf(" level=%d title=%s\n",level,si->title.data());
1653  int nextLevel = (int)si->type;
1654  if (nextLevel>level)
1655  {
1656  for (l=level;l<nextLevel;l++)
1657  {
1658  ol.writeString("<ul>");
1659  }
1660  }
1661  else if (nextLevel<level)
1662  {
1663  for (l=level;l>nextLevel;l--)
1664  {
1665  if (inLi[l]) ol.writeString("</li>\n");
1666  inLi[l]=FALSE;
1667  ol.writeString("</ul>\n");
1668  }
1669  }
1670  cs[0]='0'+nextLevel;
1671  if (inLi[nextLevel]) ol.writeString("</li>\n");
1672  QCString titleDoc = convertToHtml(si->title);
1673  ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>");
1674  inLi[nextLevel]=TRUE;
1675  level = nextLevel;
1676  }
1677  }
1678  while (level>1)
1679  {
1680  if (inLi[level]) ol.writeString("</li>\n");
1681  inLi[level]=FALSE;
1682  ol.writeString("</ul>\n");
1683  level--;
1684  }
1685  if (inLi[level]) ol.writeString("</li>\n");
1686  inLi[level]=FALSE;
1687  ol.writeString("</ul>\n");
1688  ol.writeString("</div>\n");
1689  ol.popGeneratorState();
1690 }
1691 
1692 //----------------------------------------------------------------------------------------
1693 
1694 
1696 {
1697  return m_symbolName;
1698 }
1699 
1700 //----------------------
1701 
1703 {
1704  return m_impl->details ? m_impl->details->doc : QCString("");
1705 }
1706 
1708 {
1709  return m_impl->details ? m_impl->details->line : 1;
1710 }
1711 
1713 {
1714  return m_impl->details ? m_impl->details->file : QCString("<"+m_name+">");
1715 }
1716 
1717 //----------------------------------------------------------------------------
1718 // strips w from s iff s starts with w
1720 {
1721  bool success=FALSE;
1722  if (s.left(w.length())==w)
1723  {
1724  success=TRUE;
1725  s=s.right(s.length()-w.length());
1726  }
1727  return success;
1728 }
1729 
1730 //----------------------------------------------------------------------------
1731 // some quasi intelligent brief description abbreviator :^)
1732 QCString abbreviate(const char *s,const char *name)
1733 {
1734  QCString scopelessName=name;
1735  int i=scopelessName.findRev("::");
1736  if (i!=-1) scopelessName=scopelessName.mid(i+2);
1737  QCString result=s;
1738  result=result.stripWhiteSpace();
1739  // strip trailing .
1740  if (!result.isEmpty() && result.at(result.length()-1)=='.')
1741  result=result.left(result.length()-1);
1742 
1743  // strip any predefined prefix
1744  QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
1745  const char *p = briefDescAbbrev.first();
1746  while (p)
1747  {
1748  QCString s = p;
1749  s.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name
1750  s += " ";
1751  stripWord(result,s);
1752  p = briefDescAbbrev.next();
1753  }
1754 
1755  // capitalize first word
1756  if (!result.isEmpty())
1757  {
1758  int c=result[0];
1759  if (c>='a' && c<='z') c+='A'-'a';
1760  result[0]=c;
1761  }
1762  return result;
1763 }
1764 
1765 
1766 //----------------------
1767 
1769 {
1770  //printf("%s::briefDescription(%d)='%s'\n",name().data(),abbr,m_impl->brief?m_impl->brief->doc.data():"<none>");
1771  return m_impl->brief ?
1772  (abbr ? abbreviate(m_impl->brief->doc,displayName()) : m_impl->brief->doc) :
1773  QCString("");
1774 }
1775 
1777 {
1778  if (m_impl->brief)
1779  {
1780  if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty())
1781  {
1782  static bool reentering=FALSE;
1783  if (!reentering)
1784  {
1785  MemberDef *md = definitionType()==TypeMember ? (MemberDef*)this : 0;
1786  const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this;
1787  reentering=TRUE; // prevent requests for tooltips while parsing a tooltip
1789  scope,md,
1790  m_impl->brief->doc,
1791  m_impl->brief->file,
1792  m_impl->brief->line);
1793  reentering=FALSE;
1794  }
1795  }
1796  return m_impl->brief->tooltip;
1797  }
1798  return QCString("");
1799 }
1800 
1802 {
1803  return m_impl->brief ? m_impl->brief->line : 1;
1804 }
1805 
1807 {
1808  return m_impl->brief ? m_impl->brief->file : QCString("<"+m_name+">");
1809 }
1810 
1811 //----------------------
1812 
1814 {
1815  return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString("");
1816 }
1817 
1819 {
1820  return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1;
1821 }
1822 
1824 {
1825  return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_name+">");
1826 }
1827 
1828 
1829 //----------------------
1830 
1832 {
1833  return m_impl->defFileName;
1834 }
1835 
1837 {
1838  return m_impl->defFileExt;
1839 }
1840 
1842 {
1843  return m_impl->hidden;
1844 }
1845 
1847 {
1848  return isLinkableInProject() && !m_impl->hidden;
1849 }
1850 
1852 {
1853  return isLinkable() && !m_impl->hidden;
1854 }
1855 
1857 {
1858  return m_impl->isArtificial;
1859 }
1860 
1862 {
1863  return m_impl->ref;
1864 }
1865 
1867 {
1868  return !m_impl->ref.isEmpty();
1869 }
1870 
1872 {
1873  return m_impl->body ? m_impl->body->startLine : -1;
1874 }
1875 
1877 {
1878  return m_impl->body ? m_impl->body->endLine : -1;
1879 }
1880 
1882 {
1883  return m_impl->body ? m_impl->body->fileDef : 0;
1884 }
1885 
1887 {
1888  return m_impl->partOfGroups;
1889 }
1890 
1892 {
1893  return m_impl->outerScope;
1894 }
1895 
1897 {
1898  return m_impl->sourceRefsDict;
1899 }
1900 
1902 {
1903  return m_impl->sourceRefByDict;
1904 }
1905 
1906 void Definition::setReference(const char *r)
1907 {
1908  m_impl->ref=r;
1909 }
1910 
1912 {
1913  return m_impl->lang;
1914 }
1915 
1917 {
1918  m_impl->hidden = m_impl->hidden || b;
1919 }
1920 
1922 {
1923  m_impl->isArtificial = b;
1924 }
1925 
1927 {
1928  m_impl->localName=name;
1929 }
1930 
1932 {
1933  m_impl->lang=lang;
1934 }
1935 
1936 
1938 {
1939  m_symbolName=name;
1940 }
1941 
1943 {
1944  static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
1945  return !briefDescription().isEmpty() && briefMemberDesc;
1946 }
1947 
1949 {
1950  QCString ref = getReference();
1951  if (!ref.isEmpty())
1952  {
1954  if (dest)
1955  {
1956  QCString result = *dest;
1957  int l = result.length();
1958  if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
1959  { // relative path -> prepend relPath.
1960  result.prepend(relPath);
1961  l+=relPath.length();
1962  }
1963  if (l>0 && result.at(l-1)!='/') result+='/';
1964  return result;
1965  }
1966  }
1967  return relPath;
1968 }
1969 
1970 
1971 
static QCString name
Definition: declinfo.cpp:673
QCString convertToXML(const char *s)
Definition: util.cpp:5717
QCString symbolName() const
bool resize(uint newlen)
Definition: qcstring.h:225
char * rawData() const
Definition: qcstring.h:216
QCString docFile() const
ParserInterface * getParser(const char *extension)
Definition: parserintf.h:191
QCString qualifiedName
Definition: definition.cpp:75
int _getXRefListId(const char *listName) const
virtual bool isLinkable() const =0
Definition * outerScope
Definition: definition.cpp:81
QCString stripWhiteSpace() const
Definition: qcstring.cpp:295
bool isArtificial() const
static QCString scope
Definition: declinfo.cpp:668
virtual QCString trRTFTableOfContents()=0
bool brief
virtual QCString getReference() const
QCString m_symbolName
Definition: definition.h:374
Cookie * m_cookie
Definition: definition.h:377
virtual ~Definition()
Definition: definition.cpp:381
static QCString result
bool isEmpty() const
Definition: qcstring.h:189
QCString getReference() const
Definition: memberdef.cpp:1001
The QRegExp class provides pattern matching using regular expressions or wildcards.
Definition: qregexp.h:46
void writeToc(OutputList &ol)
QCString convertNameToFile(const char *name, bool allowDots=FALSE) const
QCString file
Definition: definition.h:44
uint length() const
Definition: qcstring.h:195
virtual bool isLinkableInProject() const =0
SectionType type
Definition: section.h:58
void setBodyDef(FileDef *fd)
void append(const type *d)
Definition: qlist.h:73
FILE * portable_popen(const char *name, const char *type)
Definition: portable.cpp:400
QCString localName
Definition: definition.cpp:73
Abstract interface for programming language parsers.
Definition: parserintf.h:38
SectionDict * sectionDict
Definition: definition.cpp:59
virtual void setName(const char *name)
Definition: definition.cpp:396
QList< ListItemInfo > * xrefListItems() const
static QCString htmlFileExtension
Definition: doxygen.h:130
void writeString(const char *text)
Definition: outputlist.h:119
bool isPrototype() const
Definition: memberdef.cpp:4507
void startCodeFragment()
Definition: outputlist.h:244
QCString tooltip
Definition: definition.h:51
void writeSourceReffedBy(OutputList &ol, const char *scopeName)
QCString inbodyDocumentation() const
void setLanguage(SrcLangExt lang)
type * first()
Definition: qinternallist.h:87
#define qsnprintf
Definition: qcstring.h:73
bool generated
Definition: section.h:63
virtual void addInnerCompound(Definition *d)
void disableAllBut(OutputGenerator::OutputType o)
Definition: outputlist.cpp:49
char & at(uint i) const
Definition: qcstring.h:326
void startParagraph()
Definition: outputlist.h:115
FileDef * getBodyDef() const
void setArtificial(bool b)
virtual bool hasDocumentation() const
void writeNavigationPath(OutputList &ol) const
virtual void setOuterScope(Definition *d)
QCString pathFragment() const
const bool FALSE
Definition: qglobal.h:370
virtual bool isVisibleInProject() const
QCString label
Definition: section.h:56
bool hasSections() const
Definition: definition.cpp:447
#define Config_getList(val)
Definition: config.cpp:662
QCString left(uint len) const
Definition: qcstring.cpp:213
virtual QCString trDefinedAtLineInSourceFile()=0
int briefLine() const
virtual bool isReference() const
bool isSignal() const
Definition: memberdef.cpp:4130
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
void addSectionsToIndex()
Definition: definition.cpp:467
bool isSlot() const
Definition: memberdef.cpp:4135
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
int count() const
Definition: sortdict.h:284
virtual QCString getOutputFileBase() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
QCString briefSignatures
Definition: definition.cpp:70
GroupList * partOfGroups() const
void append(const char *key, const T *d)
Definition: sortdict.h:135
SrcLangExt
Definition: types.h:41
static QStrList * l
Definition: config.cpp:1044
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition: qcstring.cpp:95
QCString getFileFilter(const char *name, bool isSourceCode)
Definition: util.cpp:2345
virtual void setInbodyDocumentation(const char *d, const char *docFile, int docLine)
Definition: definition.cpp:711
void _writeSourceRefList(OutputList &ol, const char *scopeName, const QCString &text, MemberSDict *members, bool)
unsigned char uchar
Definition: nybbler.cc:11
GroupList * partOfGroups
Definition: definition.cpp:64
bool parseText(const QCString &textStr)
Definition: outputlist.cpp:175
MemberSDict * getReferencesMembers() const
QCString getDefFileName() const
MemberSDict * sourceRefByDict
Definition: definition.cpp:61
QCString getDefFileExtension() const
void endCodeFragment()
Definition: outputlist.h:246
void writeDocAnchorsToTagFile(FTextStream &)
Definition: definition.cpp:520
QCString transcodeCharacterStringToUTF8(const QCString &input)
Definition: util.cpp:2374
#define Config_getEnum(val)
Definition: config.cpp:663
void _setBriefDescription(const char *b, const char *briefFile, int briefLine)
Definition: definition.cpp:632
int line
Definition: definition.h:43
#define Config_getInt(val)
Definition: config.cpp:661
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
static NamespaceDef * globalScope
Definition: doxygen.h:128
int itemId
Definition: types.h:101
QCString defFileExt
Definition: definition.cpp:85
static ParserManager * parserManager
Definition: doxygen.h:141
void popGeneratorState()
Definition: outputlist.cpp:121
virtual DefType definitionType() const =0
Definition: sortdict.h:73
static void addToMap(const char *name, Definition *d)
Definition: definition.cpp:207
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Definition: util.cpp:8065
void decContentsDepth()
Definition: index.h:135
static StringDict tagDestinationDict
Definition: doxygen.h:124
MemberSDict * getReferencedByMembers() const
QCString docSignatures
Definition: definition.cpp:71
QAsciiDict< Entry > fn
void endParagraph()
Definition: outputlist.h:117
int line
Definition: definition.h:52
Q_EXPORT uint qstrlen(const char *str)
Definition: qcstring.h:81
bool m_isSymbol
Definition: definition.h:373
const QCString & name() const
Definition: definition.h:114
static bool matchExcludedSymbols(const char *name)
Definition: definition.cpp:150
#define uni_isupper(c)
Definition: definition.cpp:618
QCString inbodyFile() const
fileName
Definition: dumpTree.py:9
QCString parseCommentAsText(const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
Definition: util.cpp:7242
QCString getScopeString() const
Definition: memberdef.cpp:3301
void pushGeneratorState()
Definition: outputlist.cpp:111
QCString name() const
Definition: filedef.cpp:1193
virtual QCString getSourceFileBase() const
Definition: definition.cpp:885
virtual QCString getSourceAnchor() const
Definition: definition.cpp:898
QCString navigationPathAsString() const
int endLine
line number of the end of the definition
Definition: definition.h:60
bool hasBriefDescription() const
bool isEmpty() const
Definition: qlist.h:67
void MD5Buffer(const unsigned char *buf, unsigned int len, unsigned char sig[16])
Definition: md5.c:275
QCString convertToHtml(const char *s, bool keepEntities)
Definition: util.cpp:5746
void init(const char *df, const char *n)
Definition: definition.cpp:113
QCString getSourceFileBase() const
Definition: filedef.cpp:1771
QCString right(uint len) const
Definition: qcstring.cpp:231
SrcLangExt getLanguage() const
std::void_t< T > n
QCString m_name
Definition: definition.h:372
QCString fileName
Definition: section.h:61
void setLocalName(const QCString name)
static void print(DebugMask mask, int prio, const char *fmt,...)
Definition: debug.cpp:84
static QDict< DefinitionIntf > * symbolMap
Definition: doxygen.h:134
QCString & prepend(const char *s)
Definition: qcstring.cpp:387
MemberSDict * sourceRefsDict
Definition: definition.cpp:62
p
Definition: test.py:223
void disable(OutputGenerator::OutputType o)
Definition: outputlist.cpp:79
void makePartOfGroup(GroupDef *gd)
static SectionDict * sectionDict
Definition: doxygen.h:117
QCString id() const
Definition: definition.cpp:413
A bunch of utility functions.
void addSectionsToDefinition(QList< SectionInfo > *anchorList)
Definition: definition.cpp:418
const char * data() const
Definition: qcstring.h:207
virtual bool hasUserDocumentation() const
QCString anchor() const
Definition: memberdef.cpp:1031
QCString file
Definition: definition.h:53
type * current() const
Definition: qlist.h:146
#define Config_getBool(val)
Definition: config.cpp:664
void setReference(const char *r)
QCString doc
Definition: definition.h:42
DocInfo * details
Definition: definition.cpp:66
virtual bool isVisible() const
QCString briefFile() const
QCString title
Definition: section.h:57
bool isObjCMethod() const
Definition: memberdef.cpp:3956
virtual QCString qualifiedName() const
type * next()
Definition: qinternallist.h:89
friend class IteratorDict
Definition: sortdict.h:353
void err(const char *fmt,...)
Definition: message.cpp:226
static QDict< Definition > * clangUsrMap
Definition: doxygen.h:135
void writeSourceRefs(OutputList &ol, const char *scopeName)
QCString absFilePath() const
Definition: filedef.h:96
int inbodyLine() const
virtual QCString briefDescription(bool abbreviate=FALSE) const
void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor, bool separateIndex=FALSE, bool addToNavIndex=FALSE, Definition *def=0)
Definition: index.h:137
static bool stripWord(QCString &s, QCString w)
SrcLangExt lang
Definition: definition.cpp:87
QCString mid(uint index, uint len=0xffffffff) const
Definition: qcstring.cpp:246
int match(const QCString &str, int index=0, int *len=0, bool indexIsStart=TRUE) const
Definition: qregexp.cpp:649
int nextUtf8CharPosition(const QCString &utf8Str, int len, int startPos)
Definition: util.cpp:7195
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:27
static bool lastCharIsMultibyte(const QCString &s)
Definition: definition.cpp:622
const uint SDict_primes[]
Definition: sortdict.h:29
virtual Definition * getOuterScope() const
void setRefItems(const QList< ListItemInfo > *sli)
void writeNavigationPath(const char *s)
Definition: outputlist.h:356
bool isHidden() const
int getEndBodyLine() const
virtual QCString trReferences()=0
void sort()
Definition: sortdict.h:188
static bool useHtags
Definition: htags.h:23
bool readCodeFragment(const char *fileName, int &startLine, int &endLine, QCString &result)
Definition: definition.cpp:728
virtual Definition * findInnerCompound(const char *name)
DocInfo * inbodyDocs
Definition: definition.cpp:67
SrcLangExt getLanguageFromFileName(const QCString fileName)
Definition: util.cpp:7061
int getStartBodyLine() const
void writeInlineCode(OutputList &ol, const char *scopeName)
void MD5SigToString(unsigned char signature[16], char *str, int len)
Definition: md5.c:285
void _setDocumentation(const char *d, const char *docFile, int docLine, bool stripWhiteSpace, bool atTop)
Definition: definition.cpp:566
int computeQualifiedIndex(const QCString &name)
Definition: util.cpp:1203
void addSourceReferences(MemberDef *d)
void writeSourceDef(OutputList &ol, const char *scopeName)
Definition: definition.cpp:918
QCString stripScope(const char *name)
Definition: util.cpp:5605
Definition(const char *defFileName, int defLine, int defColumn, const char *name, const char *b=0, const char *d=0, bool isSymbol=TRUE)
Definition: definition.cpp:283
void addSourceReferencedBy(MemberDef *d)
void setId(const char *name)
Definition: definition.cpp:402
A model of a page symbol.
Definition: pagedef.h:29
uint toUInt(bool *ok=0) const
Definition: qcstring.cpp:445
int portable_pclose(FILE *stream)
Definition: portable.cpp:405
std::string pattern
Definition: regex_t.cc:35
virtual void setBriefDescription(const char *b, const char *briefFile, int briefLine)
Definition: definition.cpp:687
virtual QCString trReferencedBy()=0
QCString convertNameToFile(const char *name, bool allowDots, bool allowUnderscore)
Definition: util.cpp:5354
void enableAll()
Definition: outputlist.cpp:59
bool fill(char c, int len=-1)
Definition: qcstring.h:243
void mergeRefItems(Definition *d)
bool hasSources() const
bool truncate(uint pos)
Definition: qcstring.h:232
QCString doc
QCString getOutputFileBase() const
Definition: memberdef.cpp:941
QList< ListItemInfo > * xrefListItems
Definition: definition.cpp:63
QCString type
Definition: types.h:100
T * at(uint i)
Definition: sortdict.h:258
static bool * b
Definition: config.cpp:1043
QCString abbreviate(const char *s, const char *name)
Translator * theTranslator
Definition: language.cpp:157
virtual void setDocumentation(const char *d, const char *docFile, int docLine, bool stripWhiteSpace=TRUE)
Definition: definition.cpp:612
bool isId(int c)
Definition: util.h:224
bool isFunction() const
Definition: memberdef.cpp:4160
BriefInfo * brief
Definition: definition.cpp:68
bool removeRef(const type *d)
Definition: qlist.h:78
QCString briefDescriptionAsTooltip() const
void _setInbodyDocumentation(const char *d, const char *docFile, int docLine)
Definition: definition.cpp:693
list cmd
Definition: getreco.py:22
QCString stripLeadingAndTrailingEmptyLines(const QCString &s, int &docLine)
Definition: util.cpp:6876
const char * cs
int docLine() const
BodyInfo * body
Definition: definition.cpp:69
QCString externalReference(const QCString &relPath) const
Definition * definition
Definition: section.h:60
void docify(const char *s)
Definition: outputlist.h:145
QCString defFileName
Definition: definition.cpp:84
uint count() const
Definition: qinternallist.h:56
Q_EXPORT int qstrcmp(const char *str1, const char *str2)
Definition: qcstring.h:95
virtual QCString trWriteList(int numEntries)=0
T * find(const char *key)
Definition: sortdict.h:232
int m_defLine
Definition: definition.h:375
virtual QCString documentation() const
if(!yymsg) yymsg
void writeObjectLink(const char *ref, const char *file, const char *anchor, const char *name)
Definition: outputlist.h:149
static void removeFromMap(Definition *d)
Definition: definition.cpp:254
unsigned uint
Definition: qglobal.h:351
void setAutoDelete(bool enable)
Definition: qlist.h:99
virtual void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, const QCString &input, SrcLangExt lang, bool isExampleBlock, const char *exampleName=0, FileDef *fileDef=0, int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, MemberDef *memberDef=0, bool showLineNumbers=TRUE, Definition *searchCtx=0, bool collectXRefs=TRUE)=0
bool isLinkable() const
Definition: memberdef.cpp:1161
DefinitionImpl * m_impl
Definition: definition.h:371
FILE * portable_fopen(const char *fileName, const char *mode)
Definition: portable.cpp:344
void _setSymbolName(const QCString &name)
void incContentsDepth()
Definition: index.h:133
QCString & replace(uint index, uint len, const char *s)
Definition: qcstring.cpp:411
static QCString * s
Definition: config.cpp:1042
QCString doc
Definition: definition.h:50
QCString localName() const
const char * qPrint(const char *s)
Definition: qcstring.h:797
const bool TRUE
Definition: qglobal.h:371
bool _docsAlreadyAdded(const QCString &doc, QCString &sigList)
Definition: definition.cpp:544
static IndexList * indexList
Definition: doxygen.h:149
QCString simplifyWhiteSpace() const
Definition: qcstring.cpp:323
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition: util.cpp:5088
virtual QCString anchor() const =0
QTextStream & endl(QTextStream &s)
FileDef * fileDef
file definition containing the function body
Definition: definition.h:61
int m_defColumn
Definition: definition.h:376
QCString ref
Definition: definition.cpp:76
#define ASSERT(x)
Definition: qglobal.h:590
int startLine
line number of the start of the definition
Definition: definition.h:59
virtual void setHidden(bool b)
type * toFirst()
Definition: qlist.h:135
void setBodySegment(int bls, int ble)
virtual void resetCodeParserState()=0