Doxygen
Loading...
Searching...
No Matches
definition.cpp File Reference
#include "definition.h"
#include <algorithm>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>
#include "anchor.h"
#include "config.h"
#include "debug.h"
#include "definitionimpl.h"
#include "dirdef.h"
#include "doxygen.h"
#include "filedef.h"
#include "fileinfo.h"
#include "groupdef.h"
#include "htags.h"
#include "language.h"
#include "md5hash.h"
#include "message.h"
#include "namespacedef.h"
#include "outputlist.h"
#include "pagedef.h"
#include "parserintf.h"
#include "portable.h"
#include "reflist.h"
#include "regex.h"
#include "section.h"
#include "utf8.h"
#include "util.h"
Include dependency graph for definition.cpp:

Go to the source code of this file.

Classes

struct  ResettableOnce
 once_flag wrapper that is copyable (copy default-initializes the flag) and resettable. More...
class  DefinitionImpl::Private
 Private data associated with a Symbol DefinitionImpl object. More...
class  FilterCache
struct  FilterCache::FilterCacheItem

Functions

static bool matchExcludedSymbols (const DString &name)
static void addToMap (const DString &name, Definition *d)
static void removeFromMap (const DString &name, Definition *d)
bool readCodeFragment (const DString &fileName, bool isMacro, int &startLine, int &endLine, DString &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 (DString &s, DString w)
static DString abbreviate (const DString &s, const DString &name)
DefinitiontoDefinition (DefinitionMutable *dm)
DefinitionMutabletoDefinitionMutable (Definition *d)

Variables

static std::mutex g_memberReferenceMutex

Function Documentation

◆ abbreviate()

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

Definition at line 1606 of file definition.cpp.

1607{
1608 DString scopelessName=name;
1609 if (size_t i=scopelessName.rfind("::"); i!=DString::npos) scopelessName=scopelessName.mid(i+2);
1610 DString result=s;
1611 result=result.stripWhiteSpace();
1612 // strip trailing .
1613 if (!result.empty() && result.at(result.length()-1)=='.')
1614 result=result.left(result.length()-1);
1615
1616 // strip any predefined prefix
1617 StringVector briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF);
1618 for (const auto &p : briefDescAbbrev)
1619 {
1620 DString str = substitute(p,"$name",scopelessName); // replace $name with entity name
1621 str += " ";
1622 stripWord(result,str);
1623 }
1624
1625 // capitalize first character
1626 if (!result.empty())
1627 {
1628 char c = result[0];
1629 if (c >= 'a' && c <= 'z') result[0] += 'A' - 'a';
1630 }
1631
1632 return result;
1633}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:244
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
DString left(size_t len) const
Definition dstring.h:306
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
#define Config_getList(name)
Definition config.h:38
std::vector< std::string > StringVector
Definition containers.h:33
static bool stripWord(DString &s, DString w)
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485

References DString::at(), Config_getList, DString::empty(), DString::left(), DString::length(), DString::mid(), DString::npos, DString::rfind(), DString::stripWhiteSpace(), stripWord(), and substitute().

Referenced by DefinitionImpl::briefDescription().

◆ addToMap()

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

Definition at line 226 of file definition.cpp.

