Doxygen
Loading...
Searching...
No Matches
definition.cpp File Reference
#include <algorithm>
#include <iterator>
#include <unordered_map>
#include <string>
#include <optional>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include "anchor.h"
#include "md5.h"
#include "regex.h"
#include "config.h"
#include "definitionimpl.h"
#include "doxygen.h"
#include "language.h"
#include "message.h"
#include "portable.h"
#include "outputlist.h"
#include "code.h"
#include "util.h"
#include "groupdef.h"
#include "pagedef.h"
#include "section.h"
#include "htags.h"
#include "parserintf.h"
#include "debug.h"
#include "vhdldocgen.h"
#include "memberlist.h"
#include "namespacedef.h"
#include "filedef.h"
#include "dirdef.h"
#include "reflist.h"
#include "utf8.h"
#include "indexlist.h"
#include "fileinfo.h"
Include dependency graph for definition.cpp:

Go to the source code of this file.

Classes

class  DefinitionImpl::Private
 Private data associated with a Symbol DefinitionImpl object. More...
class  FilterCache
struct  FilterCache::FilterCacheItem

Functions

static bool matchExcludedSymbols (const QCString &name)
static void addToMap (const QCString &name, Definition *d)
static void removeFromMap (const QCString &name, Definition *d)
bool readCodeFragment (const QCString &fileName, bool isMacro, int &startLine, int &endLine, QCString &result)
 Reads a fragment from file fileName starting with line startLine and ending with line endLine.
static MemberVector refMapToVector (const std::unordered_map< std::string, MemberDef * > &map)
static bool stripWord (QCString &s, QCString w)
static QCString abbreviate (const QCString &s, const QCString &name)
DefinitiontoDefinition (DefinitionMutable *dm)
DefinitionMutabletoDefinitionMutable (Definition *d)

Variables

static std::recursive_mutex g_qualifiedNameMutex
static std::mutex g_memberReferenceMutex

Function Documentation

◆ abbreviate()

QCString abbreviate ( const QCString & s,
const QCString & name )
static

Definition at line 1498 of file definition.cpp.

1499{
1500 QCString scopelessName=name;
1501 int i=scopelessName.findRev("::");
1502 if (i!=-1) scopelessName=scopelessName.mid(i+2);
1503 QCString result=s;
1504 result=result.stripWhiteSpace();
1505 // strip trailing .
1506 if (!result.isEmpty() && result.at(result.length()-1)=='.')
1507 result=result.left(result.length()-1);
1508
1509 // strip any predefined prefix
1510 const StringVector &briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF);
1511 for (const auto &p : briefDescAbbrev)
1512 {
1513 QCString str = substitute(p.c_str(),"$name",scopelessName); // replace $name with entity name
1514 str += " ";
1515 stripWord(result,str);
1516 }
1517
1518 // capitalize first word
1519 if (!result.isEmpty())
1520 {
1521 char c=result[0];
1522 if (c>='a' && c<='z') c+='A'-'a';
1523 result[0]=c;
1524 }
1525 return result;
1526}
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
QCString left(size_t len) const
Definition qcstring.h:214
#define Config_getList(name)
Definition config.h:38
std::vector< std::string > StringVector
Definition containers.h:33
static bool stripWord(QCString &s, QCString w)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477

References QCString::at(), Config_getList, QCString::findRev(), QCString::isEmpty(), QCString::left(), QCString::length(), QCString::mid(), QCString::stripWhiteSpace(), stripWord(), and substitute().

Referenced by Definition::briefDescription(), DefinitionAliasMixin< Base >::briefDescription(), DefinitionImpl::briefDescription(), DefinitionMixin< Base >::briefDescription(), and DefinitionImpl::operator=().

◆ addToMap()

void addToMap ( const QCString & name,
Definition * d )
static

Definition at line 212 of file definition.cpp.

213{
214 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
215 QCString symbolName = name;
216 int index=computeQualifiedIndex(symbolName);
217 if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
218 if (!symbolName.isEmpty())
219 {
220 //printf("adding symbol %s\n",qPrint(symbolName));
221 Doxygen::symbolMap->add(symbolName,d);
222
223 d->_setSymbolName(symbolName);
224 }
225}
virtual void _setSymbolName(const QCString &name)=0
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
#define Config_getBool(name)
Definition config.h:33
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:7294

