Doxygen
Loading...
Searching...
No Matches
definition.cpp File Reference
#include <algorithm>
#include <iterator>
#include <mutex>
#include <unordered_map>
#include <string>
#include <optional>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include "anchor.h"
#include "md5hash.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

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 1610 of file definition.cpp.

1611{
1612 DString scopelessName=name;
1613 if (size_t i=scopelessName.rfind("::"); i!=DString::npos) scopelessName=scopelessName.mid(i+2);
1614 DString result=s;
1615 result=result.stripWhiteSpace();
1616 // strip trailing .
1617 if (!result.empty() && result.at(result.length()-1)=='.')
1618 result=result.left(result.length()-1);
1619
1620 // strip any predefined prefix
1621 StringVector briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF);
1622 for (const auto &p : briefDescAbbrev)
1623 {
1624 DString str = substitute(p,"$name",scopelessName); // replace $name with entity name
1625 str += " ";
1626 stripWord(result,str);
1627 }
1628
1629 // capitalize first character
1630 if (!result.empty())
1631 {
1632 char c = result[0];
1633 if (c >= 'a' && c <= 'z') result[0] += 'A' - 'a';
1634 }
1635
1636 return result;
1637}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:88
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:248
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:322
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:152
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:182
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:690
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:341
DString left(size_t len) const
Definition dstring.h:310
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:155
#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:481

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

Referenced by abbreviate(), and DefinitionImpl::briefDescription().

◆ addToMap()

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

Definition at line 230 of file definition.cpp.

231{
232 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
233 DString symbolName = name;
234 int index=computeQualifiedIndex(symbolName);
235 if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
236 if (!symbolName.empty())
237 {
238 //printf("adding symbol %s\n",qPrint(symbolName));
239 Doxygen::symbolMap->add(symbolName,d);
240
241 d->_setSymbolName(symbolName);
242 }
243}
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:41
#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:5280

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

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

◆ matchExcludedSymbols()

bool matchExcludedSymbols ( const DString & name)
static

Definition at line 169 of file definition.cpp.

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

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

Referenced by DefinitionImpl::DefinitionImpl(), and matchExcludedSymbols().

◆ 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 764 of file definition.cpp.

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

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

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

◆ refMapToVector()

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

Definition at line 1092 of file definition.cpp.

1093{
1094 // convert map to a vector of values
1095 MemberVector result;
1096 std::transform(map.begin(),map.end(), // iterate over map
1097 std::back_inserter(result), // add results to vector
1098 [](const auto &item)
1099 { return item.second; } // extract value to add from map Key,Value pair
1100 );
1101 // and sort it
1102 std::stable_sort(result.begin(),result.end(),
1103 [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; });
1104 return result;
1105}
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(), MemberVector::end(), and refMapToVector().

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

◆ removeFromMap()

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

Definition at line 245 of file definition.cpp.

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

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

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

◆ stripWord()

bool stripWord ( DString & s,
DString w )
static

Definition at line 1597 of file definition.cpp.

1598{
1599 bool success=false;
1600 if (s.left(w.length())==w)
1601 {
1602 success=true;
1603 s=s.mid(w.length());
1604 }
1605 return success;
1606}

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

Referenced by abbreviate(), and stripWord().

◆ toDefinition()

Definition * toDefinition ( DefinitionMutable * dm)

◆ toDefinitionMutable()

DefinitionMutable * toDefinitionMutable ( Definition * d)

Variable Documentation

◆ g_memberReferenceMutex

std::mutex g_memberReferenceMutex
static