227{
228 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
229 DString symbolName = name;
230 int index=computeQualifiedIndex(symbolName);
231 if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
232 if (!symbolName.empty())
233 {
234 //printf("adding symbol %s\n",qPrint(symbolName));
235 Doxygen::symbolMap->add(symbolName,d);
236
237 d->_setSymbolName(symbolName);
238 }
239}
virtual void _setSymbolName(const DString &name)=0
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:118
void add(const DString &name, Ptr def)
Add a symbol def into the map under key name.
Definition symbolmap.h:40
#define Config_getBool(name)
Definition config.h:33
int computeQualifiedIndex(const DString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:5278

References Definition::_setSymbolName(), SymbolMap< T >::add(), computeQualifiedIndex(), Config_getBool, DString::empty(), DString::mid(), DefinitionImpl::name(), Doxygen::symbolMap, and DefinitionImpl::symbolName().

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

◆ matchExcludedSymbols()

bool matchExcludedSymbols ( const DString & name)
static

Definition at line 165 of file definition.cpp.

166{
167 StringVector exclSyms = Config_getList(EXCLUDE_SYMBOLS);
168 if (exclSyms.empty()) return false; // nothing specified
169 const std::string &symName = name.str();
170 for (const auto &pat : exclSyms)
171 {
172 DString pattern = pat;
173 bool forceStart=false;
174 bool forceEnd=false;
175 if (pattern.at(0)=='^')
176 {
177 pattern = pattern.mid(1);
178 forceStart = true;
179 }
180 if (pattern.at(pattern.length() - 1) == '$')
181 {
182 pattern = pattern.left(pattern.length() - 1);
183 forceEnd = true;
184 }
185 if (pattern.find('*')!=DString::npos) // wildcard mode
186 {
187 const reg::Ex re(substitute(pattern,"*",".*").str());
189 if (reg::search(symName,match,re)) // wildcard match
190 {
191 size_t ui = match.position();
192 size_t pl = match.length();
193 size_t sl = symName.length();
194 if ((ui==0 || pattern.at(0)=='*' || (!isId(symName.at(ui-1)) && !forceStart)) &&
195 (ui+pl==sl || pattern.at(pattern.length()-1)=='*' || (!isId(symName.at(ui+pl)) && !forceEnd))
196 )
197 {
198 //printf("--> name=%s pattern=%s match at %d\n",qPrint(symName),qPrint(pattern),i);
199 return true;
200 }
201 }
202 }
203 else if (!pattern.empty()) // match words
204 {
205 size_t i = symName.find(pattern.str());
206 if (i!=std::string::npos) // we have a match!
207 {
208 size_t ui=i;
209 size_t pl=pattern.length();
210 size_t sl=symName.length();
211 // check if it is a whole word match
212 if ((ui==0 || (!isId(symName.at(ui-1)) && !forceStart)) &&
213 (ui+pl==sl || (!isId(symName.at(ui+pl)) && !forceEnd))
214 )
215 {
216 //printf("--> name=%s pattern=%s match at %d\n",qPrint(symName),qPrint(pattern),i);
217 return true;
218 }
219 }
220 }
221 }
222 //printf("--> name=%s: no match\n",name);
223 return false;
224}
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
const std::string & str() const
Definition dstring.h:645
Class representing a regular expression.
Definition regex.h:39
Object representing the matching results.
Definition regex.h:154
bool isId(char c)
Returns true if c is a valid character for an identifier.
Definition dstring.h:895
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:850
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:861

References DString::at(), Config_getList, DString::empty(), DString::find(), isId(), DString::left(), DString::length(), DString::mid(), DefinitionImpl::name(), DString::npos, reg::search(), DString::str(), and substitute().

Referenced by DefinitionImpl::DefinitionImpl().

◆ readCodeFragment()

bool readCodeFragment ( const DString & fileName,
bool isMacro,
int & startLine,
int & endLine,
DString & 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.

The result is returned as a string via result. The function returns true if successful and false in case of an error.

Definition at line 760 of file definition.cpp.

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

References DString::at(), Config_getBool, Config_getInt, DString::data(), DString::empty(), err, DString::fill(), Debug::FilterOutput, getEncoding(), FilterCache::getFileContents(), getFileFilter(), getLanguageFromFileName(), FilterCache::instance(), DString::length(), DString::npos, Debug::print(), DString::resize(), DString::rfind(), DString::str(), and transcodeCharacterStringToUTF8().

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

◆ refMapToVector()

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

Definition at line 1088 of file definition.cpp.

1089{
1090 // convert map to a vector of values
1091 MemberVector result;
1092 std::transform(map.begin(),map.end(), // iterate over map
1093 std::back_inserter(result), // add results to vector
1094 [](const auto &item)
1095 { return item.second; } // extract value to add from map Key,Value pair
1096 );
1097 // and sort it
1098 std::stable_sort(result.begin(),result.end(),
1099 [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; });
1100 return result;
1101}
A vector of MemberDef object.
Definition memberlist.h:36
iterator end() noexcept
Definition memberlist.h:57
iterator begin() noexcept
Definition memberlist.h:55

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

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

◆ removeFromMap()

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

Definition at line 241 of file definition.cpp.

242{
243 Doxygen::symbolMap->remove(name,d);
244}
void remove(const DString &name, Ptr def)
Remove a symbol def from the map that was stored under key name.
Definition symbolmap.h:54

References DefinitionImpl::name(), SymbolMap< T >::remove(), and Doxygen::symbolMap.

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

◆ stripWord()

bool stripWord ( DString & s,
DString w )
static

Definition at line 1593 of file definition.cpp.

1594{
1595 bool success=false;
1596 if (s.left(w.length())==w)
1597 {
1598 success=true;
1599 s=s.mid(w.length());
1600 }
1601 return success;
1602}

References DString::left(), DString::length(), and DString::mid().

Referenced by abbreviate().

◆ toDefinition()

◆ toDefinitionMutable()

DefinitionMutable * toDefinitionMutable ( Definition * d)

Variable Documentation

◆ g_memberReferenceMutex

std::mutex g_memberReferenceMutex
static