References Definition::_setSymbolName(), computeQualifiedIndex(), Config_getBool, QCString::isEmpty(), QCString::mid(), DefinitionImpl::name(), Doxygen::symbolMap, and DefinitionImpl::symbolName().

Referenced by DefinitionImpl::DefinitionImpl(), DefinitionImpl::DefinitionImpl(), and DefinitionAliasImpl::init().

◆ matchExcludedSymbols()

bool matchExcludedSymbols ( const QCString & name)
static

Definition at line 157 of file definition.cpp.

158{
159 const StringVector &exclSyms = Config_getList(EXCLUDE_SYMBOLS);
160 if (exclSyms.empty()) return FALSE; // nothing specified
161 std::string symName = name.str();
162 for (const auto &pat : exclSyms)
163 {
164 QCString pattern = pat.c_str();
165 bool forceStart=FALSE;
166 bool forceEnd=FALSE;
167 if (pattern.at(0)=='^')
168 pattern=pattern.mid(1),forceStart=TRUE;
169 if (pattern.at(pattern.length()-1)=='$')
170 pattern=pattern.left(pattern.length()-1),forceEnd=TRUE;
171 if (pattern.find('*')!=-1) // wildcard mode
172 {
173 const reg::Ex re(substitute(pattern,"*",".*").str());
175 if (reg::search(symName,match,re)) // wildcard match
176 {
177 size_t ui = match.position();
178 size_t pl = match.length();
179 size_t sl = symName.length();
180 if ((ui==0 || pattern.at(0)=='*' || (!isId(symName.at(ui-1)) && !forceStart)) &&
181 (ui+pl==sl || pattern.at(pattern.length()-1)=='*' || (!isId(symName.at(ui+pl)) && !forceEnd))
182 )
183 {
184 //printf("--> name=%s pattern=%s match at %d\n",qPrint(symName),qPrint(pattern),i);
185 return TRUE;
186 }
187 }
188 }
189 else if (!pattern.isEmpty()) // match words
190 {
191 size_t i = symName.find(pattern.str());
192 if (i!=std::string::npos) // we have a match!
193 {
194 size_t ui=i;
195 size_t pl=pattern.length();
196 size_t sl=symName.length();
197 // check if it is a whole word match
198 if ((ui==0 || (!isId(symName.at(ui-1)) && !forceStart)) &&
199 (ui+pl==sl || (!isId(symName.at(ui+pl)) && !forceEnd))
200 )
201 {
202 //printf("--> name=%s pattern=%s match at %d\n",qPrint(symName),qPrint(pattern),i);
203 return TRUE;
204 }
205 }
206 }
207 }
208 //printf("--> name=%s: no match\n",name);
209 return FALSE;
210}
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
const std::string & str() const
Definition qcstring.h:537
Class representing a regular expression.
Definition regex.h:39
Object representing the matching results.
Definition regex.h:153
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:748
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:759
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
bool isId(int c)
Definition util.h:208

References QCString::at(), Config_getList, FALSE, QCString::find(), QCString::isEmpty(), isId(), QCString::left(), QCString::length(), QCString::mid(), DefinitionImpl::name(), reg::search(), QCString::str(), substitute(), and TRUE.

Referenced by DefinitionImpl::DefinitionImpl().

◆ readCodeFragment()

bool readCodeFragment ( const QCString & fileName,
bool isMacro,
int & startLine,
int & endLine,
QCString & result )

Reads a fragment from file fileName starting with line startLine and ending with line endLine.

Reads a fragment of code from file fileName starting at line startLine and ending at line endLine (inclusive). The fragment is stored in result. If FALSE is returned the code fragment could not be found.

The file is scanned for a opening bracket ('{') from startLine onward The line actually containing the bracket is returned via startLine. The file is scanned for a closing bracket ('}') from endLine backward. The line actually containing the bracket is returned via endLine. Note that for VHDL code the bracket search is not done.

Definition at line 750 of file definition.cpp.

752{
753 bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
754 QCString filter = getFileFilter(fileName,TRUE);
755 bool usePipe = !filter.isEmpty() && filterSourceFiles;
756 int tabSize = Config_getInt(TAB_SIZE);
757 SrcLangExt lang = getLanguageFromFileName(fileName);
758 const int blockSize = 4096;
759 std::string str;
761 static_cast<size_t>(std::max(1,startLine)),
762 static_cast<size_t>(std::max({1,startLine,endLine})),str);
763 //printf("readCodeFragment(%s,startLine=%d,endLine=%d)=\n[[[\n%s]]]\n",qPrint(fileName),startLine,endLine,qPrint(str));
764
765 bool found = lang==SrcLangExt::VHDL ||
766 lang==SrcLangExt::Python ||
767 lang==SrcLangExt::Fortran ||
768 isMacro;
769 // for VHDL, Python, and Fortran no bracket search is possible
770 char *p=str.data();
771 if (p && *p)
772 {
773 char c=0;
774 int col=0;
775 int lineNr=startLine;
776 // skip until the opening bracket or lonely : is found
777 char cn=0;
778 while (*p && !found)
779 {
780 int pc=0;
781 while ((c=*p++)!='{' && c!=':' && c!=0)
782 {
783 //printf("parsing char '%c'\n",c);
784 if (c=='\n')
785 {
786 lineNr++,col=0;
787 }
788 else if (c=='\t')
789 {
790 col+=tabSize - (col%tabSize);
791 }
792 else if (pc=='/' && c=='/') // skip single line comment
793 {
794 while ((c=*p++)!='\n' && c!=0);
795 if (c=='\n') lineNr++,col=0;
796 }
797 else if (pc=='/' && c=='*') // skip C style comment
798 {
799 while (((c=*p++)!='/' || pc!='*') && c!=0)
800 {
801 if (c=='\n') lineNr++,col=0;
802 pc=c;
803 }
804 }
805 else
806 {
807 col++;
808 }
809 pc = c;
810 }
811 if (c==':')
812 {
813 cn=*p++;
814 if (cn!=':') found=TRUE;
815 }
816 else if (c=='{')
817 {
818 found=TRUE;
819 }
820 else if (c==0)
821 {
822 break;
823 }
824 }
825 //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr);
826 if (found)
827 {
828 // For code with more than one line,
829 // fill the line with spaces until we are at the right column
830 // so that the opening brace lines up with the closing brace
831 if (endLine!=startLine)
832 {
833 QCString spaces;
834 spaces.fill(' ',col);
835 result+=spaces;
836 }
837 // copy until end of line
838 if (c) result+=c;
839 startLine=lineNr;
840 if (c==':')
841 {
842 result+=cn;
843 if (cn=='\n') lineNr++;
844 }
845 char lineStr[blockSize];
846 do
847 {
848 //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine);
849 int size_read=0;
850 do
851 {
852 // read up to blockSize-1 non-zero characters
853 int i=0;
854 while ((c=*p) && i<blockSize-1)
855 {
856 lineStr[i++]=c;
857 p++;
858 if (c=='\n') break; // stop at end of the line
859 }
860 lineStr[i]=0;
861 size_read=i;
862 result+=lineStr; // append line to the output
863 } while (size_read == (blockSize-1)); // append more if line does not fit in buffer
864 lineNr++;
865 } while (*p);
866
867 // strip stuff after closing bracket
868 int newLineIndex = result.findRev('\n');
869 int braceIndex = result.findRev('}');
870 if (braceIndex > newLineIndex)
871 {
872 result.resize(static_cast<size_t>(braceIndex+1));
873 }
874 endLine=lineNr-1;
875 }
876 if (usePipe)
877 {
878 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
879 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",result);
880 }
881 }
882 QCString encoding = getEncoding(FileInfo(fileName.str()));
883 if (encoding!="UTF-8")
884 {
885 std::string encBuf = result.str();
886 bool ok = transcodeCharacterStringToUTF8(encBuf,encoding.data());
887 if (ok)
888 {
889 result = QCString(encBuf);
890 }
891 else
892 {
893 err("failed to transcode characters in code fragment in file {} lines {} to {}, from input encoding {} to UTF-8\n",
894 fileName,startLine,endLine,encoding);
895
896 }
897 }
898 if (!result.isEmpty() && result.at(result.length()-1)!='\n') result += "\n";
899 //printf("readCodeFragment(%d-%d)=%s\n",startLine,endLine,qPrint(result));
900 return found;
901}
@ FilterOutput
Definition debug.h:38
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
static FilterCache & instance()
bool getFileContents(const QCString &fileName, size_t startLine, size_t endLine, std::string &str)
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
void resize(size_t newlen)
Definition qcstring.h:167
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
#define Config_getInt(name)
Definition config.h:34
#define err(fmt,...)
Definition message.h:127
SrcLangExt
Definition types.h:207
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5714
bool transcodeCharacterStringToUTF8(std::string &input, const char *inputEncoding)
Definition util.cpp:1403
bool found
Definition util.cpp:984
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:6167
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1369

References QCString::at(), Config_getBool, Config_getInt, QCString::data(), err, QCString::fill(), Debug::FilterOutput, QCString::findRev(), found, getEncoding(), FilterCache::getFileContents(), getFileFilter(), getLanguageFromFileName(), FilterCache::instance(), QCString::isEmpty(), QCString::length(), Debug::print(), QCString::resize(), QCString::str(), transcodeCharacterStringToUTF8(), and TRUE.

Referenced by VhdlDocGen::createFlowChart(), DefinitionMutable::toDefinition_(), and DefinitionImpl::writeInlineCode().

◆ refMapToVector()

MemberVector refMapToVector ( const std::unordered_map< std::string, MemberDef * > & map)
inlinestatic

Definition at line 1062 of file definition.cpp.

1063{
1064 // convert map to a vector of values
1065 MemberVector result;
1066 std::transform(map.begin(),map.end(), // iterate over map
1067 std::back_inserter(result), // add results to vector
1068 [](const auto &item)
1069 { return item.second; } // extract value to add from map Key,Value pair
1070 );
1071 // and sort it
1072 std::stable_sort(result.begin(),result.end(),
1073 [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; });
1074 return result;
1075}
A vector of MemberDef object.
Definition memberlist.h:35
iterator end() noexcept
Definition memberlist.h:56
iterator begin() noexcept
Definition memberlist.h:54

References MemberVector::begin(), and MemberVector::end().

Referenced by DefinitionImpl::_writeSourceRefList(), DefinitionImpl::getReferencedByMembers(), and DefinitionImpl::getReferencesMembers().

◆ removeFromMap()

void removeFromMap ( const QCString & name,
Definition * d )
static

Definition at line 227 of file definition.cpp.

228{
229 Doxygen::symbolMap->remove(name,d);
230}

References DefinitionImpl::name(), and Doxygen::symbolMap.

Referenced by DefinitionAliasImpl::deinit(), and DefinitionImpl::~DefinitionImpl().

◆ stripWord()

bool stripWord ( QCString & s,
QCString w )
static

Definition at line 1485 of file definition.cpp.

1486{
1487 bool success=FALSE;
1488 if (s.left(w.length())==w)
1489 {
1490 success=TRUE;
1491 s=s.right(s.length()-w.length());
1492 }
1493 return success;
1494}
QCString right(size_t len) const
Definition qcstring.h:219

References FALSE, QCString::left(), QCString::length(), QCString::right(), and TRUE.

Referenced by abbreviate().

◆ toDefinition()

Definition * toDefinition ( DefinitionMutable * dm)

Definition at line 1870 of file definition.cpp.

1871{
1872 if (dm==nullptr) return nullptr;
1873 return dm->toDefinition_();
1874}
virtual Definition * toDefinition_()=0

References DefinitionImpl::docLine(), stripLeadingAndTrailingEmptyLines(), and stripWhiteSpace().

Referenced by buildScopeFromQualifiedName(), findScopeFromQualifiedName(), toClassDef(), toConceptDef(), toMemberDef(), toNamespaceDef(), and MemberList::writeDocumentationPage().

◆ toDefinitionMutable()

DefinitionMutable * toDefinitionMutable ( Definition * d)

Definition at line 1876 of file definition.cpp.

1877{
1878 if (d==nullptr) return nullptr;
1879 return d->toDefinitionMutable_();
1880}
virtual DefinitionMutable * toDefinitionMutable_()=0

Referenced by addConceptToContext(), buildNamespaceList(), buildScopeFromQualifiedName(), computeTooltipTexts(), createTagLessInstance(), resolveClassNestingRelations(), and DefinitionMutable::toDefinition_().

Variable Documentation

◆ g_memberReferenceMutex

std::mutex g_memberReferenceMutex
static

◆ g_qualifiedNameMutex

std::recursive_mutex g_qualifiedNameMutex
static