Doxygen
Loading...
Searching...
No Matches
util.h File Reference

A bunch of utility functions. More...

#include <src/util.h>

Include dependency graph for util.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  GetDefInput
struct  GetDefResult
struct  SelectionBlock
struct  SelectionMarkerInfo
struct  KeywordSubstitution

Typedefs

using SelectionBlockList = std::vector<SelectionBlock>
using KeywordSubstitutionList = std::vector<KeywordSubstitution>

Functions

DString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope=false)
DString fileToString (const DString &name, bool filter=false, bool isSourceCode=false)
bool readInputFile (const DString &fileName, std::string &contents, bool filter=true, bool isSourceCode=false)
 read a file name fileName and optionally filter and transcode it
DString writeInlineGraph (const DString &baseName, const DString &extension, const DString &content, bool &exists)
void cleanupInlineGraphs ()
GetDefResult getDefs (const GetDefInput &input)
DString getFileFilter (const DString &name, bool isSourceCode)
bool resolveRef (const DString &scName, const DString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecializations=true, const FileDef *currentFile=nullptr, bool checkScope=false)
bool resolveLink (const DString &scName, const DString &lr, bool inSeeBlock, const Definition **resContext, DString &resAnchor, SrcLangExt lang, const DString &prefix=DString(), const FileDef *currentFile=nullptr)
DString resolveTypeDef (const Definition *d, const DString &name, const Definition **typedefContext=nullptr)
DString externalRef (const DString &relPath, const DString &ref)
bool matchArguments2 (const Definition *srcScope, const FileDef *srcFileScope, const DString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const DString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
void mergeArguments (ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite=false)
bool matchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
DString normalizeNonTemplateArgumentsInString (const DString &name, const Definition *context, const ArgumentList &formalArgs)
DString substituteTemplateArgumentsInString (const DString &name, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
DString inlineArgListToDoc (const ArgumentList &al)
DString inlineTemplateArgListToDoc (const ArgumentList &al)
DString argListToString (const ArgumentList &al, bool useCanonicalType=false, bool showDefVals=true)
DString tempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefaults=true)
DString selectBlocks (const DString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
 remove disabled blocks and all block markers from s and return the result as a string
void checkBlocks (const DString &s, const DString fileName, const SelectionMarkerInfo &markerInfo)
DString findExampleFilePath (const DString &file, bool &ambig)
void writeExamples (OutputList &ol, const ExampleList &el)
DString stripScope (const DString &name)
DString stripAnonymousNamespaceScope (const DString &s)
DString stripFromPath (const DString &path)
DString stripFromIncludePath (const DString &path)
DString stripPath (const DString &s)
DString stripIndentation (const DString &s, bool skipFirstLine=false)
DString stripExtensionGeneral (const DString &fName, const DString &ext)
DString stripExtension (const DString &fName)
DString stripLeadingAndTrailingEmptyLines (const DString &s, int &docLine)
 Special version of DString::stripWhiteSpace() that only strips completely blank lines.
void stripIndentationVerbatim (DString &doc, size_t indentationLevel, bool skipFirstLine=true)
DString removeRedundantWhiteSpace (const DString &s)
DString detab (const DString &s, size_t &refIndent)
bool rightScopeMatch (const DString &scope, const DString &name)
bool leftScopeMatch (const DString &scope, const DString &name)
DString substituteKeywords (const DString &file, const DString &s, const KeywordSubstitutionList &keywords)
void addDirPrefix (DString &fileName)
int getPrefixIndex (const DString &name)
int computeQualifiedIndex (const DString &name)
 Return the index of the last :: in the string name that is still before the first <.
DString convertNameToFile (const DString &name, bool allowDots=false, bool allowUnderscore=false)
DString escapeCharsInString (const DString &name, bool allowDots, bool allowUnderscore=false)
DString unescapeCharsInString (const DString &s)
DString linkToText (SrcLangExt lang, const DString &link, bool ignoreDots)
DString removeAnonymousScopes (const DString &s)
DString replaceAnonymousScopes (const DString &s, const DString &replacement=DString())
DString insertTemplateSpecifierInScope (const DString &scope, const DString &templ)
DString stripTemplateSpecifiersFromScope (const DString &fullName, bool parentOnly=true, DString *lastScopeStripped=nullptr, DString scopeName=DString(), bool allowArtificial=true)
DString mergeScopes (const DString &leftScope, const DString &rightScope)
int getScopeFragment (const DString &s, int p, int *l)
DString convertToId (const DString &s)
DString convertToHtml (const DString &s, bool keepEntities=true)
DString convertToXML (const DString &s, bool keepEntities=false, bool citeEntry=false)
DString convertToJSString (const DString &s, bool keepEntities=false, bool singleQuotes=false)
bool updateLanguageMapping (const DString &extension, const DString &parser)
SrcLangExt getLanguageFromFileName (const DString &fileName, SrcLangExt defLang=SrcLangExt::Cpp)
SrcLangExt getLanguageFromCodeLang (DString &fileName)
 Routine to handle the language attribute of the \code command.
DString getFileNameExtension (const DString &fn)
void initDefaultExtensionMapping ()
void addCodeOnlyMappings ()
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
DString writeMarkerList (const std::string &markerText, size_t numMarkers, std::function< DString(size_t)> replaceFunc)
DString replaceColorMarkers (const DString &str)
 Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC, where #AABBCC represents a valid color, based on the intensity represented by hex number AA and the current HTML_COLORSTYLE_* settings.
void createSubDirs (const Dir &d)
void clearSubDirs (const Dir &d)
DString relativePathToRoot (const DString &name)
bool copyFile (const DString &src, const DString &dest)
 Copies the contents of file with name src to the newly created file with name dest.
bool openOutputFile (const DString &outFile, std::ofstream &f)
bool isURL (const DString &url)
 Checks whether the given url starts with a supported protocol.
DString correctURL (const DString &url, const DString &relPath)
 Corrects URL url according to the relative path relPath.
DString createHtmlUrl (const DString &relPath, const DString &ref, bool islocalFile, const DString &targetFileName, const DString &anchor)
DString mangleCSharpGenericName (const DString &name)
DString demangleCSharpGenericName (const DString &name, const DString &templArgs)
DString extractBeginRawStringDelimiter (const char *rawStart)
DString extractEndRawStringDelimiter (const char *rawEnd)
void extractNamespaceName (const DString &scopeName, DString &className, DString &namespaceName, bool allowEmptyClass=false)
int extractClassNameFromType (const DString &type, int &pos, DString &name, DString &templSpec, SrcLangExt=SrcLangExt::Unknown)
bool useCaseSenseNames ()
 Returns true if the names of the symbols can be case sensitive.
bool checkExtension (const DString &fName, const DString &ext)
void addHtmlExtensionIfMissing (DString &fName)
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const DString &n)
void addGroupListToTitle (OutputList &ol, const Definition *d)
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
void stackTrace ()
bool protectionLevelVisible (Protection prot)
void convertProtectionLevel (MemberListType inListType, Protection inProt, MemberListType *outListType1, MemberListType *outListType2)
 Computes for a given list type inListType, which are the the corresponding list type(s) in the base class that are to be added to this list.
DString makeBaseName (const DString &name, const DString &ext)
DString determineAbsoluteIncludeName (const DString &curFile, const DString &incFileName)
DString filterTitle (const DString &title)
DString getDotImageExtension ()
DString getDotImageExtension (const DString &format)
DString getDotImageExtensionGenerated (const DString &format)
DString externalLinkTarget (const bool parent=false)
DString getEncoding (const FileInfo &fi)
bool mainPageHasTitle ()
DString getProjectId ()
DString projectLogoFile ()
DString projectLogoSize ()
DString showDate (const DString &fmt)

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Typedef Documentation

◆ KeywordSubstitutionList

Definition at line 266 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 214 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 4163 of file util.cpp.

4164{
4165 updateLanguageMapping(".xml", "xml");
4166 updateLanguageMapping(".sql", "sql");
4167}
bool updateLanguageMapping(const DString &extension, const DString &language)
Definition util.cpp:4064

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( DString & fileName)

References parent().

◆ addGroupListToTitle()

void addGroupListToTitle ( OutputList & ol,
const Definition * d )

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( DString & fName)

Definition at line 3932 of file util.cpp.

3933{
3934 if (fName.empty()) return;
3935 size_t i_fs = fName.rfind('/');
3936 size_t i_bs = fName.rfind('\\');
3937 size_t p = i_fs!=DString::npos && i_bs!=DString::npos ? std::max(i_fs, i_bs) :
3938 i_fs!=DString::npos ? i_fs : i_bs!=DString::npos ? i_bs : 0;
3939 size_t i = fName.find('.',p); // search for . after path part
3940 if (i==DString::npos)
3941 {
3943 }
3944}
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
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
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
static DString htmlFileExtension
Definition doxygen.h:115

References DString::empty(), DString::find(), Doxygen::htmlFileExtension, DString::npos, and DString::rfind().

Referenced by HtmlCodeGenerator::_writeCodeLink(), Crawlmap::addContentsItem(), DocSets::addContentsItem(), EclipseHelp::addContentsItem(), HtmlHelp::addContentsItem(), Qhp::addContentsItem(), Crawlmap::addIndexFile(), Sitemap::addIndexFile(), common_attributes(), convertMapFile(), dumpSymbol(), field2URL(), FTVHelp::Private::generateTree(), Crawlmap::initialize(), makeFileName(), makeFileName(), makeURL(), DefinitionImpl::navigationPathAsString(), node2URL(), HtmlDocVisitor::operator()(), replaceRef(), SearchIndexExternal::setCurrentDoc(), HtmlGenerator::startFile(), HtmlGenerator::startIndexItem(), HtmlDocVisitor::startLink(), HtmlGenerator::startTextLink(), LayoutNavEntry::url(), DefinitionImpl::writeDocAnchorsToTagFile(), HtmlGenerator::writeInheritedSectionTitle(), writeJavasScriptSearchDataPage(), writeMapArea(), HtmlGenerator::writeObjectLink(), ClassDefImpl::writeQuickMemberLinks(), FileDefImpl::writeQuickMemberLinks(), GroupDefImpl::writeQuickMemberLinks(), NamespaceDefImpl::writeQuickMemberLinks(), HtmlGenerator::writeSplitBarAsString(), HtmlGenerator::writeStartAnnoItem(), HtmlGenerator::writeSummaryLink(), ClassDefImpl::writeTagFile(), ConceptDefImpl::writeTagFile(), DirDefImpl::writeTagFile(), FileDefImpl::writeTagFile(), GroupDefImpl::writeTagFile(), MemberDefImpl::writeTagFile(), ModuleDefImpl::writeTagFile(), NamespaceDefImpl::writeTagFile(), PageDefImpl::writeTagFile(), RequirementManager::writeTagFile(), VhdlDocGen::writeTagFile(), DocSets::writeToken(), HtmlCodeGenerator::writeTooltip(), and DotNode::writeUrl().

◆ argListToString()

DString argListToString ( const ArgumentList & al,
bool useCanonicalType = false,
bool showDefVals = true )

Returns a string representation of the parameter list al. If useCanonicalType is true then the canonical type is used for each argument. If showDefVals is true then default values are included in the string representation.

Definition at line 859 of file util.cpp.

860{
861 DString result;
862 if (!al.hasParameters()) return result;
863 result+="(";
864 for (auto it = al.begin() ; it!=al.end() ;)
865 {
866 Argument a = *it;
867 DString type1 = useCanonicalType && !a.canType.empty() ? a.canType : a.type;
868 DString type2;
869 if (size_t i=type1.find(")("); i!=DString::npos) // hack to deal with function pointers
870 {
871 type2=type1.mid(i);
872 type1=type1.left(i);
873 }
874 if (!a.attrib.empty())
875 {
876 result+=a.attrib+" ";
877 }
878 if (!a.name.empty() || !a.array.empty())
879 {
880 result+= type1+" "+a.name+type2+a.array;
881 }
882 else
883 {
884 result+= type1+type2;
885 }
886 if (!a.defval.empty() && showDefVals)
887 {
888 result+="="+a.defval;
889 }
890 ++it;
891 if (it!=al.end()) result+=", ";
892 }
893 result+=")";
894 if (al.constSpecifier()) result+=" const";
895 if (al.volatileSpecifier()) result+=" volatile";
896 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
897 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
898 if (!al.trailingReturnType().empty()) result+=al.trailingReturnType();
899 if (al.pureSpecifier()) result+=" =0";
900 return removeRedundantWhiteSpace(result);
901}
This class contains the information about the argument of a function or template.
Definition arguments.h:27
DString attrib
Definition arguments.h:42
DString defval
Definition arguments.h:47
DString array
Definition arguments.h:46
DString name
Definition arguments.h:45
DString type
Definition arguments.h:43
DString canType
Definition arguments.h:44
RefQualifierType refQualifier() const
Definition arguments.h:117
bool pureSpecifier() const
Definition arguments.h:114
iterator end()
Definition arguments.h:95
bool hasParameters() const
Definition arguments.h:77
DString trailingReturnType() const
Definition arguments.h:115
bool constSpecifier() const
Definition arguments.h:112
iterator begin()
Definition arguments.h:94
bool volatileSpecifier() const
Definition arguments.h:113
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
DString left(size_t len) const
Definition dstring.h:306
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:426

References Argument::array, Argument::attrib, ArgumentList::begin(), Argument::canType, ArgumentList::constSpecifier(), Argument::defval, DString::empty(), ArgumentList::end(), DString::find(), ArgumentList::hasParameters(), DString::left(), LValue, DString::mid(), Argument::name, DString::npos, ArgumentList::pureSpecifier(), ArgumentList::refQualifier(), removeRedundantWhiteSpace(), RValue, ArgumentList::trailingReturnType(), Argument::type, and ArgumentList::volatileSpecifier().

Referenced by addMemberFunction(), DocParser::checkArgumentName(), DocParser::checkUnOrMultipleDocumentedParams(), findFriends(), findGlobalMember(), findMember(), SymbolResolver::Private::getResolvedSymbol(), matchArguments2(), matchTemplateArguments(), mergeArguments(), substituteTemplateArgumentsInString(), and ClassDefImpl::title().

◆ checkBlocks()

void checkBlocks ( const DString & s,
const DString fileName,
const SelectionMarkerInfo & markerInfo )

Definition at line 5130 of file util.cpp.

5131{
5132 if (s.empty()) return;
5133
5134 const char *p = s.data();
5135 char c = 0;
5136 while ((c=*p))
5137 {
5138 if (c==markerInfo.markerChar) // potential start of marker
5139 {
5140 if (dstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
5141 {
5142 size_t len = markerInfo.beginLen;
5143 bool negate = *(p+len)=='!';
5144 if (negate) len++;
5145 p += len;
5146 DString marker;
5147 while (*p)
5148 {
5149 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
5150 {
5151 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
5152 break;
5153 }
5154 else if (markerInfo.closeLen!= 0 && dstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5155 {
5156 p += markerInfo.closeLen;
5157 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
5158 break;
5159 }
5160 marker += *p;
5161 p++;
5162 }
5163 }
5164 else if (dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
5165 {
5166 size_t len = markerInfo.endLen;
5167 bool negate = *(p+len)=='!';
5168 if (negate) len++;
5169 p += len;
5170 DString marker;
5171 while (*p)
5172 {
5173 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
5174 {
5175 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
5176 break;
5177 }
5178 else if (markerInfo.closeLen!= 0 && dstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5179 {
5180 p += markerInfo.closeLen;
5181 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
5182 break;
5183 }
5184 marker += *p;
5185 p++;
5186 }
5187 }
5188 }
5189 p++;
5190 }
5191}
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
int dstrncmp(const char *str1, const char *str2, size_t len)
Definition dstring.h:56
#define warn(file, line, fmt,...)
Definition message.h:97
size_t beginLen
Definition util.h:220
const char * closeStr
Definition util.h:223
const char * beginStr
Definition util.h:219
size_t closeLen
Definition util.h:224
const char * endStr
Definition util.h:221

References SelectionMarkerInfo::beginLen, SelectionMarkerInfo::beginStr, SelectionMarkerInfo::closeLen, SelectionMarkerInfo::closeStr, DString::data(), dstrncmp(), DString::empty(), SelectionMarkerInfo::endLen, SelectionMarkerInfo::endStr, SelectionMarkerInfo::markerChar, and warn.

Referenced by HtmlGenerator::init(), and LatexGenerator::init().

◆ checkExtension()

bool checkExtension ( const DString & fName,
const DString & ext )

Definition at line 3927 of file util.cpp.

3928{
3929 return fName.right(ext.length())==ext;
3930}
DString right(size_t len) const
Definition dstring.h:311
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151

References DString::length(), and DString::right().

Referenced by copyLatexStyleSheet(), and extraLatexStyleSheet().

◆ checkIfTypedef()

bool checkIfTypedef ( const Definition * scope,
const FileDef * fileScope,
const DString & n )

Returns true iff the given name string appears to be a typedef in scope.

Definition at line 4272 of file util.cpp.

4273{
4274 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
4275
4276 if (bestMatch && bestMatch->isTypedef())
4277 return true; // closest matching symbol is a typedef
4278 else
4279 return false;
4280}
A model of a class/file/namespace member symbol.
Definition memberdef.h:45
virtual bool isTypedef() const =0
static MemberDef * getMemberFromSymbol(const Definition *scope, const FileDef *fileScope, const DString &n)
Definition util.cpp:4220

References getMemberFromSymbol(), and MemberDef::isTypedef().

Referenced by isVarWithConstructor().

◆ cleanupInlineGraphs()

void cleanupInlineGraphs ( )

Deletes all graph files written with writeInlineGraph()

Definition at line 5399 of file util.cpp.

5400{
5401 if (Config_getBool(DOT_CLEANUP))
5402 {
5403 for (const auto& fileName: writeFileContents_set)
5404 {
5405 Dir().remove(qPrint(fileName));
5406 }
5407 }
5408}
Class representing a directory in the file system.
Definition dir.h:73
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:320
#define Config_getBool(name)
Definition config.h:33
const char * qPrint(const char *s)
Definition dstring.h:783
static StringUnorderedSet writeFileContents_set
Definition util.cpp:5372

References Config_getBool, qPrint(), Dir::remove(), and writeFileContents_set.

Referenced by generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 2997 of file util.cpp.

2998{
2999 if (Config_getBool(CREATE_SUBDIRS))
3000 {
3001 // remove empty subdirectories
3002 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3003 for (int l1=0;l1<16;l1++)
3004 {
3005 DString subdir;
3006 subdir.sprintf("d%x",l1);
3007 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3008 {
3009 DString subsubdir;
3010 subsubdir.sprintf("d%x/d%02x",l1,l2);
3011 if (d.exists(subsubdir.str()) && d.empty(subsubdir.str()))
3012 {
3013 d.rmdir(subsubdir.str());
3014 }
3015 }
3016 if (d.exists(subdir.str()) && d.empty(subdir.str()))
3017 {
3018 d.rmdir(subdir.str());
3019 }
3020 }
3021 }
3022}
DString & sprintf(const char *format,...)
Definition dstring.cpp:34
const std::string & str() const
Definition dstring.h:645
bool empty(const std::string &subdir) const
Definition dir.cpp:269
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:315
bool exists() const
Definition dir.cpp:263
#define Config_getInt(name)
Definition config.h:34

References Config_getBool, Config_getInt, Dir::empty(), Dir::exists(), Dir::rmdir(), DString::sprintf(), and DString::str().

Referenced by DocbookGenerator::cleanup(), HtmlGenerator::cleanup(), LatexGenerator::cleanup(), ManGenerator::cleanup(), RTFGenerator::cleanup(), and generateXML().

◆ computeQualifiedIndex()

int computeQualifiedIndex ( const DString & name)

Return the index of the last :: in the string name that is still before the first <.

Definition at line 5294 of file util.cpp.

5295{
5296 int l = static_cast<int>(name.length());
5297 int lastSepPos = -1;
5298 const char *p = name.data();
5299 int i=l-2;
5300 int sharpCount=0;
5301 // --- begin optimized version of ts=name.findRev(">::");
5302 int ts = -1;
5303 while (i>=0)
5304 {
5305 if (p[i]=='>')
5306 {
5307 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
5308 {
5309 ts=i;
5310 break;
5311 }
5312 sharpCount++;
5313 }
5314 else if (p[i]=='<')
5315 {
5316 sharpCount--;
5317 }
5318 i--;
5319 }
5320 // --- end optimized version
5321 if (ts==-1) ts=0; else p+=++ts;
5322 for (i=ts;i<l-1;i++)
5323 {
5324 char c=*p++;
5325 if (c==':' && *p==':') lastSepPos=i;
5326 if (c=='<') break;
5327 }
5328 return lastSepPos;
5329}

References DString::data(), and DString::length().

Referenced by addToMap(), addVariable(), buildFunctionList(), buildTypedefList(), getMemberFromSymbol(), SymbolResolver::Private::getResolvedSymbolRec(), and SymbolResolver::Private::getResolvedTypeRec().

◆ convertNameToFile()

DString convertNameToFile ( const DString & name,
bool allowDots,
bool allowUnderscore )

This function determines the file name on disk of an item given its name, which could be a class name with template arguments, so special characters need to be escaped.

Definition at line 2864 of file util.cpp.

2865{
2866 if (name.empty()) return name;
2867 bool shortNames = Config_getBool(SHORT_NAMES);
2868 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
2869 DString result;
2870 if (shortNames) // use short names only
2871 {
2872 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
2873 auto kv = g_usedNames.find(name.str());
2874 uint32_t num=0;
2875 if (kv!=g_usedNames.end())
2876 {
2877 num = kv->second;
2878 }
2879 else
2880 {
2881 num = g_usedNamesCount;
2882 g_usedNames.emplace(name.str(),g_usedNamesCount++);
2883 }
2884 result.sprintf("a%05d",num);
2885 }
2886 else // long names
2887 {
2888 result=escapeCharsInString(name,allowDots,allowUnderscore);
2889 size_t resultLen = result.length();
2890 if (resultLen>=128) // prevent names that cannot be created!
2891 {
2892 // third algorithm based on MD5 hash
2893 result=result.left(128-32)+md5str(result.view());
2894 }
2895 }
2896 if (createSubdirs)
2897 {
2898 int l1Dir=0,l2Dir=0;
2899 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
2900 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
2901
2902 // compute md5 hash to determine sub directory to use
2903 auto md5_sig = md5hash(result.view());
2904 l1Dir = md5_sig[14] & 0xf;
2905 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
2906
2907 result.prepend(DString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
2908 }
2909 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
2910 return result;
2911}
std::string_view view() const
Definition dstring.h:162
DString & prepend(const char *s)
Definition dstring.h:515
DString md5str(const std::string_view &str)
Definition md5hash.h:33
std::array< uint8_t, 16 > md5hash(const std::string_view &str)
Definition md5hash.h:26
static int g_usedNamesCount
Definition util.cpp:2856
DString escapeCharsInString(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2689
static std::mutex g_usedNamesMutex
Definition util.cpp:2855
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:2854

References Config_getBool, Config_getInt, DString::empty(), escapeCharsInString(), g_usedNames, g_usedNamesCount, g_usedNamesMutex, DString::left(), DString::length(), md5hash(), md5str(), DString::prepend(), DString::sprintf(), DString::str(), and DString::view().

Referenced by addRelatedPage(), buildExampleList(), ClassDefImpl::ClassDefImpl(), ClassDefImpl::deepCopy(), DocAnchor::DocAnchor(), DocCite::DocCite(), ModuleDefImpl::getOutputFileBase(), DocParser::handleAHref(), PageDefImpl::PageDefImpl(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), VHDLCodeParser::parseCode(), RefList::RefList(), FileDefImpl::setDiskNameLocal(), NamespaceDefImpl::setFileNameLocal(), and xmlRequirementId().

◆ convertProtectionLevel()

void convertProtectionLevel ( MemberListType inListType,
Protection inProt,
MemberListType * outListType1,
MemberListType * outListType2 )

Computes for a given list type inListType, which are the the corresponding list type(s) in the base class that are to be added to this list.

So for public inheritance, the mapping is 1-1, so outListType1=inListType Private members are to be hidden completely.

For protected inheritance, both protected and public members of the base class should be joined in the protected member section.

For private inheritance, both protected and public members of the base class should be joined in the private member section.

Definition at line 4905 of file util.cpp.

4911{
4912 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4913
4914 // default representing 1-1 mapping
4915 *outListType1=inListType;
4916 *outListType2=MemberListType::Invalid();
4917
4918 if (inProt==Protection::Public)
4919 {
4920 if (inListType.isPrivate())
4921 {
4922 *outListType1=MemberListType::Invalid();
4923 }
4924 }
4925 else if (inProt==Protection::Protected)
4926 {
4927 if (inListType.isPrivate() || inListType.isPublic())
4928 {
4929 *outListType1=MemberListType::Invalid();
4930 }
4931 else if (inListType.isProtected())
4932 {
4933 *outListType2=inListType.toPublic();
4934 }
4935 }
4936 else if (inProt==Protection::Private)
4937 {
4938 if (inListType.isPublic() || inListType.isProtected())
4939 {
4940 *outListType1=MemberListType::Invalid();
4941 }
4942 else if (inListType.isPrivate())
4943 {
4944 if (extractPrivate)
4945 {
4946 *outListType1=inListType.toPublic();
4947 *outListType2=inListType.toProtected();
4948 }
4949 else
4950 {
4951 *outListType1=MemberListType::Invalid();
4952 }
4953 }
4954 }
4955
4956 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
4957 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
4958}
constexpr bool isPrivate() const noexcept
Definition types.h:382
constexpr MemberListType toPublic() const noexcept
Definition types.h:426
static constexpr MemberListType Invalid() noexcept
Definition types.h:371
constexpr MemberListType toProtected() const noexcept
Definition types.h:438
constexpr bool isProtected() const noexcept
Definition types.h:380
ML_TYPES constexpr bool isPublic() const noexcept
Definition types.h:378

References Config_getBool, MemberListType::Invalid(), MemberListType::isPrivate(), MemberListType::isProtected(), MemberListType::isPublic(), MemberListType::toProtected(), and MemberListType::toPublic().

Referenced by ClassDefImpl::countInheritedDecMembers(), and ClassDefImpl::writeInheritedMemberDeclarations().

◆ convertToHtml()

DString convertToHtml ( const DString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 3292 of file util.cpp.

3293{
3294 if (s.empty()) return s;
3295 DString result;
3296 result.reserve(s.length()+32);
3297 const char *p=s.data();
3298 char c = 0;
3299 while ((c=*p++))
3300 {
3301 switch (c)
3302 {
3303 case '<': result+="&lt;"; break;
3304 case '>': result+="&gt;"; break;
3305 case '&': if (keepEntities)
3306 {
3307 const char *e=p;
3308 char ce = 0;
3309 while ((ce=*e++))
3310 {
3311 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3312 }
3313 if (ce==';') // found end of an entity
3314 {
3315 // copy entry verbatim
3316 result+=c;
3317 while (p<e) result+=*p++;
3318 }
3319 else
3320 {
3321 result+="&amp;";
3322 }
3323 }
3324 else
3325 {
3326 result+="&amp;";
3327 }
3328 break;
3329 case '\'': result+="&#39;"; break;
3330 case '"': result+="&quot;"; break;
3331 default:
3332 {
3333 uint8_t uc = static_cast<uint8_t>(c);
3334 if (uc<32 && !isspace(c))
3335 {
3336 result+="&#x24";
3337 result+=hex[uc>>4];
3338 result+=hex[uc&0xF];
3339 result+=';';
3340 }
3341 else
3342 {
3343 result+=c;
3344 }
3345 }
3346 break;
3347 }
3348 }
3349 return result;
3350}
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition dstring.h:217
bool isId(char c)
Returns true if c is a valid character for an identifier.
Definition dstring.h:895
static const char * hex
Definition util.cpp:80

References DString::data(), DString::empty(), hex, isId(), DString::length(), and DString::reserve().

Referenced by HtmlCodeGenerator::_writeCodeLink(), HtmlHelp::addContentsItem(), addMembersToIndex(), convertToHtmlAndTruncate(), FTVHelp::Private::generateLink(), DefinitionImpl::navigationPathAsString(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlGenerator::startFile(), HtmlDocVisitor::startLink(), substituteHtmlKeywords(), writeClassTree(), writeClassTreeForList(), writeClassTreeToOutput(), HtmlHelpIndex::writeFields(), HtmlGenerator::writeInheritedSectionTitle(), HtmlGenerator::writeLogoAsString(), writeMapArea(), HtmlGenerator::writePageFooter(), ClassDefImpl::writeQuickMemberLinks(), FileDefImpl::writeQuickMemberLinks(), GroupDefImpl::writeQuickMemberLinks(), NamespaceDefImpl::writeQuickMemberLinks(), and HtmlGenerator::writeSearchPage().

◆ convertToId()

DString convertToId ( const DString & s)

Converts a string to a HTML id string

Definition at line 3203 of file util.cpp.

3204{
3205 if (s.empty()) return s;
3206 DString result;
3207 result.reserve(s.length()+8);
3208 const char *p = s.data();
3209 char c = 0;
3210 bool first = true;
3211 while ((c=*p++))
3212 {
3213 char encChar[4];
3214 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3215 { // any permissive character except _
3216 if (first && c>='0' && c<='9') result+='a'; // don't start with a digit
3217 result+=c;
3218 }
3219 else
3220 {
3221 encChar[0]='_';
3222 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3223 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3224 encChar[3]=0;
3225 result+=encChar;
3226 }
3227 first=false;
3228 }
3229 return result;
3230}

References DString::data(), DString::empty(), hex, DString::length(), and DString::reserve().

Referenced by HtmlGenerator::endClassDiagram(), HtmlGenerator::endMemberTemplateParams(), HtmlGenerator::startGroupHeader(), HtmlGenerator::startMemberItem(), writeMemberList(), writeQuickMemberIndex(), ClassDefImpl::writeSummaryLinks(), and VhdlDocGen::writeVHDLDeclarations().

◆ convertToJSString()

DString convertToJSString ( const DString & s,
bool keepEntities = false,
bool singleQuotes = false )

Definition at line 3352 of file util.cpp.

3353{
3354 if (s.empty()) return s;
3355 DString result;
3356 result.reserve(s.length()+32);
3357 const char *p=s.data();
3358 char c = 0;
3359 while ((c=*p++))
3360 {
3361 switch (c)
3362 {
3363 case '"': if (!singleQuotes) result+="\\\""; else result+=c;
3364 break;
3365 case '\'': if (singleQuotes) result+="\\\'"; else result+=c;
3366 break;
3367 case '\\': if (*p=='u' && *(p+1)=='{') result+="\\"; // keep \u{..} unicode escapes
3368 else result+="\\\\";
3369 break;
3370 default: result+=c; break;
3371 }
3372 }
3373 return keepEntities ? result : HtmlEntityMapper::instance().convertCharEntitiesToUTF8(result);
3374}
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
DString convertCharEntitiesToUTF8(const DString &s) const

References HtmlEntityMapper::convertCharEntitiesToUTF8(), DString::data(), DString::empty(), HtmlEntityMapper::instance(), DString::length(), and DString::reserve().

Referenced by generateJSLink(), generateJSNavTree(), writeJavascriptSearchData(), and writeJavasScriptSearchDataPage().

◆ convertToXML()

DString convertToXML ( const DString & s,
bool keepEntities,
const bool citeEntry )

Converts a string to an XML-encoded string

Definition at line 3233 of file util.cpp.

3234{
3235 if (s.empty()) return s;
3236 DString result;
3237 result.reserve(s.length()+32);
3238 const char *p = s.data();
3239 char c = 0;
3240 while ((c=*p++))
3241 {
3242 switch (c)
3243 {
3244 case '<': result+="&lt;"; break;
3245 case '>': result+="&gt;"; break;
3246 case '&': if (keepEntities)
3247 {
3248 const char *e=p;
3249 char ce = 0;
3250 while ((ce=*e++))
3251 {
3252 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3253 }
3254 if (ce==';') // found end of an entity
3255 {
3256 // copy entry verbatim
3257 result+=c;
3258 while (p<e) result+=*p++;
3259 }
3260 else
3261 {
3262 result+="&amp;";
3263 }
3264 }
3265 else if (citeEntry)
3266 {
3268 result,
3269 p-1,
3270 [](HtmlEntityMapper::SymType symType) { return HtmlEntityMapper::instance().xml(symType); },
3271 "&amp;");
3272 }
3273 else
3274 {
3275 result+="&amp;";
3276 }
3277 break;
3278 case '\'': result+="&apos;"; break;
3279 case '"': result+="&quot;"; break;
3280 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
3281 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
3282 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
3283 case 27: case 28: case 29: case 30: case 31:
3284 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
3285 default: result+=c; break;
3286 }
3287 }
3288 return result;
3289}
const char * writeHtmlEntity(T &result, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback)
Definition htmlentity.h:127
const char * xml(SymType symb) const
Access routine to the XML code of the HTML entity.

References DString::data(), DString::empty(), HtmlEntityMapper::instance(), isId(), DString::length(), DString::reserve(), HtmlEntityMapper::writeHtmlEntity(), and HtmlEntityMapper::xml().

Referenced by DocSets::addContentsItem(), EclipseHelp::addContentsItem(), Qhp::addFile(), Sitemap::addIndexFile(), Qhp::addIndexItem(), XmlDocVisitor::filter(), generateXMLForClass(), generateXMLForConcept(), generateXMLForDir(), generateXMLForFile(), generateXMLForGroup(), generateXMLForMember(), generateXMLForModule(), generateXMLForNamespace(), generateXMLForPage(), generateXMLForRequirement(), generateXMLForRequirements(), generateXMLSection(), DotDirDeps::getImgAltText(), EclipseHelp::initialize(), Qhp::initialize(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), HtmlAttribList::toString(), QhpSectionTree::traverse(), visitPreStart(), SearchIndexExternal::write(), FileDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeConceptsToTagFile(), DefinitionImpl::writeDocAnchorsToTagFile(), DotNode::writeDocbook(), DotGraph::writeGraphHeader(), writeInnerClasses(), writeInnerConcepts(), writeInnerDirs(), writeInnerFiles(), writeInnerGroups(), writeInnerModules(), writeInnerNamespaces(), writeInnerPages(), writeJavascriptSearchData(), writeJavasScriptSearchDataPage(), DotNode::writeLabel(), writeListOfAllMembers(), writeMapArea(), writeMemberReference(), writeRequirementRefs(), ClassDefImpl::writeTagFile(), ConceptDefImpl::writeTagFile(), DirDefImpl::writeTagFile(), FileDefImpl::writeTagFile(), GroupDefImpl::writeTagFile(), MemberDefImpl::writeTagFile(), ModuleDefImpl::writeTagFile(), NamespaceDefImpl::writeTagFile(), PageDefImpl::writeTagFile(), RequirementManager::writeTagFile(), VhdlDocGen::writeTagFile(), writeTemplateArgumentList(), DocSets::writeToken(), DotNode::writeXML(), writeXMLLink(), and writeXMLString().

◆ copyFile()

bool copyFile ( const DString & src,
const DString & dest )

Copies the contents of file with name src to the newly created file with name dest.

Copies the file src to dest. Returns true if the copy was successful, false otherwise. When a relative path is used, is is based on the current working directory.

Returns true if successful.

Definition at line 4620 of file util.cpp.

4621{
4622 if (!Dir().copy(src.str(),dest.str()))
4623 {
4624 err("could not copy file {} to {}\n",src,dest);
4625 return false;
4626 }
4627 return true;
4628}
#define err(fmt,...)
Definition message.h:127

References err, and DString::str().

Referenced by copyExtraFiles(), copyIcon(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), DocParser::findAndCopyImage(), FormulaManager::generateImages(), CitationManager::generatePage(), RTFGenerator::init(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), and substituteLatexKeywords().

◆ correctURL()

DString correctURL ( const DString & url,
const DString & relPath )

Corrects URL url according to the relative path relPath.

Returns the corrected URL. For absolute URLs no correction will be done.

Definition at line 4660 of file util.cpp.

4661{
4662 DString result = url;
4663 if (!relPath.empty() && !isURL(url))
4664 {
4665 result.prepend(relPath);
4666 }
4667 return result;
4668}
bool isURL(const DString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:4647

References DString::empty(), isURL(), and DString::prepend().

Referenced by HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), XmlDocVisitor::operator()(), and startQuickIndexItem().

◆ createHtmlUrl()

DString createHtmlUrl ( const DString & relPath,
const DString & ref,
bool islocalFile,
const DString & targetFileName,
const DString & anchor )

Definition at line 4503 of file util.cpp.

4508{
4509 DString url;
4510 if (!ref.empty())
4511 {
4512 url = externalRef(relPath,ref);
4513 }
4514 if (!targetFileName.empty())
4515 {
4516 DString fn = targetFileName;
4517 if (ref.empty())
4518 {
4519 if (!anchor.empty() && isLocalFile)
4520 {
4521 fn=""; // omit file name for local links
4522 }
4523 else
4524 {
4525 url = relPath;
4526 }
4527 }
4528 url+=fn;
4529 }
4530 if (!anchor.empty())
4531 {
4532 if (!url.endsWith("=")) url+="#";
4533 url+=anchor;
4534 }
4535 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
4536 return url;
4537}
bool endsWith(const char *s) const
Definition dstring.h:617
DString externalRef(const DString &relPath, const DString &ref)
Definition util.cpp:4539

References DString::empty(), DString::endsWith(), and externalRef().

Referenced by HtmlCodeGenerator::_writeCodeLink(), RequirementManager::generatePage(), HtmlDocVisitor::startLink(), HtmlGenerator::startTextLink(), HtmlGenerator::writeObjectLink(), and HtmlCodeGenerator::writeTooltip().

◆ createSubDirs()

void createSubDirs ( const Dir & d)

Definition at line 2970 of file util.cpp.

2971{
2972 if (Config_getBool(CREATE_SUBDIRS))
2973 {
2974 // create up to 4096 subdirectories
2975 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
2976 for (int l1=0; l1<16; l1++)
2977 {
2978 DString subdir;
2979 subdir.sprintf("d%x",l1);
2980 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
2981 {
2982 term("Failed to create output directory '{}'\n",subdir);
2983 }
2984 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
2985 {
2986 DString subsubdir;
2987 subsubdir.sprintf("d%x/d%02x",l1,l2);
2988 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
2989 {
2990 term("Failed to create output directory '{}'\n",subsubdir);
2991 }
2992 }
2993 }
2994 }
2995}
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:301
#define term(fmt,...)
Definition message.h:137

References Config_getBool, Config_getInt, Dir::exists(), Dir::mkdir(), DString::sprintf(), DString::str(), and term.

Referenced by generateXML(), DocbookGenerator::init(), HtmlGenerator::init(), LatexGenerator::init(), ManGenerator::init(), RTFGenerator::init(), ClassDefImpl::writeQuickMemberLinks(), FileDefImpl::writeQuickMemberLinks(), GroupDefImpl::writeQuickMemberLinks(), and NamespaceDefImpl::writeQuickMemberLinks().

◆ demangleCSharpGenericName()

DString demangleCSharpGenericName ( const DString & name,
const DString & templArgs )

Definition at line 5344 of file util.cpp.

5345{
5346 DString result=name;
5347 if (result.endsWith("-g"))
5348 {
5349 size_t idx = result.find('-');
5350 result = result.left(idx)+templArgs;
5351 }
5352 return result;
5353}

References DString::endsWith(), DString::find(), and DString::left().

Referenced by ClassDefImpl::className().

◆ detab()

DString detab ( const DString & s,
size_t & refIndent )

Definition at line 5195 of file util.cpp.

5196{
5197 int tabSize = Config_getInt(TAB_SIZE);
5198 size_t size = s.length();
5199 DString result;
5200 result.reserve(size+256);
5201 const char *data = s.data();
5202 size_t i=0;
5203 int col=0;
5204 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
5205 const int maxIndent=1000000; // value representing infinity
5206 int minIndent=maxIndent;
5207 bool skip = false;
5208 while (i<size)
5209 {
5210 char c = data[i++];
5211 switch(c)
5212 {
5213 case '\t': // expand tab
5214 {
5215 int stop = tabSize - (col%tabSize);
5216 //printf("expand at %d stop=%d\n",col,stop);
5217 col+=stop;
5218 while (stop--) result+=' ';
5219 }
5220 break;
5221 case '\\':
5222 if (data[i] == '\\') // escaped command -> ignore
5223 {
5224 result+=c;
5225 result+=data[i++];
5226 col+=2;
5227 }
5228 else if (i+5<size && literal_at(data+i,"iskip")) // command
5229 {
5230 i+=5;
5231 skip = true;
5232 }
5233 else if (i+8<size && literal_at(data+i,"endiskip")) // command
5234 {
5235 i+=8;
5236 skip = false;
5237 }
5238 else // some other command
5239 {
5240 result+=c;
5241 col++;
5242 }
5243 break;
5244 case '\n': // reset column counter
5245 result+=c;
5246 col=0;
5247 break;
5248 case ' ': // increment column counter
5249 result+=c;
5250 col++;
5251 break;
5252 default: // non-whitespace => update minIndent
5253 if (static_cast<signed char>(c)<0 && i<size) // multibyte sequence
5254 {
5255 // special handling of the UTF-8 nbsp character 0xC2 0xA0
5256 int nb = isUTF8NonBreakableSpace(data);
5257 if (nb>0)
5258 {
5259 result+=doxy_nbsp;
5260 i+=nb-1;
5261 }
5262 else
5263 {
5264 int bytes = getUTF8CharNumBytes(c);
5265 for (int j=0;j<bytes-1 && c;j++)
5266 {
5267 result+=c;
5268 c = data[i++];
5269 }
5270 result+=c;
5271 }
5272 }
5273 else
5274 {
5275 result+=c;
5276 }
5277 if (!skip && col<minIndent) minIndent=col;
5278 col++;
5279 }
5280 }
5281 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
5282 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
5283 return result;
5284}
bool literal_at(const char *data, const char(&str)[N])
returns true iff data points to a substring that matches string literal str
Definition stringutil.h:101
int isUTF8NonBreakableSpace(const char *input)
Check if the first character pointed at by input is a non-breakable whitespace character.
Definition utf8.cpp:232
uint8_t getUTF8CharNumBytes(char c)
Returns the number of bytes making up a single UTF8 character given the first byte in the sequence.
Definition utf8.cpp:27

References Config_getInt, DString::data(), getUTF8CharNumBytes(), isUTF8NonBreakableSpace(), DString::length(), literal_at(), and DString::reserve().

Referenced by FileDefImpl::parseSource(), Markdown::process(), DocParser::readTextFileByName(), readTextFileByName(), MemberDefImpl::setInitializer(), DefinitionImpl::writeInlineCode(), and FileDefImpl::writeSourceBody().

◆ determineAbsoluteIncludeName()

DString determineAbsoluteIncludeName ( const DString & curFile,
const DString & incFileName )

Definition at line 2930 of file util.cpp.

2931{
2932 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
2933 DString absIncFileName = incFileName;
2934 FileInfo fi(curFile.str());
2935 if (fi.exists())
2936 {
2937 DString absName = fi.dirPath(true)+"/"+incFileName;
2938 FileInfo fi2(absName.str());
2939 if (fi2.exists())
2940 {
2941 absIncFileName=fi2.absFilePath();
2942 }
2943 else if (searchIncludes) // search in INCLUDE_PATH as well
2944 {
2945 StringVector includePath = Config_getList(INCLUDE_PATH);
2946 for (const auto &incPath : includePath)
2947 {
2948 FileInfo fi3(incPath);
2949 if (fi3.exists() && fi3.isDir())
2950 {
2951 absName = fi3.absFilePath()+"/"+incFileName;
2952 //printf("trying absName=%s\n",qPrint(absName));
2953 FileInfo fi4(absName.str());
2954 if (fi4.exists())
2955 {
2956 absIncFileName=fi4.absFilePath();
2957 break;
2958 }
2959 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
2960 }
2961 }
2962 }
2963 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
2964 }
2965 return absIncFileName;
2966}
Minimal replacement for QFileInfo.
Definition fileinfo.h:26
#define Config_getList(name)
Definition config.h:38
std::vector< std::string > StringVector
Definition containers.h:33

References FileInfo::absFilePath(), Config_getBool, Config_getList, FileInfo::dirPath(), FileInfo::exists(), FileInfo::isDir(), and DString::str().

Referenced by readIncludeFile(), and ModuleManager::resolveImports().

◆ escapeCharsInString()

DString escapeCharsInString ( const DString & name,
bool allowDots,
bool allowUnderscore = false )

Definition at line 2689 of file util.cpp.

2690{
2691 if (name.empty()) return name;
2692 bool caseSenseNames = useCaseSenseNames();
2693 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
2694 DString result;
2695 result.reserve(name.length()+8);
2696 signed char c = 0;
2697 const char *p=name.data();
2698 while ((c=*p++)!=0)
2699 {
2700 switch(c)
2701 {
2702 case '_': if (allowUnderscore) result+='_'; else result+="__"; break;
2703 case '-': result+='-'; break;
2704 case ':': result+="_1"; break;
2705 case '/': result+="_2"; break;
2706 case '<': result+="_3"; break;
2707 case '>': result+="_4"; break;
2708 case '*': result+="_5"; break;
2709 case '&': result+="_6"; break;
2710 case '|': result+="_7"; break;
2711 case '.': if (allowDots) result+='.'; else result+="_8"; break;
2712 case '!': result+="_9"; break;
2713 case ',': result+="_00"; break;
2714 case ' ': result+="_01"; break;
2715 case '{': result+="_02"; break;
2716 case '}': result+="_03"; break;
2717 case '?': result+="_04"; break;
2718 case '^': result+="_05"; break;
2719 case '%': result+="_06"; break;
2720 case '(': result+="_07"; break;
2721 case ')': result+="_08"; break;
2722 case '+': result+="_09"; break;
2723 case '=': result+="_0a"; break;
2724 case '$': result+="_0b"; break;
2725 case '\\': result+="_0c"; break;
2726 case '@': result+="_0d"; break;
2727 case ']': result+="_0e"; break;
2728 case '[': result+="_0f"; break;
2729 case '#': result+="_0g"; break;
2730 case '"': result+="_0h"; break;
2731 case '~': result+="_0i"; break;
2732 case '\'': result+="_0j"; break;
2733 case ';': result+="_0k"; break;
2734 case '`': result+="_0l"; break;
2735 default:
2736 if (c<0)
2737 {
2738 bool doEscape = true;
2739 if (allowUnicodeNames)
2740 {
2741 int charLen = getUTF8CharNumBytes(c);
2742 if (charLen>0)
2743 {
2744 result+=DString(p-1,charLen);
2745 p+=charLen;
2746 doEscape = false;
2747 }
2748 }
2749 if (doEscape) // not a valid unicode char or escaping needed
2750 {
2751 char ids[5];
2752 unsigned char id = static_cast<unsigned char>(c);
2753 ids[0]='_';
2754 ids[1]='x';
2755 ids[2]=hex[id>>4];
2756 ids[3]=hex[id&0xF];
2757 ids[4]=0;
2758 result+=ids;
2759 }
2760 }
2761 else if (caseSenseNames || !isupper(c))
2762 {
2763 result+=c;
2764 }
2765 else
2766 {
2767 result+='_';
2768 result+=static_cast<char>(tolower(c));
2769 }
2770 break;
2771 }
2772 }
2773 return result;
2774}
bool useCaseSenseNames()
Returns true if the names of the symbols can be case sensitive.
Definition util.cpp:2680

References Config_getBool, DString::data(), DString::empty(), getUTF8CharNumBytes(), hex, DString::length(), DString::reserve(), and useCaseSenseNames().

Referenced by convertNameToFile(), DotClassGraph::getMapLabel(), DotDirDeps::getMapLabel(), DotGfxHierarchyTable::getMapLabel(), DotGroupCollaboration::getMapLabel(), DotInclDepGraph::getMapLabel(), markdownFileNameToId(), and PageDefImpl::writeDocumentation().

◆ externalLinkTarget()

DString externalLinkTarget ( const bool parent = false)

Definition at line 4492 of file util.cpp.

4493{
4494 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
4495 if (extLinksInWindow)
4496 return "target=\"_blank\" ";
4497 else if (parent)
4498 return "target=\"_parent\" ";
4499 else
4500 return "";
4501}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1335

References Config_getBool, and parent().

Referenced by HtmlCodeGenerator::_writeCodeLink(), FTVHelp::Private::generateLink(), Markdown::Private::processLink(), replaceRef(), HtmlGenerator::startIndexItem(), HtmlDocVisitor::startLink(), HtmlGenerator::writeInheritedSectionTitle(), writeMapArea(), and HtmlGenerator::writeObjectLink().

◆ externalRef()

DString externalRef ( const DString & relPath,
const DString & ref )

Resolve a reference via a tagfile reference ref. If after resolving the reference the result points to a relative path then relPath is prepended to create the correct link.

Definition at line 4539 of file util.cpp.

4540{
4541 DString result;
4542 if (!ref.empty())
4543 {
4544 auto it = Doxygen::tagDestinationMap.find(ref.str());
4546 {
4547 result = it->second;
4548 size_t l = result.length();
4549 if (!relPath.empty() && l>0 && result.at(0)=='.')
4550 { // relative path -> prepend relPath.
4551 result.prepend(relPath);
4552 l+=relPath.length();
4553 }
4554 if (l>0 && result.at(l-1)!='/') result+='/';
4555 }
4556 }
4557 else
4558 {
4559 result = relPath;
4560 }
4561 return result;
4562}
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
static StringMap tagDestinationMap
Definition doxygen.h:109
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:181

References DString::at(), DString::empty(), end(), DString::length(), DString::prepend(), DString::str(), and Doxygen::tagDestinationMap.

Referenced by HtmlHelp::addContentsItem(), convertMapFile(), createHtmlUrl(), generateJSLink(), FTVHelp::Private::generateLink(), replaceRef(), HtmlGenerator::startIndexItem(), LayoutNavEntry::url(), HtmlGenerator::writeInheritedSectionTitle(), writeJavasScriptSearchDataPage(), and writeMapArea().

◆ extractBeginRawStringDelimiter()

DString extractBeginRawStringDelimiter ( const char * rawStart)

Definition at line 5355 of file util.cpp.

5356{
5357 DString text=rawStart;
5358 size_t i = text.find('"');
5360 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
5361}
#define ASSERT(x)
Definition message.h:142

References ASSERT, DString::find(), DString::length(), DString::mid(), and DString::npos.

◆ extractClassNameFromType()

int extractClassNameFromType ( const DString & type,
int & pos,
DString & name,
DString & templSpec,
SrcLangExt lang )

Extracts a (sub-)string from type starting at pos that could form a class. The index of the match is returned and the found class name and a template argument list templSpec. If -1 is returned there are no more matches.

Definition at line 3381 of file util.cpp.

3382{
3383 AUTO_TRACE("type='{}' pos={} name='{}' lang={}",type,pos,name,lang);
3384 static const reg::Ex re_norm(R"(\a[\w:]*)");
3385 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
3386 const reg::Ex *re = &re_norm;
3387
3388 name.clear();
3389 templSpec.clear();
3390 if (type.empty())
3391 {
3392 AUTO_TRACE_EXIT("empty type");
3393 return -1;
3394 }
3395 size_t typeLen=type.length();
3396 if (typeLen>0)
3397 {
3398 if (lang == SrcLangExt::Fortran)
3399 {
3400 if (type[pos]==',')
3401 {
3402 AUTO_TRACE_EXIT("comma");
3403 return -1;
3404 }
3405 if (!type.lower().startsWith("type"))
3406 {
3407 re = &re_fortran;
3408 }
3409 }
3410 std::string s = type.str();
3411 reg::Iterator it(s,*re,static_cast<int>(pos));
3413
3414 if (it!=end)
3415 {
3416 const auto &match = *it;
3417 size_t i = match.position();
3418 size_t l = match.length();
3419 size_t ts = i+l;
3420 size_t te = ts;
3421 size_t tl = 0;
3422
3423 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') { ts++; tl++; } // skip any whitespace
3424 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
3425 {
3426 // locate end of template
3427 te=ts+1;
3428 int brCount=1;
3429 while (te<typeLen && brCount!=0)
3430 {
3431 if (type[static_cast<uint32_t>(te)]=='<')
3432 {
3433 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
3434 }
3435 if (type[static_cast<uint32_t>(te)]=='>')
3436 {
3437 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
3438 }
3439 te++;
3440 }
3441 }
3442 name = match.str();
3443 if (te>ts)
3444 {
3445 templSpec = DString(type).mid(ts,te-ts);
3446 tl+=te-ts;
3447 pos=static_cast<int>(i+l+tl);
3448 }
3449 else // no template part
3450 {
3451 pos=static_cast<int>(i+l);
3452 }
3453 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=true i=%d\n",
3454 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
3455 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
3456 return static_cast<int>(i);
3457 }
3458 }
3459 pos = static_cast<int>(typeLen);
3460 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=false\n",
3461 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
3462 AUTO_TRACE_EXIT("not found");
3463 return -1;
3464}
void clear()
Definition dstring.h:214
DString lower() const
Definition dstring.h:326
bool startsWith(const char *s) const
Definition dstring.h:600
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:239
#define AUTO_TRACE(...)
Definition docnode.cpp:53
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:55
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 AUTO_TRACE, AUTO_TRACE_EXIT, DString::clear(), DString::empty(), end(), DString::length(), DString::lower(), DString::mid(), DString::startsWith(), and DString::str().

Referenced by extractCanonicalType(), findUsedClassesForClass(), stripClassName(), and stripClassName().

◆ extractEndRawStringDelimiter()

DString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 5363 of file util.cpp.

5364{
5365 DString text=rawEnd;
5366 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
5367}

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

◆ extractNamespaceName()

void extractNamespaceName ( const DString & scopeName,
DString & className,
DString & namespaceName,
bool allowEmptyClass )

Input is a scopeName, output is the scopename split into a namespace part (as large as possible) and a classname part.

Definition at line 3027 of file util.cpp.

3030{
3031 DString clName=scopeName;
3032 NamespaceDef *nd = nullptr;
3033 size_t i=0;
3034 int p=0;
3035 if (!clName.empty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
3036 { // the whole name is a namespace (and not a class)
3037 namespaceName=nd->name();
3038 className.clear();
3039 goto done;
3040 }
3041 p=static_cast<int>(clName.length())-2;
3042 while (p>=0 && (i=clName.rfind("::",p))!=DString::npos)
3043 // see if the first part is a namespace (and not a class)
3044 {
3045 //printf("Trying %s\n",qPrint(clName.left(i)));
3046 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
3047 {
3048 //printf("found!\n");
3049 namespaceName=nd->name();
3050 className=clName.mid(i+2);
3051 goto done;
3052 }
3053 p=static_cast<int>(i)-2; // try a smaller piece of the scope
3054 }
3055 //printf("not found!\n");
3056
3057 // not found, so we just have to guess.
3058 className=scopeName;
3059 namespaceName.clear();
3060
3061done:
3062 if (className.empty() && !namespaceName.empty() && !allowEmptyClass)
3063 {
3064 // class and namespace with the same name, correct to return the class.
3065 className=namespaceName;
3066 namespaceName.clear();
3067 }
3068 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
3069 // qPrint(className),qPrint(namespaceName));
3070 if (className.endsWith("-p"))
3071 {
3072 className = className.left(className.length()-2);
3073 }
3074 return;
3075}
virtual const DString & name() const =0
An abstract interface of a namespace symbol.
ClassDef * getClass(const DString &n)
NamespaceDef * getResolvedNamespace(const DString &name)

References DString::clear(), DString::empty(), DString::endsWith(), getClass(), getResolvedNamespace(), DString::left(), DString::length(), DString::mid(), Definition::name(), DString::npos, and DString::rfind().

Referenced by addClassToContext(), addConceptToContext(), findMember(), and writeAlphabeticalClassList().

◆ fileToString()

DString fileToString ( const DString & name,
bool filter = false,
bool isSourceCode = false )

reads a file with name name and returns it as a string. If filter is true the file will be filtered by any user specified input filter. If name is "-" the string will be read from standard input.

Definition at line 1053 of file util.cpp.

1054{
1055 if (name.empty()) return DString();
1056 bool fileOpened=false;
1057 if (name[0]=='-' && name[1]==0) // read from stdin
1058 {
1059 std::string contents;
1060 std::string line;
1061 while (getline(std::cin,line))
1062 {
1063 contents+=line+'\n';
1064 }
1065 return contents;
1066 }
1067 else // read from file
1068 {
1069 FileInfo fi(name.str());
1070 if (!fi.exists() || !fi.isFile())
1071 {
1072 err("file '{}' not found\n",name);
1073 return "";
1074 }
1075 std::string buf;
1076 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1077 if (fileOpened)
1078 {
1079 addTerminalCharIfMissing(buf,'\n');
1080 return buf;
1081 }
1082 }
1083 if (!fileOpened)
1084 {
1085 err("cannot open file '{}' for reading\n",name);
1086 }
1087 return "";
1088}
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:87
bool readInputFile(const DString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:4375

References addTerminalCharIfMissing(), DString::empty(), err, FileInfo::exists(), FileInfo::isFile(), readInputFile(), and DString::str().

Referenced by createDVIFile(), extractBoundingBox(), getConvertLatexMacro(), HtmlGenerator::init(), LatexGenerator::init(), LayoutDocManager::parse(), parseInput(), FileDefImpl::parseSource(), parseTagFile(), DocParser::readTextFileByName(), readTextFileByName(), runMermaid(), runPlantumlContent(), FileDefImpl::writeSourceBody(), HtmlGenerator::writeStyleInfo(), and writeXMLCodeBlock().

◆ filterTitle()

DString filterTitle ( const DString & title)

Definition at line 4455 of file util.cpp.

4456{
4457 std::string tf;
4458 std::string t = title.str();
4459 static const reg::Ex re(R"(%[a-z_A-Z]+)");
4460 reg::Iterator it(t,re);
4462 size_t p = 0;
4463 for (; it!=end ; ++it)
4464 {
4465 const auto &match = *it;
4466 size_t i = match.position();
4467 size_t l = match.length();
4468 if (i>p) tf+=t.substr(p,i-p);
4469 tf+=match.str().substr(1); // skip %
4470 p=i+l;
4471 }
4472 tf+=t.substr(p);
4473 return tf;
4474}

References end(), and DString::str().

Referenced by addToIndices(), createJavaScriptSearchIndex(), PerlModGenerator::generatePerlModForPage(), generateSqlite3ForPage(), generateXMLForPage(), generateXMLForRequirement(), generateXMLForRequirements(), parseCommentAsHtml(), SearchIndexExternal::setCurrentDoc(), HtmlGenerator::startFile(), and writeJavasScriptSearchDataPage().

◆ findExampleFilePath()

DString findExampleFilePath ( const DString & file,
bool & ambig )

Definition at line 2452 of file util.cpp.

2453{
2454 ambig=false;
2455 DString result;
2456 bool found=false;
2457 if (!found)
2458 {
2459 FileInfo fi(file.str());
2460 if (fi.exists())
2461 {
2462 result=fi.absFilePath();
2463 found=true;
2464 }
2465 }
2466 if (!found)
2467 {
2468 StringVector examplePathList = Config_getList(EXAMPLE_PATH);
2469 for (const auto &s : examplePathList)
2470 {
2471 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2472 FileInfo fi(absFileName);
2473 if (fi.exists())
2474 {
2475 result=fi.absFilePath();
2476 found=true;
2477 }
2478 }
2479 }
2480
2481 if (!found)
2482 {
2483 // as a fallback we also look in the exampleNameDict
2485 if (fd && !ambig)
2486 {
2487 result=fd->absFilePath();
2488 }
2489 }
2490 return result;
2491}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:95
A model of a file symbol.
Definition filedef.h:97
virtual DString absFilePath() const =0
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:38
DString pathSeparator()
Definition portable.cpp:390

References FileDef::absFilePath(), FileInfo::absFilePath(), Config_getList, Doxygen::exampleNameLinkedMap, FileInfo::exists(), FileNameLinkedMap::findFileDef(), Portable::pathSeparator(), and DString::str().

Referenced by readIncludeFile(), and DocParser::readTextFileByName().

◆ getDefs()

GetDefResult getDefs ( const GetDefInput & input)

Definition at line 1866 of file util.cpp.

1867{
1868 GetDefResult result;
1869 if (input.memberName.empty()) return result;
1870 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
1871 input.scopeName,input.memberName,input.forceEmptyScope);
1872
1873 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
1874 const Definition *scope = Doxygen::globalScope;
1875 SymbolResolver resolver;
1876 if (input.currentFile) resolver.setFileScope(input.currentFile);
1877 if (!input.scopeName.empty() && !input.forceEmptyScope)
1878 {
1879 scope = resolver.resolveSymbol(scope,input.scopeName);
1880 }
1881 if (scope==Doxygen::globalScope)
1882 {
1883 scope = input.currentFile;
1884 }
1885 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
1886 //
1887 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
1888 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():DString()));
1889 if (symbol && symbol->definitionType()==Definition::TypeMember)
1890 {
1891 result.md = toMemberDef(symbol);
1892 result.cd = result.md->getClassDef();
1893 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
1894 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
1895 result.gd = result.md->getGroupDef();
1896 result.found = true;
1897 }
1898 else if (symbol && symbol->definitionType()==Definition::TypeClass)
1899 {
1900 result.cd = toClassDef(symbol);
1901 result.found = true;
1902 }
1903 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
1904 {
1905 result.nd = toNamespaceDef(symbol);
1906 result.found = true;
1907 }
1908 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
1909 {
1910 result.cnd = toConceptDef(symbol);
1911 result.found = true;
1912 }
1913 else if (symbol && symbol->definitionType()==Definition::TypeModule)
1914 {
1915 result.modd = toModuleDef(symbol);
1916 result.found = true;
1917 }
1918 return result;
1919}
The common base class of all entity definitions found in the sources.
Definition definition.h:77
virtual DefType definitionType() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:114
virtual const ClassDef * getClassDef() const =0
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
const Definition * resolveSymbol(const Definition *scope, const DString &name, const DString &args=DString(), bool checkCV=false, bool insideCode=false, bool onlyLinkable=false)
Find the symbool definition matching name within the scope set.
void setFileScope(const FileDef *fd)
Sets or updates the file scope using when resolving symbols.
ClassDef * toClassDef(Definition *d)
ConceptDef * toConceptDef(Definition *d)
MemberDef * toMemberDef(Definition *d)
ModuleDef * toModuleDef(Definition *d)
NamespaceDef * toNamespaceDef(Definition *d)
bool forceEmptyScope
Definition util.h:85
const FileDef * currentFile
Definition util.h:86
bool insideCode
Definition util.h:88
DString args
Definition util.h:84
DString memberName
Definition util.h:83
bool checkCV
Definition util.h:87
DString scopeName
Definition util.h:82
const MemberDef * md
Definition util.h:95
const ConceptDef * cnd
Definition util.h:100
const FileDef * fd
Definition util.h:97
const ModuleDef * modd
Definition util.h:101
const GroupDef * gd
Definition util.h:99
bool found
Definition util.h:94
const ClassDef * cd
Definition util.h:96
const NamespaceDef * nd
Definition util.h:98

References GetDefInput::args, AUTO_TRACE, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, GetDefInput::currentFile, Definition::definitionType(), DString::empty(), GetDefResult::fd, GetDefInput::forceEmptyScope, GetDefResult::found, GetDefResult::gd, MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getNamespaceDef(), Doxygen::globalScope, GetDefInput::insideCode, GetDefResult::md, GetDefInput::memberName, GetDefResult::modd, GetDefResult::nd, SymbolResolver::resolveSymbol(), GetDefInput::scopeName, SymbolResolver::setFileScope(), toClassDef(), toConceptDef(), toMemberDef(), toModuleDef(), toNamespaceDef(), Definition::TypeClass, Definition::TypeConcept, Definition::TypeMember, Definition::TypeModule, and Definition::TypeNamespace.

Referenced by DocParser::findDocsForMemberOrCompound(), getLinkInScope(), getLinkInScope(), linkifyText(), and resolveRef().

◆ getDotImageExtension() [1/2]

DString getDotImageExtension ( )

Returns the file extension to use for dot files as specified via the DOT_IMAGE_FORMAT configuration option.

Definition at line 4965 of file util.cpp.

4966{
4967 return getDotImageExtension(Config_getEnumAsString(DOT_IMAGE_FORMAT));
4968}
#define Config_getEnumAsString(name)
Definition config.h:36
DString getDotImageExtension()
Definition util.cpp:4965

References Config_getEnumAsString, and getDotImageExtension().

Referenced by MermaidManager::convertToImageFormat(), RTFGenerator::endCallGraph(), RTFGenerator::endDirDepGraph(), RTFGenerator::endDotGraph(), RTFGenerator::endInclDepGraph(), DotGraph::generateCode(), getDotImageExtension(), DotGraph::imgName(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), DotRunner::run(), DocbookDocVisitor::startDotFile(), TranslatorAfrikaans::trLegendDocs(), TranslatorArabic::trLegendDocs(), TranslatorArmenian::trLegendDocs(), TranslatorBrazilian::trLegendDocs(), TranslatorBulgarian::trLegendDocs(), TranslatorCatalan::trLegendDocs(), TranslatorChinese::trLegendDocs(), TranslatorChinesetraditional::trLegendDocs(), TranslatorCroatian::trLegendDocs(), TranslatorCzech::trLegendDocs(), TranslatorDanish::trLegendDocs(), TranslatorDutch::trLegendDocs(), TranslatorEnglish::trLegendDocs(), TranslatorEsperanto::trLegendDocs(), TranslatorFinnish::trLegendDocs(), TranslatorFrench::trLegendDocs(), TranslatorGerman::trLegendDocs(), TranslatorGreek::trLegendDocs(), TranslatorHindi::trLegendDocs(), TranslatorHungarian::trLegendDocs(), TranslatorIndonesian::trLegendDocs(), TranslatorItalian::trLegendDocs(), TranslatorJapanese::trLegendDocs(), TranslatorKorean::trLegendDocs(), TranslatorLatvian::trLegendDocs(), TranslatorLithuanian::trLegendDocs(), TranslatorMacedonian::trLegendDocs(), TranslatorNorwegian::trLegendDocs(), TranslatorPersian::trLegendDocs(), TranslatorPolish::trLegendDocs(), TranslatorPortuguese::trLegendDocs(), TranslatorRomanian::trLegendDocs(), TranslatorRussian::trLegendDocs(), TranslatorSerbian::trLegendDocs(), TranslatorSerbianCyrillic::trLegendDocs(), TranslatorSlovak::trLegendDocs(), TranslatorSlovene::trLegendDocs(), TranslatorSpanish::trLegendDocs(), TranslatorSwedish::trLegendDocs(), TranslatorTurkish::trLegendDocs(), TranslatorUkrainian::trLegendDocs(), TranslatorVietnamese::trLegendDocs(), DocbookDocVisitor::writeDotFile(), RTFDocVisitor::writeDotFile(), writeDotGraphFromFile(), writeDotImageMapFromFile(), DotLegendGraph::writeGraph(), HtmlDocVisitor::writeMscFile(), and HtmlDocVisitor::writePlantUMLFile().

◆ getDotImageExtension() [2/2]

DString getDotImageExtension ( const DString & format)

Returns the file extension to use for dot files as specified via the argument format.

Definition at line 4969 of file util.cpp.

4970{
4971 size_t i= format.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
4972 return i==DString::npos ? format : format.left(i);
4973}

References DString::find(), DString::left(), and DString::npos.

◆ getDotImageExtensionGenerated()

DString getDotImageExtensionGenerated ( const DString & format)

Definition at line 4975 of file util.cpp.

4976{
4977 StringVector splitExt = split(format.str(),":");
4978 DString extGen;
4979 for (size_t i = splitExt.size(); i > 0; )
4980 {
4981 --i;
4982 extGen += splitExt[i] + (i!=0 ? "." : "");
4983 }
4984 return extGen;
4985}
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition stringutil.h:117

References split(), and DString::str().

Referenced by DotRunner::run().

◆ getEncoding()

DString getEncoding ( const FileInfo & fi)

Definition at line 4478 of file util.cpp.

4479{
4480 InputFileEncoding elem;
4481 auto getter = [](const InputFileEncoding &e) { return e.pattern.str(); };
4482 if (fi.match(Doxygen::inputFileEncodingList,useCaseSenseNames(),&elem,getter)) // check for file specific encoding
4483 {
4484 return elem.encoding;
4485 }
4486 else // fall back to default encoding
4487 {
4488 return Config_getString(INPUT_ENCODING);
4489 }
4490}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:131
bool match(const PatternList &patList, bool caseSenseNames, PatternElem *elem=nullptr, PatternGet getter=[](const std::string &s){ return s;}) const
Match the file name against a list of patterns.
Definition fileinfo.h:60
#define Config_getString(name)
Definition config.h:32
DString encoding
Definition doxygen.h:63

References Config_getString, InputFileEncoding::encoding, Doxygen::inputFileEncodingList, FileInfo::match(), and useCaseSenseNames().

Referenced by readCodeFragment(), and readInputFile().

◆ getFileFilter()

DString getFileFilter ( const DString & name,
bool isSourceCode )

looks for a filter for the file name. Returns the name of the filter if there is a match for the file name, otherwise an empty string. In case inSourceCode is true then first the source filter list is considered.

Definition at line 1020 of file util.cpp.

1021{
1022 // sanity check
1023 if (name.empty()) return "";
1024
1025 StringVector filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1026 StringVector filterList = Config_getList(FILTER_PATTERNS);
1027
1028 DString filterName;
1029 bool found=false;
1030 if (isSourceCode && !filterSrcList.empty())
1031 { // first look for source filter pattern list
1032 filterName = getFilterFromList(name,filterSrcList,found);
1033 }
1034 if (!found && filterName.empty())
1035 { // then look for filter pattern list
1036 filterName = getFilterFromList(name,filterList,found);
1037 }
1038 if (!found)
1039 { // then use the generic input filter
1040 return Config_getString(INPUT_FILTER);
1041 }
1042 else
1043 {
1044 /* remove surrounding double quotes */
1045 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1046 {
1047 filterName = filterName.mid(1,filterName.length()-2);
1048 }
1049 return filterName;
1050 }
1051}
static DString getFilterFromList(const DString &name, const StringVector &filterList, bool &found)
Definition util.cpp:985

References Config_getList, Config_getString, DString::empty(), getFilterFromList(), DString::length(), and DString::mid().

Referenced by FilterCache::getFileContents(), CodeFragmentManager::parseCodeFragment(), readCodeFragment(), readInputFile(), and FileDefImpl::writeSourceBody().

◆ getFileNameExtension()

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( DString & fileName)

Routine to handle the language attribute of the \code command.

Definition at line 4187 of file util.cpp.

4188{
4189 // try the extension
4190 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
4191 if (lang == SrcLangExt::Unknown)
4192 {
4193 // try the language names
4194 DString langName = fileName.lower();
4195 if (langName.at(0)=='.') langName = langName.mid(1);
4196 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
4197 [&langName](const auto &info) { return info.langName==langName; });
4198 if (it != g_lang2extMap.end())
4199 {
4200 lang = it->parserId;
4201 fileName = it->defExt;
4202 }
4203 else // default to C++
4204 {
4205 return SrcLangExt::Cpp;
4206 }
4207 }
4208 return lang;
4209}
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
Definition util.cpp:4169
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:4040

References DString::at(), g_lang2extMap, getLanguageFromFileName(), DString::lower(), and DString::mid().

Referenced by DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), ManDocVisitor::operator()(), RTFDocVisitor::operator()(), and XmlDocVisitor::operator()().

◆ getLanguageFromFileName()

SrcLangExt getLanguageFromFileName ( const DString & fileName,
SrcLangExt defLang = SrcLangExt::Cpp )

Definition at line 4169 of file util.cpp.

4170{
4171 FileInfo fi(fileName.str());
4172 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
4173 DString extName = DString(fi.extension(false)).lower();
4174 if (extName.empty()) extName=".no_extension";
4175 if (extName.at(0)!='.') extName.prepend(".");
4176 auto it = g_extLookup.find(extName.str());
4177 if (it!=g_extLookup.end()) // listed extension
4178 {
4179 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
4180 return it->second;
4181 }
4182 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
4183 return defLang; // not listed => assume C-ish language.
4184}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:4030

References DString::at(), DString::empty(), FileInfo::extension(), g_extLookup, DString::lower(), DString::prepend(), and DString::str().

Referenced by MemberDefImpl::_writeMultiLineInitializer(), ClassDefImpl::ClassDefImpl(), convertCppComments(), DocRef::DocRef(), FileDefImpl::FileDefImpl(), generateExampleDocs(), getLanguageFromCodeLang(), EntryType::guessSection(), FileDefImpl::isDocumentationFile(), COutlineParser::needsPreprocessing(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), ManDocVisitor::operator()(), ManDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), CodeFragmentManager::parseCodeFragment(), parseFilesMultiThreading(), parseFilesSingleThreading(), parseMain(), Markdown::Private::processLink(), readCodeFragment(), setContext(), setFileName(), validatingParseDoc(), and writeXMLCodeBlock().

◆ getLanguageSpecificSeparator()

DString getLanguageSpecificSeparator ( SrcLangExt lang,
bool classScope = false )

Returns the scope separator to use given the programming language lang

Definition at line 4630 of file util.cpp.

4631{
4632 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
4633 {
4634 return ".";
4635 }
4636 else if (lang==SrcLangExt::PHP && !classScope)
4637 {
4638 return "\\";
4639 }
4640 else
4641 {
4642 return "::";
4643 }
4644}

Referenced by DefinitionImpl::_writeSourceRefList(), addGlobalFunction(), MemberDefImpl::addListReference(), addMethodToClass(), addVariableToFile(), MemberDefImpl::displayDefinition(), DefinitionAliasImpl::init(), linkToText(), makeDisplayName(), makeDisplayName(), makeQualifiedNameWithTemplateParameters(), ClassDefImpl::mergeMembersFromBaseClasses(), MemberDefImpl::qualifiedName(), SearchIndex::setCurrentDoc(), validatingParseDoc(), MemberDefImpl::warnIfUndocumented(), writeAlphabeticalClassList(), MemberDefImpl::writeDeclaration(), writeDefArgumentList(), MemberDefImpl::writeDocumentation(), writeJavasScriptSearchDataPage(), MemberDefImpl::writeLink(), and writeMemberReference().

◆ getPrefixIndex()

int getPrefixIndex ( const DString & name)

Returns the character index within name of the first prefix in Config_getList(IGNORE_PREFIX) that matches name at the left hand side, or zero if no match was found

Definition at line 2652 of file util.cpp.

2653{
2654 if (name.empty()) return 0;
2655 int result=0;
2656 StringVector sl = Config_getList(IGNORE_PREFIX);
2657 for (const auto &s : sl)
2658 {
2659 const char *ps=s.c_str();
2660 const char *pd=name.data();
2661 int i=0;
2662 while (*ps!=0 && *pd!=0 && *ps==*pd)
2663 {
2664 ps++;
2665 pd++;
2666 i++;
2667 }
2668 if (*ps==0 && *pd!=0)
2669 {
2670 result=i;
2671 break;
2672 }
2673 }
2674 if (result<static_cast<int>(name.length())-1 && name.at(result)=='[') result++; // for e.g. [union] return u
2675 return result;
2676}

References DString::at(), Config_getList, DString::data(), DString::empty(), and DString::length().

Referenced by Index::addClassMemberNameToIndex(), Index::addFileMemberNameToIndex(), Index::addModuleMemberNameToIndex(), Index::addNamespaceMemberNameToIndex(), SearchIndex::addWordRec(), parseInput(), writeAlphabeticalClassList(), and writeMemberList().

◆ getProjectId()

DString getProjectId ( )

Definition at line 5286 of file util.cpp.

5287{
5288 DString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
5289 if (projectCookie.empty()) return DString();
5290 return md5str(projectCookie.view())+"_";
5291}

References Config_getString, DString::empty(), md5str(), and DString::view().

Referenced by generateJSNavTree(), HtmlGenerator::init(), and writeJavaScriptSearchIndex().

◆ getScopeFragment()

int getScopeFragment ( const DString & s,
int p,
int * l )

Returns a fragment from scope s, starting at position p.

Parameters
sthe scope name as a string.
pthe start position (0 is the first).
lthe resulting length of the fragment.
Returns
the location of the fragment, or -1 if non is found.

Definition at line 3799 of file util.cpp.

3800{
3801 int sl=static_cast<int>(s.length());
3802 int sp=p;
3803 int count=0;
3804 bool done=false;
3805 if (sp>=sl) return -1;
3806 while (sp<sl)
3807 {
3808 char c=s.at(sp);
3809 if (c==':')
3810 {
3811 sp++;
3812 p++;
3813 }
3814 else
3815 {
3816 break;
3817 }
3818 }
3819 while (sp<sl)
3820 {
3821 char c=s.at(sp);
3822 switch (c)
3823 {
3824 case ':': // found next part
3825 goto found;
3826 case '<': // skip template specifier
3827 count=1;sp++;
3828 done=false;
3829 while (sp<sl && !done)
3830 {
3831 // TODO: deal with << and >> operators!
3832 c=s.at(sp++);
3833 switch(c)
3834 {
3835 case '<': count++; break;
3836 case '>': count--; if (count==0) done=true; break;
3837 default: break;
3838 }
3839 }
3840 break;
3841 default:
3842 sp++;
3843 break;
3844 }
3845 }
3846found:
3847 *l=sp-p;
3848 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
3849 return p;
3850}

References DString::at(), and DString::length().

Referenced by buildScopeFromQualifiedName(), findScopeFromQualifiedName(), SymbolResolver::Private::followPath(), resolveTypeDef(), and stripAnonymousNamespaceScope().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 4096 of file util.cpp.

4097{
4098 // NOTE: when adding an extension, also add the extension in config.xml
4099 // extension parser id
4100 updateLanguageMapping(".dox", "c");
4101 updateLanguageMapping(".txt", "c"); // see bug 760836
4102 updateLanguageMapping(".doc", "c");
4103 updateLanguageMapping(".c", "c");
4104 updateLanguageMapping(".C", "c");
4105 updateLanguageMapping(".cc", "c");
4106 updateLanguageMapping(".CC", "c");
4107 updateLanguageMapping(".cxx", "c");
4108 updateLanguageMapping(".cpp", "c");
4109 updateLanguageMapping(".c++", "c");
4110 updateLanguageMapping(".cxxm", "c"); // C++20 modules
4111 updateLanguageMapping(".cppm", "c"); // C++20 modules
4112 updateLanguageMapping(".ccm", "c"); // C++20 modules
4113 updateLanguageMapping(".c++m", "c"); // C++20 modules
4114 updateLanguageMapping(".ii", "c");
4115 updateLanguageMapping(".ixx", "c");
4116 updateLanguageMapping(".ipp", "c");
4117 updateLanguageMapping(".i++", "c");
4118 updateLanguageMapping(".inl", "c");
4119 updateLanguageMapping(".h", "c");
4120 updateLanguageMapping(".H", "c");
4121 updateLanguageMapping(".hh", "c");
4122 updateLanguageMapping(".HH", "c");
4123 updateLanguageMapping(".hxx", "c");
4124 updateLanguageMapping(".hpp", "c");
4125 updateLanguageMapping(".h++", "c");
4126 updateLanguageMapping(".idl", "idl");
4127 updateLanguageMapping(".ddl", "idl");
4128 updateLanguageMapping(".odl", "idl");
4129 updateLanguageMapping(".java", "java");
4130 //updateLanguageMapping(".as", "javascript"); // not officially supported
4131 //updateLanguageMapping(".js", "javascript"); // not officially supported
4132 updateLanguageMapping(".cs", "csharp");
4133 updateLanguageMapping(".d", "d");
4134 updateLanguageMapping(".php", "php");
4135 updateLanguageMapping(".php4", "php");
4136 updateLanguageMapping(".php5", "php");
4137 updateLanguageMapping(".inc", "php");
4138 updateLanguageMapping(".phtml", "php");
4139 updateLanguageMapping(".m", "objective-c");
4140 updateLanguageMapping(".M", "objective-c");
4141 updateLanguageMapping(".mm", "c"); // see bug746361
4142 updateLanguageMapping(".py", "python");
4143 updateLanguageMapping(".pyw", "python");
4144 updateLanguageMapping(".f", "fortran");
4145 updateLanguageMapping(".for", "fortran");
4146 updateLanguageMapping(".f90", "fortran");
4147 updateLanguageMapping(".f95", "fortran");
4148 updateLanguageMapping(".f03", "fortran");
4149 updateLanguageMapping(".f08", "fortran");
4150 updateLanguageMapping(".f18", "fortran");
4151 updateLanguageMapping(".vhd", "vhdl");
4152 updateLanguageMapping(".vhdl", "vhdl");
4153 updateLanguageMapping(".ucf", "vhdl");
4154 updateLanguageMapping(".qsf", "vhdl");
4155 updateLanguageMapping(".md", "md");
4156 updateLanguageMapping(".markdown", "md");
4157 updateLanguageMapping(".ice", "slice");
4158 updateLanguageMapping(".l", "lex");
4159 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
4160 // in the lex scanning to cpp
4161}

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

DString inlineArgListToDoc ( const ArgumentList & al)

Returns a documentation string combining the inline documentation for each parameter in the list al.

Definition at line 4866 of file util.cpp.

4867{
4868 DString paramDocs;
4869 if (al.hasDocumentation(true))
4870 {
4871 for (const Argument &a : al)
4872 {
4873 if (a.hasDocumentation(true))
4874 {
4875 DString docsWithoutDir = a.docs;
4876 DString direction = extractDirection(docsWithoutDir);
4877 DString name = a.name;
4878 if (name.empty())
4879 {
4880 name = "-";
4881 }
4882 paramDocs+=" \\ilinebr @param"+direction+" "+name+" "+docsWithoutDir;
4883 }
4884 }
4885 }
4886 return paramDocs;
4887}
bool hasDocumentation(bool allowEmptyNames=false) const
Definition arguments.cpp:26
static DString extractDirection(DString &docs)
Strip the direction part from docs and return it as a string in canonical form.
Definition util.cpp:4830

References DString::empty(), extractDirection(), and ArgumentList::hasDocumentation().

Referenced by DocParser::processCopyDoc(), and MemberDefImpl::writeDocumentation().

◆ inlineTemplateArgListToDoc()

DString inlineTemplateArgListToDoc ( const ArgumentList & al)

Returns a documentation string combining the inline documentation for each template parameter in the list al.

Definition at line 832 of file util.cpp.

833{
834 DString paramDocs;
836 {
837 for (const Argument &a : al)
838 {
839 if (!a.docs.empty())
840 {
841 if (!a.name.empty())
842 {
843 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
844 }
845 else if (!a.type.empty())
846 {
847 DString type = a.type;
848 type.stripPrefix("class ");
849 type.stripPrefix("typename ");
850 type = type.stripWhiteSpace();
851 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
852 }
853 }
854 }
855 }
856 return paramDocs;
857}
bool hasTemplateDocumentation() const
Definition arguments.cpp:34
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
bool stripPrefix(const DString &prefix)
Definition dstring.h:290

References ArgumentList::hasTemplateDocumentation(), DString::stripPrefix(), and DString::stripWhiteSpace().

Referenced by ClassDefImpl::writeDetailedDocumentationBody(), and MemberDefImpl::writeDocumentation().

◆ insertTemplateSpecifierInScope()

DString insertTemplateSpecifierInScope ( const DString & scope,
const DString & templ )

Definition at line 3077 of file util.cpp.

3078{
3079 DString result=scope;
3080 if (!templ.empty() && scope.find('<')==DString::npos)
3081 {
3082 size_t si=0, pi=0;
3083 ClassDef *cd=nullptr;
3084 while (
3085 (si=scope.find("::",pi))!=DString::npos && !getClass(scope.left(si)+templ) &&
3086 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3087 )
3088 {
3089 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3090 pi=si+2;
3091 }
3092 if (si==DString::npos) // not nested => append template specifier
3093 {
3094 result+=templ;
3095 }
3096 else // nested => insert template specifier before after first class name
3097 {
3098 result=scope.left(si) + templ + scope.mid(si);
3099 }
3100 }
3101 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3102 // qPrint(scope),qPrint(templ),qPrint(result));
3103 return result;
3104}
bool empty() const
Definition arguments.h:100
A abstract class representing of a compound symbol.
Definition classdef.h:100
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.

References ArgumentList::empty(), DString::empty(), DString::find(), getClass(), DString::left(), DString::mid(), DString::npos, and ClassDef::templateArguments().

Referenced by DotClassGraph::addClass(), generateXMLForClass(), DiagramItem::label(), ClassDefImpl::writeInheritanceGraph(), and ClassDefImpl::writeTagFile().

◆ isURL()

bool isURL ( const DString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 4647 of file util.cpp.

4648{
4649 static const std::unordered_set<std::string> schemes = {
4650 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
4651 };
4652 DString loc_url = url.stripWhiteSpace();
4653 size_t colonPos = loc_url.find(':');
4654 return colonPos!=DString::npos && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
4655}

References DString::find(), DString::left(), DString::npos, DString::str(), and DString::stripWhiteSpace().

Referenced by correctURL(), and Markdown::Private::processLink().

◆ leftScopeMatch()

bool leftScopeMatch ( const DString & scope,
const DString & name )

Definition at line 740 of file util.cpp.

741{
742 size_t sl=scope.length();
743 size_t nl=name.length();
744 return (name==scope || // equal
745 (name.left(sl)==scope && // substring
746 nl>sl+1 && name.at(sl)==':' && name.at(sl+1)==':' // scope
747 )
748 );
749}

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

Referenced by addClassToContext(), addConceptToContext(), buildFunctionList(), mergeScopes(), pushScope(), and resolveRef().

◆ linkToText()

DString linkToText ( SrcLangExt lang,
const DString & link,
bool ignoreDots )

Definition at line 2265 of file util.cpp.

2266{
2267 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2268 DString result=link;
2269 if (!result.empty())
2270 {
2271 // replace # by ::
2272 result=substitute(result,"#","::");
2273 // replace . by ::
2274 if (!ignoreDots && result.find('<')==DString::npos) result=substitute(result,".","::",3);
2275 // strip leading :: prefix if present
2276 if (result.at(0)==':' && result.at(1)==':')
2277 {
2278 result=result.mid(2);
2279 }
2281 if (sep!="::")
2282 {
2283 result=substitute(result,"::",sep);
2284 }
2285 }
2286 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2287 return result;
2288}
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485
DString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Definition util.cpp:4630

References DString::at(), DString::empty(), DString::find(), getLanguageSpecificSeparator(), DString::mid(), DString::npos, and substitute().

Referenced by DotCallGraph::buildGraph(), DocRef::DocRef(), DotCallGraph::DotCallGraph(), and DocParser::handleLinkedWord().

◆ mainPageHasTitle()

bool mainPageHasTitle ( )

Definition at line 4960 of file util.cpp.

4961{
4962 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
4963}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:93

References Doxygen::mainPage.

Referenced by generateJSNavTree(), generateSqlite3ForPage(), and generateXMLForPage().

◆ makeBaseName()

◆ mangleCSharpGenericName()

DString mangleCSharpGenericName ( const DString & name)

Definition at line 5335 of file util.cpp.

5336{
5337 if (size_t idx = name.find('<'); idx!=DString::npos)
5338 {
5339 return name.left(idx)+"-"+DString().setNum(name.contains(",")+1)+"-g";
5340 }
5341 return name;
5342}
DString & setNum(short n)
Definition dstring.h:552
int contains(char c, bool cs=true) const
Definition dstring.cpp:85

References DString::contains(), DString::find(), DString::left(), DString::npos, and DString::setNum().

Referenced by addClassToContext(), addEnumValuesToEnums(), addVariable(), buildFunctionList(), extractClassName(), findClassRelation(), findEnums(), SymbolResolver::resolveClass(), resolveLink(), and resolveRef().

◆ matchArguments2()

bool matchArguments2 ( const Definition * srcScope,
const FileDef * srcFileScope,
const DString & srcReturnType,
const ArgumentList * srcAl,
const Definition * dstScope,
const FileDef * dstFileScope,
const DString & dstReturnType,
const ArgumentList * dstAl,
bool checkCV,
SrcLangExt lang )

Compares two parameter lists srcAl and dstAl and returns true if they match.

Definition at line 1589 of file util.cpp.

1592{
1593 ASSERT(srcScope!=nullptr && dstScope!=nullptr);
1594
1595 AUTO_TRACE("srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
1596 srcScope->name(),dstScope->name(),srcAl?argListToString(*srcAl):"",dstAl?argListToString(*dstAl):"",checkCV,lang);
1597
1598 if (srcAl==nullptr || dstAl==nullptr)
1599 {
1600 bool match = srcAl==dstAl;
1601 if (match)
1602 {
1603 MATCH
1604 return true;
1605 }
1606 else
1607 {
1608 NOMATCH
1609 return false;
1610 }
1611 }
1612
1613 // handle special case with void argument
1614 if ( srcAl->empty() && dstAl->size()==1 && dstAl->front().type=="void" )
1615 { // special case for finding match between func() and func(void)
1616 Argument a;
1617 a.type = "void";
1618 const_cast<ArgumentList*>(srcAl)->push_back(a);
1619 MATCH
1620 return true;
1621 }
1622 if ( dstAl->empty() && srcAl->size()==1 && srcAl->front().type=="void" )
1623 { // special case for finding match between func(void) and func()
1624 Argument a;
1625 a.type = "void";
1626 const_cast<ArgumentList*>(dstAl)->push_back(a);
1627 MATCH
1628 return true;
1629 }
1630
1631 if (srcAl->size() != dstAl->size())
1632 {
1633 NOMATCH
1634 return false; // different number of arguments -> no match
1635 }
1636
1637 if (checkCV)
1638 {
1639 if (srcAl->constSpecifier() != dstAl->constSpecifier())
1640 {
1641 NOMATCH
1642 return false; // one member is const, the other not -> no match
1643 }
1644 if (srcAl->volatileSpecifier() != dstAl->volatileSpecifier())
1645 {
1646 NOMATCH
1647 return false; // one member is volatile, the other not -> no match
1648 }
1649 }
1650
1651 if (srcAl->refQualifier() != dstAl->refQualifier())
1652 {
1653 NOMATCH
1654 return false; // one member is has a different ref-qualifier than the other
1655 }
1656
1657 if (srcReturnType=="auto" && dstReturnType=="auto" && srcAl->trailingReturnType()!=dstAl->trailingReturnType())
1658 {
1659 NOMATCH
1660 return false; // one member is has a different return type than the other
1661 }
1662
1663 // so far the argument list could match, so we need to compare the types of
1664 // all arguments.
1665 auto srcIt = srcAl->begin();
1666 auto dstIt = dstAl->begin();
1667 for (;srcIt!=srcAl->end() && dstIt!=dstAl->end();++srcIt,++dstIt)
1668 {
1669 Argument &srcA = const_cast<Argument&>(*srcIt);
1670 Argument &dstA = const_cast<Argument&>(*dstIt);
1671 if (!matchArgument2(srcScope,srcFileScope,srcA,
1672 dstScope,dstFileScope,dstA,
1673 lang)
1674 )
1675 {
1676 NOMATCH
1677 return false;
1678 }
1679 }
1680 MATCH
1681 return true; // all arguments match
1682}
This class represents an function or template argument list.
Definition arguments.h:66
Argument & front()
Definition arguments.h:106
size_t size() const
Definition arguments.h:101
#define MATCH
Definition util.cpp:1488
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:859
#define NOMATCH
Definition util.cpp:1489
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
Definition util.cpp:1523

References argListToString(), ASSERT, AUTO_TRACE, ArgumentList::begin(), ArgumentList::constSpecifier(), ArgumentList::empty(), ArgumentList::end(), ArgumentList::front(), MATCH, matchArgument2(), Definition::name(), NOMATCH, ArgumentList::refQualifier(), ArgumentList::size(), ArgumentList::trailingReturnType(), Argument::type, and ArgumentList::volatileSpecifier().

Referenced by addMemberDocs(), addMemberFunction(), buildFunctionList(), combineDeclarationAndDefinition(), computeMemberRelationsForBaseClass(), ClassDefImpl::containsOverload(), findFriends(), findGlobalMember(), findMember(), SymbolResolver::Private::getResolvedSymbol(), GroupDefImpl::insertMember(), matchCanonicalTypes(), ClassDefImpl::mergeMembersFromBaseClasses(), transferFunctionReferences(), and transferRelatedFunctionDocumentation().

◆ matchTemplateArguments()

bool matchTemplateArguments ( const ArgumentList & srcAl,
const ArgumentList & dstAl )

Returns true if the template parameter lists srcAl and dstAl match. The lists are considered to match if they have the same number of parameters and each matching parameter in srcAl and dstAl has the same constraints (or at least one parameter has no constraints).

Definition at line 1833 of file util.cpp.

1834{
1835 AUTO_TRACE("srcAl={} dstAl={}",argListToString(srcAl),argListToString(dstAl));
1836 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
1837 {
1838 AUTO_TRACE_EXIT("different number of parameters");
1839 return false;
1840 }
1841 auto isUnconstraintTemplate = [](const DString &type)
1842 {
1843 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
1844 };
1845 auto srcIt = srcAl.begin();
1846 auto dstIt = dstAl.begin();
1847 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
1848 {
1849 const Argument &srcA = *srcIt;
1850 const Argument &dstA = *dstIt;
1851 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
1852 {
1853 AUTO_TRACE_EXIT("different constraints");
1854 return false;
1855 }
1856 ++srcIt;
1857 ++dstIt;
1858 }
1859 AUTO_TRACE_EXIT("same");
1860 // no overload with respect to the template parameters
1861 return true;
1862}

References argListToString(), AUTO_TRACE, AUTO_TRACE_EXIT, ArgumentList::begin(), ArgumentList::end(), ArgumentList::size(), and Argument::type.

Referenced by buildFunctionList().

◆ mergeArguments()

void mergeArguments ( ArgumentList & srcAl,
ArgumentList & dstAl,
bool forceNameOverwrite = false )

Merges the information of two parameter lists (typically a declaration and a definition). Missing information is added to either list. The name of parameter of srcAl is only overwritten if forceNameOverwrite is true.

Definition at line 1689 of file util.cpp.

1690{
1691 AUTO_TRACE("srcAl='{}',dstAl='{}',forceNameOverwrite={}",
1692 qPrint(argListToString(srcAl)),qPrint(argListToString(dstAl)),forceNameOverwrite);
1693
1694 if (srcAl.size()!=dstAl.size())
1695 {
1696 return; // invalid argument lists -> do not merge
1697 }
1698
1699 auto srcIt=srcAl.begin();
1700 auto dstIt=dstAl.begin();
1701 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
1702 {
1703 Argument &srcA = *srcIt;
1704 Argument &dstA = *dstIt;
1705
1706 AUTO_TRACE_ADD("before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1707 srcA.type,srcA.name,srcA.defval,
1708 dstA.type,dstA.name,dstA.defval);
1709 if (srcA.defval.empty() && !dstA.defval.empty())
1710 {
1711 //printf("Defval changing '%s'->'%s'\n",qPrint(srcA.defval),qPrint(dstA.defval));
1712 srcA.defval=dstA.defval;
1713 }
1714 else if (!srcA.defval.empty() && dstA.defval.empty())
1715 {
1716 //printf("Defval changing '%s'->'%s'\n",qPrint(dstA.defval),qPrint(srcA.defval));
1717 dstA.defval=srcA.defval;
1718 }
1719
1720 // fix wrongly detected const or volatile specifiers before merging.
1721 // example: "const A *const" is detected as type="const A *" name="const"
1722 if (srcA.name=="const" || srcA.name=="volatile")
1723 {
1724 srcA.type+=" "+srcA.name;
1725 srcA.name.clear();
1726 }
1727 if (dstA.name=="const" || dstA.name=="volatile")
1728 {
1729 dstA.type+=" "+dstA.name;
1730 dstA.name.clear();
1731 }
1732
1733 if (srcA.type==dstA.type)
1734 {
1735 //printf("1. merging %s:%s <-> %s:%s\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
1736 if (srcA.name.empty() && !dstA.name.empty())
1737 {
1738 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
1739 //printf("name: '%s':='%s'\n",qPrint(srcA.name),qPrint(dstA.name));
1740 srcA.type = dstA.type;
1741 srcA.name = dstA.name;
1742 }
1743 else if (!srcA.name.empty() && dstA.name.empty())
1744 {
1745 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
1746 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1747 dstA.type = srcA.type;
1748 dstA.name = srcA.name;
1749 }
1750 else if (!srcA.name.empty() && !dstA.name.empty())
1751 {
1752 //printf("srcA.name=%s dstA.name=%s\n",qPrint(srcA.name),qPrint(dstA.name));
1753 if (forceNameOverwrite)
1754 {
1755 srcA.name = dstA.name;
1756 }
1757 else
1758 {
1759 if (srcA.docs.empty() && !dstA.docs.empty())
1760 {
1761 srcA.name = dstA.name;
1762 }
1763 else if (!srcA.docs.empty() && dstA.docs.empty())
1764 {
1765 dstA.name = srcA.name;
1766 }
1767 }
1768 }
1769 }
1770 else
1771 {
1772 //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
1773 srcA.type=srcA.type.stripWhiteSpace();
1774 dstA.type=dstA.type.stripWhiteSpace();
1775 if (srcA.type+" "+srcA.name==dstA.type) // "unsigned long:int" <-> "unsigned long int:bla"
1776 {
1777 srcA.type+=" "+srcA.name;
1778 srcA.name=dstA.name;
1779 }
1780 else if (dstA.type+" "+dstA.name==srcA.type) // "unsigned long int bla" <-> "unsigned long int"
1781 {
1782 dstA.type+=" "+dstA.name;
1783 dstA.name=srcA.name;
1784 }
1785 else if (srcA.name.empty() && !dstA.name.empty())
1786 {
1787 srcA.name = dstA.name;
1788 }
1789 else if (dstA.name.empty() && !srcA.name.empty())
1790 {
1791 dstA.name = srcA.name;
1792 }
1793 }
1794 size_t i1=srcA.type.find("::"),
1795 i2=dstA.type.find("::"),
1796 j1=srcA.type.length()-i1-2,
1797 j2=dstA.type.length()-i2-2;
1798 if (i1!=DString::npos && i2==DString::npos && srcA.type.right(j1)==dstA.type)
1799 {
1800 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
1801 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1802 dstA.type = srcA.type.left(i1+2)+dstA.type;
1803 dstA.name = srcA.name;
1804 }
1805 else if (i1==DString::npos && i2!=DString::npos && dstA.type.right(j2)==srcA.type)
1806 {
1807 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
1808 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1809 srcA.type = dstA.type.left(i2+2)+srcA.type;
1810 srcA.name = dstA.name;
1811 }
1812 if (srcA.docs.empty() && !dstA.docs.empty())
1813 {
1814 srcA.docs = dstA.docs;
1815 }
1816 else if (dstA.docs.empty() && !srcA.docs.empty())
1817 {
1818 dstA.docs = srcA.docs;
1819 }
1820 //printf("Merge argument '%s|%s' '%s|%s'\n",
1821 // qPrint(srcA.type), qPrint(srcA.name),
1822 // qPrint(dstA.type), qPrint(dstA.name));
1823 ++srcIt;
1824 ++dstIt;
1825 AUTO_TRACE_ADD("after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1826 srcA.type,srcA.name,srcA.defval,
1827 dstA.type,dstA.name,dstA.defval);
1828 }
1829}
DString docs
Definition arguments.h:48
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:54

References argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, ArgumentList::begin(), DString::clear(), Argument::defval, Argument::docs, DString::empty(), ArgumentList::end(), DString::find(), DString::left(), DString::length(), Argument::name, DString::npos, qPrint(), DString::right(), ArgumentList::size(), DString::stripWhiteSpace(), and Argument::type.

Referenced by addMemberDocs(), buildFunctionList(), and findFriends().

◆ mergeScopes()

DString mergeScopes ( const DString & leftScope,
const DString & rightScope )

Merges two scope parts together. The parts may (partially) overlap. Example1: A::B and B::C will result in A::B::C
Example2: A and B will be A::B
Example3: A::B and B will be A::B

Parameters
leftScopethe left hand part of the scope.
rightScopethe right hand part of the scope.
Returns
the merged scope.

Definition at line 3754 of file util.cpp.

3755{
3756 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
3757 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
3758 if (leftScopeMatch(leftScope,rightScope))
3759 {
3760 AUTO_TRACE_EXIT("case1={}",rightScope);
3761 return rightScope;
3762 }
3763 DString result;
3764 size_t i=0,p=leftScope.length();
3765
3766 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
3767 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
3768 bool found=false;
3769 while ((i=leftScope.rfind("::",p))!=DString::npos && i>0)
3770 {
3771 if (leftScopeMatch(rightScope,leftScope.mid(i+2)))
3772 {
3773 result = leftScope.left(i+2)+rightScope;
3774 found=true;
3775 }
3776 p=i-1;
3777 }
3778 if (found)
3779 {
3780 AUTO_TRACE_EXIT("case2={}",result);
3781 return result;
3782 }
3783
3784 // case leftScope=="A" rightScope=="B" => result = "A::B"
3785 result=leftScope;
3786 if (!result.empty() && !rightScope.empty()) result+="::";
3787 result+=rightScope;
3788 AUTO_TRACE_EXIT("case3={}",result);
3789 return result;
3790}
bool leftScopeMatch(const DString &scope, const DString &name)
Definition util.cpp:740

References AUTO_TRACE, AUTO_TRACE_EXIT, DString::empty(), DString::left(), leftScopeMatch(), DString::length(), DString::mid(), DString::npos, and DString::rfind().

Referenced by addEnumValuesToEnums(), addVariable(), findEnums(), findMember(), and stripTemplateSpecifiersFromScope().

◆ normalizeNonTemplateArgumentsInString()

DString normalizeNonTemplateArgumentsInString ( const DString & name,
const Definition * context,
const ArgumentList & formalArgs )

Returns a representation of name where all known types have been normalized to their canonical form. The normalization is done in the context of context and using the formal arguments in formalArgs.

Definition at line 3466 of file util.cpp.

3470{
3471 // skip until <
3472 size_t p=name.find('<');
3473 if (p==DString::npos) return name;
3474 p++;
3475 DString result = name.left(p);
3476
3477 std::string s = name.mid(p).str();
3478 static const reg::Ex re(R"([\a:][\w:]*)");
3479 reg::Iterator it(s,re);
3481 size_t pi=0;
3482 // for each identifier in the template part (e.g. B<T> -> T)
3483 for (; it!=end ; ++it)
3484 {
3485 const auto &match = *it;
3486 size_t i = match.position();
3487 size_t l = match.length();
3488 result += s.substr(pi,i-pi);
3489 DString n(match.str());
3490 bool found=false;
3491 for (const Argument &formArg : formalArgs)
3492 {
3493 if (formArg.name == n)
3494 {
3495 found=true;
3496 break;
3497 }
3498 }
3499 if (!found)
3500 {
3501 // try to resolve the type
3502 SymbolResolver resolver;
3503 const ClassDef *cd = resolver.resolveClass(context,n);
3504 if (cd)
3505 {
3506 result+=cd->name();
3507 }
3508 else
3509 {
3510 result+=n;
3511 }
3512 }
3513 else
3514 {
3515 result+=n;
3516 }
3517 pi=i+l;
3518 }
3519 result+=s.substr(pi);
3520 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
3521 return removeRedundantWhiteSpace(result);
3522}
DString substr(size_t pos=0, size_t count=npos) const
Returns a substring of length count starting at pos.
Definition dstring.h:223
const ClassDef * resolveClass(const Definition *scope, const DString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.

References end(), DString::find(), DString::left(), DString::mid(), Definition::name(), DString::npos, removeRedundantWhiteSpace(), SymbolResolver::resolveClass(), DString::str(), and DString::substr().

Referenced by findUsedClassesForClass().

◆ openOutputFile()

bool openOutputFile ( const DString & outFile,
std::ofstream & f )

Helper to open an output search f for writing. If the file already exists it will be renamed to .bak first. If outFile is "-" then the output will be written to standard output.

Definition at line 4987 of file util.cpp.

4988{
4989 ASSERT(!f.is_open());
4990 bool fileOpened=false;
4991 bool writeToStdout=outFile=="-";
4992 if (writeToStdout) // write to stdout
4993 {
4994 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
4995 fileOpened = true;
4996 }
4997 else // write to file
4998 {
4999 FileInfo fi(outFile.str());
5000 if (fi.exists()) // create a backup
5001 {
5002 Dir dir;
5003 FileInfo backup(fi.filePath()+".bak");
5004 if (backup.exists()) // remove existing backup
5005 dir.remove(backup.filePath());
5006 dir.rename(fi.filePath(),fi.filePath()+".bak");
5007 }
5008 f = Portable::openOutputStream(outFile);
5009 fileOpened = f.is_open();
5010 }
5011 return fileOpened;
5012}
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:327
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:681

References ASSERT, FileInfo::exists(), FileInfo::filePath(), Portable::openOutputStream(), Dir::remove(), Dir::rename(), and DString::str().

Referenced by compareDoxyfile(), generateConfigFile(), readConfiguration(), and writeDefaultLayoutFile().

◆ projectLogoFile()

DString projectLogoFile ( )

Definition at line 2581 of file util.cpp.

2582{
2583 DString projectLogo = Config_getString(PROJECT_LOGO);
2584 if (!projectLogo.empty())
2585 {
2586 // check for optional width= and height= specifier
2587 if (size_t wi = projectLogo.find(" width="); wi!=DString::npos) // and strip them
2588 {
2589 projectLogo = projectLogo.left(wi);
2590 }
2591 if (size_t hi = projectLogo.find(" height="); hi!=DString::npos)
2592 {
2593 projectLogo = projectLogo.left(hi);
2594 }
2595 }
2596 //printf("projectlogo='%s'\n",qPrint(projectLogo));
2597 return projectLogo;
2598}

References Config_getString, DString::empty(), DString::find(), DString::left(), and DString::npos.

Referenced by copyLogo(), substituteHtmlKeywords(), and substituteLatexKeywords().

◆ projectLogoSize()

DString projectLogoSize ( )

Definition at line 2600 of file util.cpp.

2601{
2602 DString sizeVal;
2603 DString projectLogo = Config_getString(PROJECT_LOGO);
2604 if (!projectLogo.empty())
2605 {
2606 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> DString
2607 {
2608 DString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
2609 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
2610 {
2611 result="\""+result+"\"";
2612 }
2613 result.prepend(startMarker);
2614 return result;
2615 };
2616 // check for optional width= and height= specifier
2617 size_t wi = projectLogo.find(" width=");
2618 size_t hi = projectLogo.find(" height=");
2619 if (wi!=DString::npos && hi!=DString::npos)
2620 {
2621 if (wi<hi) // "... width=x height=y..."
2622 {
2623 sizeVal = extractDimension(" width=", wi+7, hi) + " "
2624 + extractDimension(" height=", hi+8, projectLogo.length());
2625 }
2626 else // "... height=y width=x..."
2627 {
2628 sizeVal = extractDimension(" height=", hi+8, wi) + " "
2629 + extractDimension(" width=", wi+7, projectLogo.length());
2630 }
2631 }
2632 else if (wi!=DString::npos) // ... width=x..."
2633 {
2634 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
2635 }
2636 else if (hi!=DString::npos) // ... height=x..."
2637 {
2638 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
2639 }
2640 }
2641 //printf("projectsize='%s'\n",qPrint(sizeVal));
2642 return sizeVal;
2643}
DString quoted() const
Definition dstring.h:352

References DString::at(), Config_getString, DString::empty(), DString::find(), DString::length(), DString::mid(), DString::npos, DString::prepend(), DString::quoted(), and DString::stripWhiteSpace().

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 4672 of file util.cpp.

4673{
4674 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4675 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
4676
4677 return (prot!=Protection::Private && prot!=Protection::Package) ||
4678 (prot==Protection::Private && extractPrivate) ||
4679 (prot==Protection::Package && extractPackage);
4680}

References Config_getBool.

Referenced by MemberDefImpl::_computeLinkableInProject(), addClassAndNestedClasses(), computeClassRelations(), MemberDefImpl::hasDetailedDescription(), ClassDefImpl::internalInsertMember(), MemberDefImpl::isBriefSectionVisible(), ClassDefImpl::isLinkableInProject(), ClassDefImpl::isVisibleInHierarchy(), MemberDefImpl::warnIfUndocumented(), MemberDefImpl::writeDeclaration(), ClassDefImpl::writeDocumentationForInnerClasses(), ClassDefImpl::writeMemberList(), and ClassDefImpl::writeTagFile().

◆ readInputFile()

bool readInputFile ( const DString & fileName,
std::string & contents,
bool filter = true,
bool isSourceCode = false )

read a file name fileName and optionally filter and transcode it

Definition at line 4375 of file util.cpp.

4376{
4377 // try to open file
4378 FileInfo fi(fileName.str());
4379 if (!fi.exists()) return false;
4380 DString filterName = getFileFilter(fileName,isSourceCode);
4381 if (filterName.empty() || !filter)
4382 {
4383 std::ifstream f = Portable::openInputStream(fileName,true);
4384 if (!f.is_open())
4385 {
4386 err("could not open file {}\n",fileName);
4387 return false;
4388 }
4389 // read the file
4390 auto fileSize = fi.size();
4391 contents.resize(fileSize);
4392 f.read(contents.data(),fileSize);
4393 if (f.fail())
4394 {
4395 err("problems while reading file {}\n",fileName);
4396 return false;
4397 }
4398 }
4399 else
4400 {
4401 DString cmd=filterName+" \""+fileName+"\"";
4402 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
4403 FILE *f=Portable::popen(cmd,"r");
4404 if (!f)
4405 {
4406 err("could not execute filter {}\n",filterName);
4407 return false;
4408 }
4409 const int bufSize=4096;
4410 char buf[bufSize];
4411 int numRead = 0;
4412 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
4413 {
4414 //printf(">>>>>>>>Reading %d bytes\n",numRead);
4415 contents.append(buf,numRead);
4416 }
4418 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
4419 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
4420 }
4421
4422 if (contents.size()>=2 &&
4423 static_cast<uint8_t>(contents[0])==0xFF &&
4424 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
4425 ) // UCS-2LE encoded file
4426 {
4427 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
4428 }
4429 else if (contents.size()>=2 &&
4430 static_cast<uint8_t>(contents[0])==0xFE &&
4431 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
4432 ) // UCS-2BE encoded file
4433 {
4434 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
4435 }
4436 else if (contents.size()>=3 &&
4437 static_cast<uint8_t>(contents[0])==0xEF &&
4438 static_cast<uint8_t>(contents[1])==0xBB &&
4439 static_cast<uint8_t>(contents[2])==0xBF
4440 ) // UTF-8 encoded file
4441 {
4442 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
4443 }
4444 else // transcode according to the INPUT_ENCODING setting
4445 {
4446 // do character transcoding if needed.
4447 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
4448 }
4449
4450 filterCRLF(contents);
4451 return true;
4452}
@ FilterOutput
Definition debug.h:39
@ ExtCmd
Definition debug.h:37
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:78
FILE * popen(const DString &name, const DString &type)
Definition portable.cpp:495
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:692
int pclose(FILE *stream)
Definition portable.cpp:504
static void filterCRLF(std::string &contents)
Definition util.cpp:959
DString getFileFilter(const DString &name, bool isSourceCode)
Definition util.cpp:1020
static void transcodeCharacterBuffer(const DString &fileName, std::string &contents, const DString &inputEncoding, const DString &outputEncoding)
Definition util.cpp:4339
DString getEncoding(const FileInfo &fi)
Definition util.cpp:4478

References DString::empty(), err, FileInfo::exists(), Debug::ExtCmd, filterCRLF(), Debug::FilterOutput, getEncoding(), getFileFilter(), Portable::openInputStream(), Portable::pclose(), Portable::popen(), Debug::print(), FileInfo::size(), DString::str(), and transcodeCharacterBuffer().

Referenced by checkAndOpenFile(), fileToString(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), parseFile(), parseInput(), readIncludeFile(), DocbookDocVisitor::startMermaidFile(), LatexDocVisitor::startMermaidFile(), DocbookDocVisitor::startPlantUmlFile(), and LatexDocVisitor::startPlantUmlFile().

◆ relativePathToRoot()

DString relativePathToRoot ( const DString & name)

Definition at line 2913 of file util.cpp.

2914{
2915 DString result;
2916 if (Config_getBool(CREATE_SUBDIRS))
2917 {
2918 if (name.empty())
2919 {
2920 return REL_PATH_TO_ROOT;
2921 }
2922 else if (size_t i = name.rfind('/'); i!=DString::npos)
2923 {
2924 result=REL_PATH_TO_ROOT;
2925 }
2926 }
2927 return result;
2928}
#define REL_PATH_TO_ROOT
Definition util.cpp:78

References Config_getBool, DString::empty(), DString::npos, REL_PATH_TO_ROOT, and DString::rfind().

Referenced by generateBriefDoc(), DocbookGenerator::startFile(), HtmlGenerator::startFile(), LatexGenerator::startFile(), RTFGenerator::startFile(), and validatingParseDoc().

◆ removeAnonymousScopes()

DString removeAnonymousScopes ( const DString & str)

Removes all anonymous scopes from string s Possible examples:

   "bla::@10::blep"      => "bla::blep"
   "bla::@10::@11::blep" => "bla::blep"
   "@10::blep"           => "blep"
   " @10::blep"          => "blep"
   "@9::@10::blep"       => "blep"
   "bla::@1"             => "bla"
   "bla::@1::@2"         => "bla"
   "bla @1"              => "bla"

Definition at line 98 of file util.cpp.

99{
100 std::string result;
101 if (str.empty()) return result;
102
103 // helper to check if the found delimiter starts with a colon
104 auto startsWithColon = [](const std::string &del)
105 {
106 for (size_t i=0;i<del.size();i++)
107 {
108 if (del[i]=='@') return false;
109 else if (del[i]==':') return true;
110 }
111 return false;
112 };
113
114 // helper to check if the found delimiter ends with a colon
115 auto endsWithColon = [](const std::string &del)
116 {
117 for (int i=static_cast<int>(del.size())-1;i>=0;i--)
118 {
119 if (del[i]=='@') return false;
120 else if (del[i]==':') return true;
121 }
122 return false;
123 };
124
125 static const reg::Ex re(R"([\s:]*@\d+[\s:]*)");
126 std::string s = str.str();
127 reg::Iterator iter(s,re);
129 size_t p=0;
130 size_t sl=s.length();
131 bool needsSeparator=false;
132 for ( ; iter!=end ; ++iter)
133 {
134 const auto &match = *iter;
135 size_t i = match.position();
136 if (i>p) // add non-matching prefix
137 {
138 if (needsSeparator) result+="::";
139 needsSeparator=false;
140 result+=s.substr(p,i-p);
141 }
142 std::string delim = match.str();
143 needsSeparator = needsSeparator || (startsWithColon(delim) && endsWithColon(delim));
144 p = match.position()+match.length();
145 }
146 if (p<sl) // add trailing remainder
147 {
148 if (needsSeparator) result+="::";
149 result+=s.substr(p);
150 }
151 return result;
152}

References DString::empty(), end(), and DString::str().

Referenced by MemberDefImpl::displayDefinition(), generateClassMemberLink(), ClassDefImpl::internalInsertMember(), makeDisplayName(), makeDisplayName(), simplifyTypeForTable(), MemberDefImpl::writeDeclaration(), and MemberDefImpl::writeDocumentation().

◆ removeRedundantWhiteSpace()

DString removeRedundantWhiteSpace ( const DString & s)

Definition at line 426 of file util.cpp.

427{
428 bool cliSupport = Config_getBool(CPP_CLI_SUPPORT);
429 bool vhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
430
431 if (s.empty() || vhdl) return s;
432
433 // We use a static character array to
434 // improve the performance of this function
435 // and thread_local is needed to make it multi-thread safe
436 static THREAD_LOCAL char *growBuf = nullptr;
437 static THREAD_LOCAL size_t growBufLen = 0;
438 if (s.length()*3>growBufLen) // For input character we produce at most 3 output characters,
439 {
440 growBufLen = s.length()*3;
441 growBuf = static_cast<char *>(realloc(growBuf,growBufLen+1)); // add 1 for 0-terminator
442 }
443 if (growBuf==nullptr) return s; // should not happen, only we run out of memory
444
445 const char *src=s.data();
446 char *dst=growBuf;
447
448 size_t i=0;
449 size_t l=s.length();
450 size_t csp=0;
451 size_t vosp=0;
452 size_t vsp=0;
453 size_t osp=0;
454 char pc=0;
455 // skip leading whitespace
456 while (i<l && isspace(static_cast<uint8_t>(src[i])))
457 {
458 i++;
459 }
460 for (;i<l;i++)
461 {
462 char c=src[i];
463 char nc=i+1<l ? src[i+1] : ' ';
464
465 auto searchForKeyword = [&](const char *kw,size_t &matchLen,size_t totalLen)
466 {
467 if (matchLen<=totalLen && c==kw[matchLen] && // character matches substring kw
468 (matchLen>0 || // inside search string
469 i==0 || // if it is the first character
470 !isId(pc) // the previous may not be a digit
471 )
472 )
473 matchLen++;
474 else // reset counter
475 matchLen=0;
476 };
477 searchForKeyword(constScope, csp, 5); // keyword: const
478 searchForKeyword(volatileScope, vosp, 8); // keyword: volatile
479 searchForKeyword(virtualScope, vsp, 7); // keyword: virtual
480
481 // search for "operator"
482 if (osp<11 && (osp>=8 || c==operatorScope[osp]) && // character matches substring "operator" followed by 3 arbitrary characters
483 (osp>0 || // inside search string
484 i==0 || // if it is the first character
485 !isId(pc) // the previous may not be a digit
486 )
487 )
488 osp++;
489 else // reset counter
490 osp=0;
491
492 switch(c)
493 {
494 case '"': // quoted string
495 {
496 *dst++=c;
497 i++;
498 for (;i<l;i++) // find end of string
499 {
500 c = src[i];
501 *dst++=c;
502 if (c=='\\' && i+1<l)
503 {
504 i++;
505 c = src[i];
506 *dst++=c;
507 }
508 else if (c=='"')
509 {
510 break;
511 }
512 }
513 }
514 break;
515 case '<': // current char is a <
516 *dst++=c;
517 if (i+1<l &&
518 (isId(nc)) && // next char is an id char
519 (osp<8) // string in front is not "operator"
520 )
521 {
522 *dst++=' '; // add extra space
523 }
524 break;
525 case '>': // current char is a >
526 if (i>0 && !isspace(static_cast<uint8_t>(pc)) &&
527 (isId(pc) || pc=='*' || pc=='&' || pc=='.' || pc=='>') && // prev char is an id char or space or *&.
528 (osp<8 || (osp==8 && pc!='-')) // string in front is not "operator>" or "operator->"
529 )
530 {
531 *dst++=' '; // add extra space in front
532 }
533 *dst++=c;
534 if (i+1<l && (nc=='-' || nc=='&')) // '>-' -> '> -'
535 {
536 *dst++=' '; // add extra space after
537 }
538 break;
539 case ',': // current char is a ,
540 *dst++=c;
541 if (i>0 && !isspace(static_cast<uint8_t>(pc)) &&
542 ((i+1<l && (isId(nc) || nc=='[')) || // the [ is for attributes (see bug702170)
543 (i+2<l && nc=='$' && isId(src[i+2])) || // for PHP: ',$name' -> ', $name'
544 (i+3<l && nc=='&' && src[i+2]=='$' && isId(src[i+3])) // for PHP: ',&$name' -> ', &$name'
545 )
546 )
547 {
548 *dst++=' '; // add extra space after
549 }
550 break;
551 case '^': // CLI 'Type^name' -> 'Type^ name'
552 case '%': // CLI 'Type%name' -> 'Type% name'
553 *dst++=c;
554 if (cliSupport && i+1<l && (isId(nc) || nc=='-'))
555 {
556 *dst++=' '; // add extra space after
557 }
558 break;
559 case ')': // current char is a ) -> ')name' -> ') name'
560 *dst++=c;
561 if (i+1<l && (isId(nc) || nc=='-'))
562 {
563 *dst++=' '; // add extra space after
564 }
565 break;
566 case '*':
567 if (i>0 && pc!=' ' && pc!='\t' && pc!=':' &&
568 pc!='*' && pc!='&' && pc!='(' && pc!='/' && pc!='[' &&
569 pc!='.' && osp<9
570 )
571 // avoid splitting &&, **, .*, operator*, operator->*
572 {
573 *dst++=' ';
574 }
575 *dst++=c;
576 break;
577 case '&':
578 if (i>0 && isId(pc) && osp<9)
579 {
580 if (nc != '=')
581 // avoid splitting operator&=
582 {
583 *dst++=' ';
584 }
585 }
586 *dst++=c;
587 break;
588 case '$': // '$name' -> ' $name'
589 // 'name$name' -> 'name$name'
590 if (isId(pc))
591 {
592 *dst++=c;
593 break;
594 }
595 // else fallthrough
596 case '@': // '@name' -> ' @name'
597 case '\'': // ''name' -> '' name'
598 if (i>0 && i+1<l && pc!='=' && pc!=':' && !isspace(static_cast<uint8_t>(pc)) &&
599 isId(nc) && osp<8) // ")id" -> ") id"
600 {
601 *dst++=' ';
602 }
603 *dst++=c;
604 break;
605 case ':': // current char is a :
606 if (csp==6) // replace const::A by const ::A
607 {
608 *dst++=' ';
609 csp=0;
610 }
611 else if (vosp==9) // replace volatile::A by volatile ::A
612 {
613 *dst++=' ';
614 vosp=0;
615 }
616 else if (vsp==8) // replace virtual::A by virtual ::A
617 {
618 *dst++=' ';
619 vsp=0;
620 }
621 *dst++=c;
622 break;
623 case ' ': // fallthrough
624 case '\n': // fallthrough
625 case '\t':
626 {
627 if (g_charAroundSpace.charMap[static_cast<uint8_t>(pc)].before &&
628 g_charAroundSpace.charMap[static_cast<uint8_t>(nc)].after &&
629 !(pc==',' && nc=='.') &&
630 (osp<8 || (osp>=8 && isId(pc) && isId(nc)))
631 // e.g. 'operator >>' -> 'operator>>',
632 // 'operator "" _x' -> 'operator""_x',
633 // but not 'operator int' -> 'operatorint'
634 )
635 { // keep space
636 *dst++=' ';
637 }
638 else if ((pc=='*' || pc=='&' || pc=='.') && nc=='>')
639 {
640 *dst++=' ';
641 }
642 }
643 break;
644 default:
645 *dst++=c;
646 auto correctKeywordAllowedInsideScope = [&](char cc,size_t &matchLen,size_t totalLen) {
647 if (c==cc && matchLen==totalLen)
648 {
649 if ((i+2<l && src[i+1] == ':' && src[i+2] == ':') || // keyword::
650 ((i>matchLen && src[i-matchLen] == ':' && src[i-matchLen-1] == ':')) // ::keyword
651 ) matchLen = 0;
652 };
653 };
654 correctKeywordAllowedInsideScope('t',csp, 5); // keyword: const
655 correctKeywordAllowedInsideScope('e',vosp,8); // keyword: volatile
656 correctKeywordAllowedInsideScope('l',vsp, 7); // keyword: virtual
657
658 auto correctKeywordNotPartOfScope = [&](char cc,size_t &matchLen,size_t totalLen)
659 {
660 if (c==cc && matchLen==totalLen && i+1<l && // found matching keyword
661 !(isId(nc) || nc==')' || nc==',' || disspace(nc))
662 ) // prevent keyword ::A from being converted to keyword::A
663 {
664 *dst++=' ';
665 matchLen=0;
666 }
667 };
668 correctKeywordNotPartOfScope('t',csp, 5); // keyword: const
669 correctKeywordNotPartOfScope('e',vosp,8); // keyword: volatile
670 correctKeywordNotPartOfScope('l',vsp, 7); // keyword: virtual
671 break;
672 }
673 pc=c;
674 }
675 *dst++='\0';
676 //printf("removeRedundantWhitespace(%s)->%s\n",qPrint(s),growBuf);
677 return growBuf;
678}
#define THREAD_LOCAL
Definition doxygen.h:29
bool disspace(char c)
Definition dstring.h:62
Token literal values and constants.
Definition CharStream.h:12
CharElem charMap[256]
Definition util.cpp:420
static const char constScope[]
Definition util.cpp:379
static const char virtualScope[]
Definition util.cpp:381
static const char volatileScope[]
Definition util.cpp:380
static CharAroundSpace g_charAroundSpace
Definition util.cpp:423
static const char operatorScope[]
Definition util.cpp:382

References CharAroundSpace::CharElem::after, CharAroundSpace::CharElem::before, CharAroundSpace::charMap, Config_getBool, constScope, DString::data(), disspace(), DString::empty(), g_charAroundSpace, isId(), DString::length(), operatorScope, THREAD_LOCAL, virtualScope, and volatileScope.

Referenced by addFrom(), addGlobalFunction(), addMethodToClass(), addVariable(), addVariableToClass(), argListToString(), buildFunctionList(), buildInterfaceAndServiceList(), buildTypedefList(), ClassDefImpl::ClassDefImpl(), extractCanonicalType(), findClassRelation(), DocParser::findDocsForMemberOrCompound(), findMember(), findUsedClassesForClass(), findUsingDeclImports(), ArgumentList::finishTrailingReturnType(), generateFunctionLink(), generateFunctionLink(), generateLink(), getCanonicalTypeForIdentifier(), getLink(), getLink(), getLink(), MemberDefImpl::init(), ClassDefImpl::insertTemplateInstance(), MemberDefImpl::MemberDefImpl(), normalizeNonTemplateArgumentsInString(), parseFuncDecl(), resolveRef(), tempArgListToString(), and writeExceptionListImpl().

◆ replaceAnonymousScopes()

DString replaceAnonymousScopes ( const DString & s,
const DString & replacement = DString() )

Definition at line 155 of file util.cpp.

156{
157 if (s.empty()) return s;
158 static const reg::Ex marker(R"(@\d+)");
159 std::string result = reg::replace(s.str(),marker,
160 !replacement.empty() ? replacement.data() : "__anonymous__");
161 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
162 return result;
163}
std::string replace(std::string_view str, const Ex &re, std::string_view replacement)
Searching in a given input string for parts that match regular expression re and replaces those parts...
Definition regex.cpp:872

References DString::data(), DString::empty(), reg::replace(), and DString::str().

Referenced by addMemberFunction(), findGlobalMember(), and generateDEFForMember().

◆ replaceColorMarkers()

DString replaceColorMarkers ( const DString & str)

Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC, where #AABBCC represents a valid color, based on the intensity represented by hex number AA and the current HTML_COLORSTYLE_* settings.

Definition at line 4569 of file util.cpp.

4570{
4571 if (str.empty()) return DString();
4572 std::string result;
4573 std::string s=str.str();
4574 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
4575 reg::Iterator it(s,re);
4577 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
4578 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
4579 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
4580 size_t sl=s.length();
4581 size_t p=0;
4582 for (; it!=end ; ++it)
4583 {
4584 const auto &match = *it;
4585 size_t i = match.position();
4586 size_t l = match.length();
4587 if (i>p) result+=s.substr(p,i-p);
4588 std::string lumStr = match.str().substr(2);
4589#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
4590 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
4591 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
4592
4593 double r = 0,g = 0,b = 0;
4594 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
4595 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
4596 pow(level/255.0,gamma/100.0),&r,&g,&b);
4597 int red = static_cast<int>(r*255.0);
4598 int green = static_cast<int>(g*255.0);
4599 int blue = static_cast<int>(b*255.0);
4600 char colStr[8];
4601 colStr[0]='#';
4602 colStr[1]=hex[red>>4];
4603 colStr[2]=hex[red&0xf];
4604 colStr[3]=hex[green>>4];
4605 colStr[4]=hex[green&0xf];
4606 colStr[5]=hex[blue>>4];
4607 colStr[6]=hex[blue&0xf];
4608 colStr[7]=0;
4609 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
4610 result+=colStr;
4611 p=i+l;
4612 }
4613 if (p<sl) result+=s.substr(p);
4614 return result;
4615}
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
Definition image.cpp:373
#define HEXTONUM(x)

References Config_getInt, DString::empty(), end(), hex, HEXTONUM, ColoredImage::hsl2rgb(), and DString::str().

Referenced by ResourceMgr::copyResourceAs(), fillColorStyleMaps(), HtmlGenerator::init(), and writeDefaultStyleSheet().

◆ resolveLink()

bool resolveLink ( const DString & scName,
const DString & lr,
bool inSeeBlock,
const Definition ** resContext,
DString & resAnchor,
SrcLangExt lang,
const DString & prefix = DString(),
const FileDef * currentFile = nullptr )

Returns an symbol definition given its name and context for an explicitly linked symbol.

Postcondition
return value true implies *resContext!=0

Definition at line 2308 of file util.cpp.

2317{
2318 *resContext=nullptr;
2319
2320 DString linkRef=lr;
2321 if (lang==SrcLangExt::CSharp)
2322 {
2323 linkRef = mangleCSharpGenericName(linkRef);
2324 }
2325 DString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,false);
2326 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2327 const FileDef *fd = nullptr;
2328 const GroupDef *gd = nullptr;
2329 const PageDef *pd = nullptr;
2330 const ClassDef *cd = nullptr;
2331 const DirDef *dir = nullptr;
2332 const ConceptDef *cnd = nullptr;
2333 const ModuleDef *modd = nullptr;
2334 const NamespaceDef *nd = nullptr;
2335 const SectionInfo *si = nullptr;
2336 bool ambig = false;
2337 if (linkRef.empty()) // no reference name!
2338 {
2339 AUTO_TRACE_EXIT("no_ref");
2340 return false;
2341 }
2342 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2343 {
2344 gd = pd->getGroupDef();
2345 if (gd)
2346 {
2347 if (!pd->name().empty()) si=SectionManager::instance().find(pd->name());
2348 *resContext=gd;
2349 if (si) resAnchor = si->label();
2350 }
2351 else
2352 {
2353 *resContext=pd;
2354 }
2355 AUTO_TRACE_EXIT("page");
2356 return true;
2357 }
2358 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2359 {
2360 *resContext=si->definition();
2361 resAnchor = si->label();
2362 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2363 return true;
2364 }
2365 else if (!prefix.empty() && (si=SectionManager::instance().find(linkRef)))
2366 {
2367 *resContext=si->definition();
2368 resAnchor = si->label();
2369 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2370 return true;
2371 }
2372 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2373 {
2374 *resContext=pd;
2375 AUTO_TRACE_EXIT("example");
2376 return true;
2377 }
2378 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2379 {
2380 *resContext=gd;
2381 AUTO_TRACE_EXIT("group");
2382 return true;
2383 }
2384 else if ((fd=Doxygen::inputNameLinkedMap->findFileDef(linkRef,ambig)) // file link
2385 && fd->isLinkable())
2386 {
2387 *resContext=fd;
2388 AUTO_TRACE_EXIT("file");
2389 return true;
2390 }
2391 else if ((cd=getClass(linkRef))) // class link
2392 {
2393 *resContext=cd;
2394 resAnchor=cd->anchor();
2395 AUTO_TRACE_EXIT("class");
2396 return true;
2397 }
2398 else if (lang==SrcLangExt::Java &&
2399 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2400 {
2401 *resContext=cd;
2402 resAnchor=cd->anchor();
2403 AUTO_TRACE_EXIT("generic");
2404 return true;
2405 }
2406 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2407 {
2408 *resContext=cd;
2409 resAnchor=cd->anchor();
2410 AUTO_TRACE_EXIT("protocol");
2411 return true;
2412 }
2413 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2414 {
2415 *resContext=cnd;
2416 resAnchor=cnd->anchor();
2417 AUTO_TRACE_EXIT("concept");
2418 return true;
2419 }
2420 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2421 {
2422 *resContext=modd;
2423 resAnchor=modd->anchor();
2424 AUTO_TRACE_EXIT("module");
2425 return true;
2426 }
2427 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2428 {
2429 *resContext=nd;
2430 AUTO_TRACE_EXIT("namespace");
2431 return true;
2432 }
2433 else if ((dir=resolveDirLink(linkRef)) && dir->isLinkable())
2434 {
2435 *resContext=dir;
2436 AUTO_TRACE_EXIT("directory");
2437 return true;
2438 }
2439 else // probably a member reference
2440 {
2441 const MemberDef *md = nullptr;
2442 bool res = resolveRef(scName,lr,true,resContext,&md,lang,true,currentFile);
2443 if (md) resAnchor=md->anchor();
2444 AUTO_TRACE_EXIT("member? res={}",res);
2445 return res;
2446 }
2447}
constexpr auto prefix
Definition anchor.cpp:47
virtual bool isLinkable() const =0
virtual DString anchor() const =0
A model of a directory symbol.
Definition dirdef.h:108
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:108
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:97
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:91
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:92
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:107
A model of a group of symbols.
Definition groupdef.h:48
const T * find(const std::string &key) const
Definition linkedmap.h:47
static ModuleManager & instance()
A model of a page symbol.
Definition pagedef.h:27
virtual const GroupDef * getGroupDef() const =0
class that provide information about a section.
Definition section.h:58
Definition * definition() const
Definition section.h:77
DString label() const
Definition section.h:69
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
ConceptDef * getConcept(const DString &n)
bool resolveRef(const DString &scName, const DString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
Definition util.cpp:2008
DString stripTemplateSpecifiersFromScope(const DString &fullName, bool parentOnly, DString *pLastScopeStripped, DString scopeName, bool allowArtificial)
Definition util.cpp:3687
static const DirDef * resolveDirLink(const DString &linkRef)
Definition util.cpp:2290
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5335

References Definition::anchor(), AUTO_TRACE, AUTO_TRACE_EXIT, SectionInfo::definition(), DString::empty(), Doxygen::exampleLinkedMap, LinkedMap< T, Hash, KeyEqual, Map >::find(), getClass(), getConcept(), PageDef::getGroupDef(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), SectionManager::instance(), Definition::isLinkable(), SectionInfo::label(), mangleCSharpGenericName(), Definition::name(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, prefix, resolveDirLink(), resolveRef(), and stripTemplateSpecifiersFromScope().

Referenced by DocLink::DocLink(), and DocRef::DocRef().

◆ resolveRef()

bool resolveRef ( const DString & scName,
const DString & name,
bool inSeeBlock,
const Definition ** resContext,
const MemberDef ** resMember,
SrcLangExt lang,
bool lookForSpecializations = true,
const FileDef * currentFile = nullptr,
bool checkScope = false )

Returns a symbol definition (compound and/or member) given its name and context.

Postcondition
return value true implies *resContext!=0 or *resMember!=0

Definition at line 2008 of file util.cpp.

2018{
2019 AUTO_TRACE("scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2020 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->name() : "", checkScope);
2021 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2022 DString tsName = name;
2023 //bool memberScopeFirst = tsName.find('#')!=-1;
2024 DString fullName = substitute(tsName,"#","::");
2025 if (fullName.find("anonymous_namespace{")==DString::npos)
2026 {
2027 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2028 }
2029 else
2030 {
2031 fullName = removeRedundantWhiteSpace(fullName);
2032 }
2033
2034 size_t templStartPos;
2035 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=DString::npos)
2036 {
2037 size_t templEndPos = fullName.rfind('>');
2038 if (templEndPos!=DString::npos)
2039 {
2040 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2041 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2042 }
2043 }
2044
2045 size_t bracePos = findParameterList(fullName);
2046 size_t endNamePos = bracePos!=DString::npos ? bracePos : fullName.length();
2047 size_t scopePos = fullName.rfind("::",endNamePos);
2048 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2049 ((scopePos!=DString::npos && scopePos>2) || // ::N::A
2050 tsName.startsWith("::") || // ::foo in local scope
2051 scName==nullptr // #foo in global scope
2052 );
2053 bool allowTypeOnly=false;
2054
2055 // default result values
2056 *resContext=nullptr;
2057 *resMember=nullptr;
2058
2059 if (bracePos==DString::npos) // simple name
2060 {
2061 // the following if() was commented out for releases in the range
2062 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2063 if (!inSeeBlock && scopePos==DString::npos && isLowerCase(tsName))
2064 { // link to lower case only name => do not try to autolink
2065 AUTO_TRACE_ADD("false");
2066 return false;
2067 }
2068
2069 ClassDef *cd=nullptr;
2070 NamespaceDef *nd=nullptr;
2071 ConceptDef *cnd=nullptr;
2072 ModuleDef *modd=nullptr;
2073
2074 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2075
2076 // check if this is a class or namespace reference
2077 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2078 {
2079 //printf("found scopeDef\n");
2080 if (cd) // scope matches that of a class
2081 {
2082 *resContext = cd;
2083 }
2084 else if (cnd)
2085 {
2086 *resContext = cnd;
2087 }
2088 else if (modd)
2089 {
2090 *resContext = modd;
2091 }
2092 else // scope matches that of a namespace
2093 {
2094 ASSERT(nd!=nullptr);
2095 *resContext = nd;
2096 }
2097 AUTO_TRACE_ADD("true");
2098 return true;
2099 }
2100 else if (scName==fullName || (!inSeeBlock && scopePos==DString::npos))
2101 // nothing to link => output plain text
2102 {
2103 //printf("found scName=%s fullName=%s scName==fullName=%d "
2104 // "inSeeBlock=%d scopePos=%d!\n",
2105 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
2106
2107 // at this point we have a bare word that is not a class or namespace
2108 // we should also allow typedefs or enums to be linked, but not for instance member
2109 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
2110 // 'Foo' class. So we use this flag as a filter.
2111 allowTypeOnly=true;
2112 }
2113
2114 // continue search...
2115 }
2116
2117 // extract userscope+name
2118 DString nameStr=fullName.left(endNamePos);
2119 if (explicitScope) nameStr=nameStr.mid(2);
2120
2121
2122 // extract arguments
2123 DString argsStr;
2124 if (bracePos!=DString::npos) argsStr=fullName.mid(bracePos);
2125
2126 // strip template specifier
2127 // TODO: match against the correct partial template instantiation
2128 size_t templPos = nameStr.find('<');
2129 bool tryUnspecializedVersion = false;
2130 if (templPos!=DString::npos && nameStr.find("operator")==DString::npos)
2131 {
2132 size_t endTemplPos=nameStr.rfind('>');
2133 if (endTemplPos!=DString::npos)
2134 {
2135 if (!lookForSpecialization)
2136 {
2137 nameStr=nameStr.left(templPos)+nameStr.mid(endTemplPos+1);
2138 }
2139 else
2140 {
2141 tryUnspecializedVersion = true;
2142 }
2143 }
2144 }
2145
2146 DString scopeStr=scName;
2147 if (!explicitScope && nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
2148 {
2149 nameStr=nameStr.mid(scopeStr.length()+2);
2150 }
2151
2152 const GroupDef *gd = nullptr;
2153 const ConceptDef *cnd = nullptr;
2154 const ModuleDef *modd = nullptr;
2155
2156 // check if nameStr is a member or global.
2157 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
2158 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
2159 GetDefInput input(scopeStr,nameStr,argsStr);
2160 input.forceEmptyScope = explicitScope;
2161 input.currentFile = currentFile;
2162 input.checkCV = true;
2163 GetDefResult result = getDefs(input);
2164 if (result.found)
2165 {
2166 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
2167 size_t np = nameStr.find("::");
2168 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
2169 !result.md->isStrongEnumValue() &&
2170 (!scopeStr.empty() || (np!=DString::npos && np>0)))
2171 {
2172 // we did find a member, but it is a global one while we were explicitly
2173 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
2174 // note we do need to support autolinking to "::symbol" hence the >0
2175 //printf("not global member!\n");
2176 *resContext=nullptr;
2177 *resMember=nullptr;
2178 AUTO_TRACE_ADD("false");
2179 return false;
2180 }
2181 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
2182 if (result.md)
2183 {
2184 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
2185 {
2186 *resMember=result.md;
2187 *resContext=result.md;
2188 }
2189 else // md is not a type, but we explicitly expect one
2190 {
2191 *resContext=nullptr;
2192 *resMember=nullptr;
2193 AUTO_TRACE_ADD("false");
2194 return false;
2195 }
2196 }
2197 else if (result.cd) *resContext=result.cd;
2198 else if (result.nd) *resContext=result.nd;
2199 else if (result.fd) *resContext=result.fd;
2200 else if (result.gd) *resContext=result.gd;
2201 else if (result.cnd) *resContext=result.cnd;
2202 else if (result.modd) *resContext=result.modd;
2203 else
2204 {
2205 *resContext=nullptr; *resMember=nullptr;
2206 AUTO_TRACE_ADD("false");
2207 return false;
2208 }
2209 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
2210 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
2211 AUTO_TRACE_ADD("true");
2212 return true;
2213 }
2214 else if (inSeeBlock && !nameStr.empty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
2215 { // group link
2216 *resContext=gd;
2217 AUTO_TRACE_ADD("true");
2218 return true;
2219 }
2220 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
2221 {
2222 *resContext=cnd;
2223 AUTO_TRACE_ADD("true");
2224 return true;
2225 }
2226 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
2227 {
2228 *resContext=modd;
2229 AUTO_TRACE_ADD("true");
2230 return true;
2231 }
2232 else if (tsName.find('.')!=DString::npos) // maybe a link to a file
2233 {
2234 bool ambig = false;
2235 const FileDef *fd=Doxygen::inputNameLinkedMap->findFileDef(tsName,ambig);
2236 if (fd && !ambig)
2237 {
2238 *resContext=fd;
2239 AUTO_TRACE_ADD("true");
2240 return true;
2241 }
2242 }
2243
2244 if (tryUnspecializedVersion)
2245 {
2246 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,false,nullptr,checkScope);
2247 AUTO_TRACE_ADD("{}",b);
2248 return b;
2249 }
2250 if (bracePos!=DString::npos) // Try without parameters as well, could be a constructor invocation
2251 {
2252 *resContext=getClass(fullName.left(bracePos));
2253 if (*resContext)
2254 {
2255 AUTO_TRACE_ADD("true");
2256 return true;
2257 }
2258 }
2259 //printf("resolveRef: %s not found!\n",qPrint(name));
2260
2261 AUTO_TRACE_ADD("false");
2262 return false;
2263}
virtual Definition * getOuterScope() const =0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:90
virtual bool isStrongEnumValue() const =0
virtual bool isEnumerate() const =0
static size_t findParameterList(const DString &name)
Returns the position in the string where a function parameter list begins, or DString::npos if one is...
Definition util.cpp:684
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:1866
static bool getScopeDefs(const DString &docScope, const DString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:1936
static bool isLowerCase(DString &s)
Definition util.cpp:1999

References ASSERT, AUTO_TRACE, AUTO_TRACE_ADD, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, Doxygen::conceptLinkedMap, GetDefInput::currentFile, DString::empty(), GetDefResult::fd, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), FileNameLinkedMap::findFileDef(), findParameterList(), GetDefInput::forceEmptyScope, GetDefResult::found, GetDefResult::gd, getClass(), getDefs(), Definition::getOuterScope(), getScopeDefs(), Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), MemberDef::isEnumerate(), isLowerCase(), MemberDef::isStrongEnumValue(), MemberDef::isTypedef(), DString::left(), leftScopeMatch(), DString::length(), mangleCSharpGenericName(), GetDefResult::md, DString::mid(), GetDefResult::modd, Definition::name(), GetDefResult::nd, DString::npos, removeRedundantWhiteSpace(), resolveRef(), DString::rfind(), DString::startsWith(), and substitute().

Referenced by DocParser::handleLinkedWord(), resolveLink(), and resolveRef().

◆ resolveTypeDef()

DString resolveTypeDef ( const Definition * d,
const DString & name,
const Definition ** typedefContext = nullptr )

Definition at line 232 of file util.cpp.

234{
235 AUTO_TRACE("context='{}' qualifiedName='{}'",context?context->name():"",qualifiedName);
236 DString result;
237 if (qualifiedName.empty())
238 {
239 AUTO_TRACE_EXIT("empty name");
240 return result;
241 }
242
243 const Definition *mContext=context;
244 if (typedefContext) *typedefContext=context;
245
246 // see if the qualified name has a scope part
247 if (qualifiedName.find('<')!=DString::npos)
248 {
249 AUTO_TRACE_EXIT("template");
250 return result;
251 }
252 size_t scopeIndex = qualifiedName.rfind("::");
253 DString resName=qualifiedName;
254 if (scopeIndex!=DString::npos) // strip scope part for the name
255 {
256 resName=qualifiedName.mid(scopeIndex+2);
257 if (resName.empty())
258 {
259 AUTO_TRACE_EXIT("invalid format");
260 return result;
261 }
262 }
263 const MemberDef *md=nullptr;
264 while (mContext && md==nullptr)
265 {
266 // step 1: get the right scope
267 const Definition *resScope=mContext;
268 if (scopeIndex!=DString::npos)
269 {
270 // split-off scope part
271 DString resScopeName = qualifiedName.left(scopeIndex);
272 //printf("resScopeName='%s'\n",qPrint(resScopeName));
273
274 // look-up scope in context
275 int is=0,ps=0,l=0;
276 while ((is=getScopeFragment(resScopeName,ps,&l))!=-1)
277 {
278 DString qualScopePart = resScopeName.mid(is,l);
279 DString tmp = resolveTypeDef(mContext,qualScopePart);
280 if (!tmp.empty()) qualScopePart=tmp;
281 resScope = resScope->findInnerCompound(qualScopePart);
282 //printf("qualScopePart='%s' resScope=%p\n",qPrint(qualScopePart),resScope);
283 if (resScope==nullptr) break;
284 ps=is+l;
285 }
286 }
287 AUTO_TRACE_ADD("resScope='{}' resName='{}'",resScope?resScope->name():"",resName);
288
289 // step 2: get the member
290 if (resScope) // no scope or scope found in the current context
291 {
292 //printf("scope found: %s, look for typedef %s\n",
293 // qPrint(resScope->qualifiedName()),qPrint(resName));
294 MemberNameLinkedMap *mnd=nullptr;
295 bool searchRelated=false;
296 bool mustBeRelated=false;
297 if (resScope->definitionType()==Definition::TypeClass)
298 {
300 }
301 else
302 {
304 searchRelated=true;
305 }
306 MemberName *mn=mnd->find(resName);
307 if (mn==0 && searchRelated)
308 {
310 mustBeRelated=true;
311 }
312 if (mn)
313 {
314 int minDist=-1;
315 for (const auto &tmd_p : *mn)
316 {
317 const MemberDef *tmd = tmd_p.get();
318 AUTO_TRACE_ADD("found candidate member '{}' isTypeDef={}' isRelated={} mustBeRelated={}",
319 tmd->name(),tmd->isTypedef(),tmd->isRelated(),mustBeRelated);
320 //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n",
321 // qPrint(tmd->name()),qPrint( resScope->name()),
322 // qPrint(tmd->getOuterScope()->name()), mContext);
323 if (tmd->isTypedef())
324 {
325 if (resScope==Doxygen::globalScope && tmd->isRelated() && mustBeRelated)
326 {
327 md = tmd;
328 }
329 else
330 {
331 SymbolResolver resolver;
332 int dist=resolver.isAccessibleFrom(resScope,tmd);
333 if (dist!=-1 && (md==nullptr || dist<minDist))
334 {
335 md = tmd;
336 minDist = dist;
337 }
338 }
339 }
340 }
341 }
342 }
343 mContext=mContext->getOuterScope();
344 }
345
346 AUTO_TRACE_ADD("md='{}'",md?md->name():"");
347 // step 3: get the member's type
348 if (md)
349 {
350 //printf(">>resolveTypeDef: Found typedef name '%s' in scope '%s' value='%s' args='%s'\n",
351 // qPrint(qualifiedName),qPrint(context->name()),qPrint(md->typeString()),qPrint(md->argsString())
352 // );
353 result=md->typeString();
354 DString args = md->argsString();
355 if (args.find(")(")!=DString::npos) // typedef of a function/member pointer
356 {
357 result+=args;
358 }
359 else if (args.find('[')!=DString::npos) // typedef of an array
360 {
361 result+=args;
362 }
363 if (typedefContext) *typedefContext=md->getOuterScope();
364 }
365 else
366 {
367 //printf(">>resolveTypeDef: Typedef '%s' not found in scope '%s'!\n",
368 // qPrint(qualifiedName),context ? qPrint(context->name()) : "<global>");
369 }
370 AUTO_TRACE_EXIT("result='{}'",result);
371 return result;
372}
virtual const Definition * findInnerCompound(const DString &name) const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:105
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:104
virtual DString argsString() const =0
virtual bool isRelated() const =0
virtual DString typeString() const =0
Ordered dictionary of MemberName objects.
Definition membername.h:61
int isAccessibleFrom(const Definition *scope, const Definition *item)
Checks if symbol item is accessible from within scope.
DString resolveTypeDef(const Definition *context, const DString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:232
int getScopeFragment(const DString &s, int p, int *l)
Definition util.cpp:3799

References MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, Definition::definitionType(), DString::empty(), DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Definition::findInnerCompound(), Doxygen::functionNameLinkedMap, Definition::getOuterScope(), getScopeFragment(), Doxygen::globalScope, SymbolResolver::isAccessibleFrom(), MemberDef::isRelated(), MemberDef::isTypedef(), DString::left(), Doxygen::memberNameLinkedMap, DString::mid(), Definition::name(), DString::npos, resolveTypeDef(), DString::rfind(), Definition::TypeClass, and MemberDef::typeString().

Referenced by findUsedClassesForClass(), getCanonicalTemplateSpec(), getCanonicalTypeForIdentifier(), isVarWithConstructor(), and resolveTypeDef().

◆ rightScopeMatch()

bool rightScopeMatch ( const DString & scope,
const DString & name )

Definition at line 729 of file util.cpp.

730{
731 size_t sl=scope.length();
732 size_t nl=name.length();
733 return (name==scope || // equal
734 (scope.right(nl)==name && // substring
735 sl>1+nl && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
736 )
737 );
738}

References DString::at(), DString::length(), and DString::right().

Referenced by addMemberFunction(), findScopeFromQualifiedName(), and isRecursiveBaseClass().

◆ selectBlocks()

DString selectBlocks ( const DString & s,
const SelectionBlockList & blockList,
const SelectionMarkerInfo & markerInfo )

remove disabled blocks and all block markers from s and return the result as a string

Definition at line 5017 of file util.cpp.

5018{
5019 if (s.empty()) return s;
5020
5021 // helper to find the end of a block
5022 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
5023 {
5024 char c = 0;
5025 while ((c=*p))
5026 {
5027 if (c==markerInfo.markerChar && dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
5028 {
5029 size_t len = markerInfo.endLen;
5030 bool negate = *(p+markerInfo.endLen)=='!';
5031 if (negate) len++;
5032 size_t blkNameLen = dstrlen(blk.name);
5033 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5034 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5035 {
5036 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5037 return p+len+blkNameLen+markerInfo.closeLen;
5038 }
5039 else // not the right marker id
5040 {
5041 p++;
5042 }
5043 }
5044 else // not and end marker
5045 {
5046 p++;
5047 }
5048 }
5049 return p;
5050 };
5051
5052 DString result;
5053 result.reserve(s.length());
5054 const char *p = s.data();
5055 char c = 0;
5056 while ((c=*p))
5057 {
5058 if (c==markerInfo.markerChar) // potential start of marker
5059 {
5060 if (dstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
5061 {
5062 bool found = false;
5063 size_t len = markerInfo.beginLen;
5064 bool negate = *(p+len)=='!';
5065 if (negate) len++;
5066 for (const auto &blk : blockList)
5067 {
5068 size_t blkNameLen = dstrlen(blk.name);
5069 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5070 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5071 {
5072 bool blockEnabled = blk.enabled!=negate;
5073 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5074 p+=len+blkNameLen+markerInfo.closeLen;
5075 if (!blockEnabled) // skip until the end of the block
5076 {
5077 //printf("skipping block\n");
5078 p=skipBlock(p,blk);
5079 }
5080 found=true;
5081 break;
5082 }
5083 }
5084 if (!found) // unknown marker id
5085 {
5086 result+=c;
5087 p++;
5088 }
5089 }
5090 else if (dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
5091 {
5092 bool found = false;
5093 size_t len = markerInfo.endLen;
5094 bool negate = *(p+len)=='!';
5095 if (negate) len++;
5096 for (const auto &blk : blockList)
5097 {
5098 size_t blkNameLen = dstrlen(blk.name);
5099 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5100 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5101 {
5102 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5103 p+=len+blkNameLen+markerInfo.closeLen;
5104 found=true;
5105 break;
5106 }
5107 }
5108 if (!found) // unknown marker id
5109 {
5110 result+=c;
5111 p++;
5112 }
5113 }
5114 else // not a start or end marker
5115 {
5116 result+=c;
5117 p++;
5118 }
5119 }
5120 else // not a marker character
5121 {
5122 result+=c;
5123 p++;
5124 }
5125 }
5126 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
5127 return result;
5128}
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:39

References SelectionMarkerInfo::beginLen, SelectionMarkerInfo::beginStr, SelectionMarkerInfo::closeLen, SelectionMarkerInfo::closeStr, DString::data(), dstrlen(), dstrncmp(), DString::empty(), SelectionMarkerInfo::endLen, SelectionMarkerInfo::endStr, DString::length(), SelectionMarkerInfo::markerChar, and DString::reserve().

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showDate()

DString showDate ( const DString & fmt)

Definition at line 2568 of file util.cpp.

2569{
2570 // get the current date and time
2571 std::tm dat{};
2572 int specFormat=0;
2573 DString specDate = "";
2574 DString err = dateTimeFromString(specDate,dat,specFormat);
2575
2576 // do the conversion
2577 int usedFormat=0;
2578 return formatDateTime(fmt,dat,usedFormat);
2579}
DString formatDateTime(const DString &format, const std::tm &dt, int &formatUsed)
Return a string representation for a given std::tm value that is formatted according to the pattern g...
Definition datetime.cpp:176
DString dateTimeFromString(const DString &spec, std::tm &dt, int &format)
Returns the filled in std::tm for a given string representing a date and/or time.
Definition datetime.cpp:135
Definition message.h:146

References dateTimeFromString(), err, and formatDateTime().

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ stackTrace()

void stackTrace ( )

Definition at line 4311 of file util.cpp.

4312{
4313#ifdef TRACINGSUPPORT
4314 void *backtraceFrames[128];
4315 int frameCount = backtrace(backtraceFrames, 128);
4316 const size_t cmdLen = 40960;
4317 static char cmd[cmdLen];
4318 char *p = cmd;
4319 p += snprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
4320 for (int x = 0; x < frameCount; x++)
4321 {
4322 p += snprintf(p,cmdLen,"%p ", backtraceFrames[x]);
4323 }
4324 fprintf(stderr,"========== STACKTRACE START ==============\n");
4325 if (FILE *fp = Portable::popen(cmd, "r"))
4326 {
4327 char resBuf[512];
4328 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
4329 {
4330 fwrite(resBuf, 1, len, stderr);
4331 }
4332 Portable::pclose(fp);
4333 }
4334 fprintf(stderr,"============ STACKTRACE END ==============\n");
4335 //fprintf(stderr,"%s\n", frameStrings[x]);
4336#endif
4337}

References Portable::pclose(), and Portable::popen().

◆ stripAnonymousNamespaceScope()

DString stripAnonymousNamespaceScope ( const DString & s)

Definition at line 167 of file util.cpp.

168{
169 int i=0,p=0,l=0;
170 DString newScope;
171 int sl = static_cast<int>(s.length());
172 while ((i=getScopeFragment(s,p,&l))!=-1)
173 {
174 //printf("Scope fragment %s\n",qPrint(s.mid(i,l)));
175 if (Doxygen::namespaceLinkedMap->find(s.left(i+l))!=nullptr)
176 {
177 if (s.at(i)!='@')
178 {
179 if (!newScope.empty()) newScope+="::";
180 newScope+=s.mid(i,l);
181 }
182 }
183 else if (i<sl)
184 {
185 if (!newScope.empty()) newScope+="::";
186 newScope+=s.right(sl-i);
187 goto done;
188 }
189 p=i+l;
190 }
191done:
192 //printf("stripAnonymousNamespaceScope('%s')='%s'\n",qPrint(s),qPrint(newScope));
193 return newScope;
194}

References DString::at(), DString::empty(), getScopeFragment(), DString::left(), DString::length(), DString::mid(), Doxygen::namespaceLinkedMap, and DString::right().

Referenced by addMemberFunction(), addPageToContext(), addVariable(), buildNamespaceList(), computeTemplateClassRelations(), extractClassName(), findGroupScope(), findUsingDeclImports(), findUsingDirectives(), and resolveClassNestingRelations().

◆ stripExtension()

◆ stripExtensionGeneral()

DString stripExtensionGeneral ( const DString & fName,
const DString & ext )

◆ stripFromIncludePath()

DString stripFromIncludePath ( const DString & path)

strip part of path if it matches one of the paths in the Config_getList(INCLUDE_PATH) list

Definition at line 227 of file util.cpp.

228{
229 return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
230}
static DString stripFromPath(const DString &p, StringVector l)
Definition util.cpp:196

References Config_getList, and stripFromPath().

Referenced by MemberDefImpl::_writeGroupInclude(), addIncludeFile(), FileNameLinkedMap::findFileDef(), and FileNameLinkedMap::showFileDefMatches().

◆ stripFromPath()

◆ stripIndentation()

DString stripIndentation ( const DString & s,
bool skipFirstLine = false )

Definition at line 4684 of file util.cpp.

4685{
4686 if (s.empty()) return s; // empty string -> we're done
4687
4688 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
4689 // compute minimum indentation over all lines
4690 const char *p=s.data();
4691 char c=0;
4692 int indent=0;
4693 int minIndent=1000000; // "infinite"
4694 bool searchIndent=true;
4695 int tabSize=Config_getInt(TAB_SIZE);
4696 bool skipFirst = skipFirstLine;
4697 while ((c=*p++))
4698 {
4699 if (c=='\t') { indent+=tabSize - (indent%tabSize); }
4700 else if (c=='\n') { indent=0; searchIndent=true; skipFirst=false; }
4701 else if (c==' ') { indent++; }
4702 else if (searchIndent && !skipFirst)
4703 {
4704 searchIndent=false;
4705 if (indent<minIndent) minIndent=indent;
4706 }
4707 }
4708
4709 // no indent to remove -> we're done
4710 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
4711
4712 // remove minimum indentation for each line
4713 TextStream result;
4714 p=s.data();
4715 indent=0;
4716 skipFirst=skipFirstLine;
4717 while ((c=*p++))
4718 {
4719 if (c=='\n') // start of new line
4720 {
4721 indent=0;
4722 result << c;
4723 skipFirst=false;
4724 }
4725 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
4726 {
4727 if (c=='\t')
4728 {
4729 int newIndent = indent+tabSize-(indent%tabSize);
4730 int i=newIndent;
4731 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
4732 {
4733 result << ' ';
4734 i--;
4735 }
4736 indent=newIndent;
4737 }
4738 else // space
4739 {
4740 indent++;
4741 }
4742 }
4743 else if (c=='\\' && literal_at(p,"ilinebr "))
4744 // we also need to remove the indentation after a \ilinebr command at the end of a line
4745 {
4746 result << "\\ilinebr ";
4747 p+=8;
4748 int skipAmount=0;
4749 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
4750 if (skipAmount==minIndent)
4751 {
4752 p+=skipAmount; // remove the indent
4753 }
4754 }
4755 else if (c=='@' && literal_at(p,"ilinebr"))
4756 {
4757 result << "\\ilinebr";
4758 p+=7;
4759 }
4760 else // copy anything until the end of the line
4761 {
4762 result << c;
4763 }
4764 }
4765
4766 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
4767
4768 return result.str();
4769}
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:232

References Config_getInt, DString::data(), DString::empty(), literal_at(), TextStream::str(), and substitute().

Referenced by handleCommentBlock(), handleCommentBlock(), handleCommentBlock(), handleParametersCommentBlocks(), DocPara::handleStartCode(), and MarkdownOutlineParser::parseInput().

◆ stripIndentationVerbatim()

void stripIndentationVerbatim ( DString & doc,
size_t indentationLevel,
bool skipFirstLine = true )

Definition at line 4773 of file util.cpp.

4774{
4775 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
4776 if (indentationLevel <= 0 || doc.empty()) return; // nothing to strip
4777
4778 // by stripping content the string will only become shorter so we write the results
4779 // back into the input string and then resize it at the end.
4780 char c = 0;
4781 const char *src = doc.data();
4782 char *dst = doc.rawData();
4783 bool insideIndent = !skipFirstLine; // skip the initial line from stripping
4784 size_t cnt = 0;
4785 if (!skipFirstLine) cnt = indentationLevel;
4786 while ((c=*src++))
4787 {
4788 // invariant: dst<=src
4789 switch(c)
4790 {
4791 case '\n':
4792 *dst++ = c;
4793 insideIndent = true;
4794 cnt = indentationLevel;
4795 break;
4796 case ' ':
4797 if (insideIndent)
4798 {
4799 if (cnt>0) // count down the spacing until the end of the indent
4800 {
4801 cnt--;
4802 }
4803 else // reached the end of the indent, start of the part of the line to keep
4804 {
4805 insideIndent = false;
4806 *dst++ = c;
4807 }
4808 }
4809 else // part after indent, copy to the output
4810 {
4811 *dst++ = c;
4812 }
4813 break;
4814 default:
4815 insideIndent = false;
4816 *dst++ = c;
4817 break;
4818 }
4819 }
4820 doc.resize(static_cast<uint32_t>(dst-doc.data()));
4821 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
4822}
void resize(size_t newlen)
Definition dstring.h:209
char * rawData()
Returns a writable pointer to the data.
Definition dstring.h:166

References DString::data(), DString::empty(), DString::rawData(), and DString::resize().

Referenced by MemberDefImpl::setInitializer().

◆ stripLeadingAndTrailingEmptyLines()

DString stripLeadingAndTrailingEmptyLines ( const DString & s,
int & docLine )

Special version of DString::stripWhiteSpace() that only strips completely blank lines.

Parameters
sthe string to be stripped
docLinethe line number corresponding to the start of the string. This will be adjusted based on the number of lines stripped from the start.
Returns
The stripped string.

Definition at line 3988 of file util.cpp.

3989{
3990 if (s.empty()) return DString();
3991 const char *p = s.data();
3992
3993 // search for leading empty lines
3994 int i=0,li=-1,l=static_cast<int>(s.length());
3995 char c = 0;
3996 while ((c=*p))
3997 {
3998 if (c==' ' || c=='\t' || c=='\r') { i++; p++; }
3999 else if (c=='\\' && literal_at(p,"\\ilinebr")) { i+=8; li=i; p+=8; }
4000 else if (c=='\n') { i++; li=i; docLine++; p++; }
4001 else break;
4002 }
4003
4004 // search for trailing empty lines
4005 int b=l-1,bi=-1;
4006 p=s.data()+b;
4007 while (b>=0)
4008 {
4009 c=*p;
4010 if (c==' ' || c=='\t' || c=='\r') { b--; p--; }
4011 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
4012 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
4013 else if (c=='\n') { bi=b; b--; p--; }
4014 else break;
4015 }
4016
4017 // return whole string if no leading or trailing lines where found
4018 if (li==-1 && bi==-1) return s;
4019
4020 // return substring
4021 if (bi==-1) bi=l;
4022 if (li==-1) li=0;
4023 if (bi<=li) return DString(); // only empty lines
4024 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
4025 return s.mid(li,bi-li);
4026}

References DString::data(), DString::empty(), DString::length(), literal_at(), and DString::mid().

Referenced by DefinitionImpl::_setBriefDescription(), DocGroup::addDocs(), VHDLOutlineParser::checkInlineCode(), DocPara::handleCommand(), CommentScanner::parseCommentBlock(), and toDefinition().

◆ stripPath()

DString stripPath ( const DString & s)

Definition at line 3961 of file util.cpp.

3962{
3963 DString result=s;
3964 if (size_t i=result.rfind('/'); i!=DString::npos)
3965 {
3966 result=result.mid(i+1);
3967 }
3968 if (size_t i=result.rfind('\\'); i!=DString::npos)
3969 {
3970 result=result.mid(i+1);
3971 }
3972 return result;
3973}

References DString::mid(), DString::npos, and DString::rfind().

Referenced by LatexGenerator::addLabel(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), RTFGenerator::endDoxyAnchor(), LatexGenerator::endIndexItem(), LatexGenerator::endIndexValue(), LatexGenerator::endTitleHead(), makeBaseName(), objectLinkToString(), objectLinkToString(), objectLinkToString(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), DotFilePatcher::run(), SearchIndexExternal::setCurrentDoc(), DocbookGenerator::startDoxyAnchor(), LatexGenerator::startDoxyAnchor(), DocbookGenerator::startFile(), LatexGenerator::startFile(), RTFGenerator::startFile(), DocbookDocVisitor::startLink(), LatexDocVisitor::startLink(), RTFDocVisitor::startLink(), DocbookDocVisitor::startMermaidFile(), LatexDocVisitor::startMermaidFile(), LatexDocVisitor::startPlantUmlFile(), DocbookGenerator::startSection(), LatexGenerator::startSection(), LatexGenerator::startTextLink(), RTFGenerator::startTextLink(), substituteHtmlKeywords(), substituteLatexKeywords(), LatexGenerator::writeAnchor(), RTFGenerator::writeAnchor(), LatexCodeGenerator::writeCodeLink(), RTFCodeGenerator::writeCodeLink(), DocbookCodeGenerator::writeCodeLinkLine(), MemberList::writeDeclarations(), DocbookDocVisitor::writeDiaFile(), writeDocbookLink(), LatexCodeGenerator::writeLineNumber(), RTFCodeGenerator::writeLineNumber(), DocbookDocVisitor::writeMermaidFile(), LatexDocVisitor::writeMermaidFile(), DocbookDocVisitor::writePlantUMLFile(), LatexDocVisitor::writePlantUMLFile(), RTFGenerator::writeRTFReference(), and RTFGenerator::writeStartAnnoItem().

◆ stripScope()

DString stripScope ( const DString & name)

Strips the scope from a name. Examples: A::B will return A and A<T>::B<N::C<D> > will return A<T>.

Definition at line 3110 of file util.cpp.

3111{
3112 DString result = name;
3113 int l = static_cast<int>(result.length());
3114 int p = 0;
3115 bool done = false;
3116 bool skipBracket=false; // if brackets do not match properly, ignore them altogether
3117 int count=0;
3118 int round=0;
3119
3120 do
3121 {
3122 p=l-1; // start at the end of the string
3123 while (p>=0 && count>=0)
3124 {
3125 char c=result.at(p);
3126 switch (c)
3127 {
3128 case ':':
3129 // only exit in the case of ::
3130 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
3131 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
3132 {
3133 return result.right(l-p-1);
3134 }
3135 p--;
3136 break;
3137 case '>':
3138 if (skipBracket) // we don't care about brackets
3139 {
3140 p--;
3141 }
3142 else // count open/close brackets
3143 {
3144 if (p>0 && result.at(p-1)=='>') // skip >> operator
3145 {
3146 p-=2;
3147 break;
3148 }
3149 count=1;
3150 //printf("pos < = %d\n",p);
3151 p--;
3152 bool foundMatch=false;
3153 while (p>=0 && !foundMatch)
3154 {
3155 c=result.at(p--);
3156 switch (c)
3157 {
3158 case ')':
3159 round++;
3160 break;
3161 case '(':
3162 round--;
3163 break;
3164 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
3165 if (round==0) count++;
3166 break;
3167 case '<':
3168 if (round==0)
3169 {
3170 if (p>0)
3171 {
3172 if (result.at(p-1) == '<') // skip << operator
3173 {
3174 p--;
3175 break;
3176 }
3177 }
3178 count--;
3179 foundMatch = count==0;
3180 }
3181 break;
3182 default:
3183 //printf("c=%c count=%d\n",c,count);
3184 break;
3185 }
3186 }
3187 }
3188 //printf("pos > = %d\n",p+1);
3189 break;
3190 default:
3191 p--;
3192 }
3193 }
3194 done = count==0 || skipBracket; // reparse if brackets do not match
3195 skipBracket=true;
3196 }
3197 while (!done); // if < > unbalanced repeat ignoring them
3198 //printf("stripScope(%s)=%s\n",name,name);
3199 return name;
3200}

References DString::at(), DString::length(), and DString::right().

Referenced by DotClassGraph::addClass(), DocRef::DocRef(), generateJSLink(), getCanonicalTypeForIdentifier(), DefinitionImpl::Private::init(), DiagramItem::label(), NamespaceDefImpl::writeBriefDescription(), and ClassDefImpl::writeIncludeFilesForSlice().

◆ stripTemplateSpecifiersFromScope()

DString stripTemplateSpecifiersFromScope ( const DString & fullName,
bool parentOnly,
DString * pLastScopeStripped,
DString scopeName,
bool allowArtificial )

Strips template specifiers from scope fullName, except those that make up specialized classes. The switch parentOnly determines whether or not a template "at the end" of a scope should be considered, e.g. with parentOnly is true, A<T>::B<S> will try to strip <T> and not <S>, while parentOnly is false will strip both unless A<T> or B<S> are specialized template classes.

Definition at line 3687 of file util.cpp.

3692{
3693 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
3694 size_t i=fullName.find('<');
3695 if (i==DString::npos) return fullName;
3696 DString result;
3697 size_t p=0;
3698 size_t l=fullName.length();
3699 while (i!=DString::npos)
3700 {
3701 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
3702 size_t e=i+1;
3703 int count=1;
3704 int round=0;
3705 while (e<l && count>0)
3706 {
3707 char c=fullName.at(e++);
3708 switch (c)
3709 {
3710 case '(': round++; break;
3711 case ')': if (round>0) round--; break;
3712 case '<': if (round==0) count++; break;
3713 case '>': if (round==0) count--; break;
3714 default:
3715 break;
3716 }
3717 }
3718 size_t si = fullName.find("::",e);
3719
3720 if (parentOnly && si==DString::npos) break;
3721 // we only do the parent scope, so we stop here if needed
3722
3723 result+=fullName.mid(p,i-p);
3724 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
3725 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
3726 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
3727 {
3728 result+=fullName.mid(i,e-i);
3729 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
3730 }
3731 else if (pLastScopeStripped)
3732 {
3733 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
3734 *pLastScopeStripped=fullName.mid(i,e-i);
3735 }
3736 p=e;
3737 i=fullName.find('<',p);
3738 }
3739 result+=fullName.right(l-p);
3740 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
3741 //printf("end result=%s\n",qPrint(result));
3742 return result;
3743}
virtual bool isArtificial() const =0
DString mergeScopes(const DString &leftScope, const DString &rightScope)
Definition util.cpp:3754

References DString::at(), DString::find(), getClass(), Definition::isArtificial(), DString::length(), mergeScopes(), DString::mid(), DString::npos, and DString::right().

Referenced by addClassToContext(), addMemberFunction(), addVariable(), buildFunctionList(), computeTemplateClassRelations(), extractClassName(), findMember(), findScopeFromQualifiedName(), findUsingDeclImports(), getCanonicalTypeForIdentifier(), SymbolResolver::Private::getResolvedSymbolRec(), SymbolResolver::Private::getResolvedTypeRec(), SymbolResolver::Private::newResolveTypedef(), and resolveLink().

◆ substituteKeywords()

DString substituteKeywords ( const DString & file,
const DString & s,
const KeywordSubstitutionList & keywords )

Definition at line 2495 of file util.cpp.

2496{
2497 std::string substRes;
2498 int line = 1;
2499 const char *p = s.data();
2500 if (p)
2501 {
2502 // reserve some room for expansion
2503 substRes.reserve(s.length()+1024);
2504 char c = 0;
2505 while ((c=*p))
2506 {
2507 bool found = false;
2508 if (c=='$')
2509 {
2510 for (const auto &kw : keywords)
2511 {
2512 size_t keyLen = dstrlen(kw.keyword);
2513 if (dstrncmp(p,kw.keyword,keyLen)==0)
2514 {
2515 const char *startArg = p+keyLen;
2516 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2517 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
2518 if (expectParam && *startArg=='(') // $key(value)
2519 {
2520 size_t j=1;
2521 const char *endArg = nullptr;
2522 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
2523 if (c==')') endArg=startArg+j;
2524 if (endArg)
2525 {
2526 DString value = DString(startArg+1).left(endArg-startArg-1);
2527 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2528 substRes+=getValue(value).str();
2529 p=endArg+1;
2530 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
2531 }
2532 else
2533 {
2534 //printf("missing argument\n");
2535 warn(file,line,"Missing argument for '{}'",kw.keyword);
2536 p+=keyLen;
2537 }
2538 }
2539 else if (!expectParam) // $key
2540 {
2541 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
2542 substRes+=getValue().str();
2543 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
2544 p+=keyLen;
2545 }
2546 else
2547 {
2548 //printf("%s %d Expected arguments, none specified '%s'\n",qPrint(file), line, qPrint(kw.keyword));
2549 warn(file,line,"Expected arguments for '{}' but none were specified",kw.keyword);
2550 p+=keyLen;
2551 }
2552 found = true;
2553 break;
2554 }
2555 }
2556 }
2557 if (!found) // copy
2558 {
2559 if (c=='\n') line++;
2560 substRes+=c;
2561 p++;
2562 }
2563 }
2564 }
2565 return substRes;
2566}

References DString::data(), dstrlen(), dstrncmp(), DString::left(), DString::length(), and warn.

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ substituteTemplateArgumentsInString()

DString substituteTemplateArgumentsInString ( const DString & name,
const ArgumentList & formalArgs,
const ArgumentList * actualArgs )

Substitutes any occurrence of a formal argument from argument list formalArgs in name by the corresponding actual argument in argument list actualArgs. The result after substitution is returned as a string. The argument name is used to prevent recursive substitution.

Definition at line 3525 of file util.cpp.

3529{
3530 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : DString());
3531 if (formalArgs.empty()) return nm;
3532 DString result;
3533
3534 static const reg::Ex re(R"(\a\w*)");
3535 std::string name = nm.str();
3536 reg::Iterator it(name,re);
3538 size_t p=0;
3539
3540 for (; it!=end ; ++it)
3541 {
3542 const auto &match = *it;
3543 size_t i = match.position();
3544 size_t l = match.length();
3545 if (i>p) result += name.substr(p,i-p);
3546 DString n(match.str());
3548 if (actualArgs)
3549 {
3550 actIt = actualArgs->begin();
3551 }
3552 //printf(": name=%s\n",qPrint(name));
3553
3554 // if n is a template argument, then we substitute it
3555 // for its template instance argument.
3556 bool found=false;
3557 for (auto formIt = formalArgs.begin();
3558 formIt!=formalArgs.end() && !found;
3559 ++formIt
3560 )
3561 {
3562 Argument formArg = *formIt;
3563 Argument actArg;
3564 if (actualArgs && actIt!=actualArgs->end())
3565 {
3566 actArg = *actIt;
3567 }
3568 if (formArg.type.startsWith("class ") && formArg.name.empty())
3569 {
3570 formArg.name = formArg.type.mid(6);
3571 formArg.type = "class";
3572 }
3573 else if (formArg.type.startsWith("typename ") && formArg.name.empty())
3574 {
3575 formArg.name = formArg.type.mid(9);
3576 formArg.type = "typename";
3577 }
3578 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
3579 {
3580 formArg.name += "...";
3581 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
3582 }
3583 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
3584 {
3585 formArg.name += "...";
3586 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
3587 }
3588 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
3589 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
3590 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
3591 {
3592 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.empty()) // base class is a template argument
3593 {
3594 static constexpr auto hasRecursion = [](const DString &prefix,const DString &nameArg,const DString &subst) -> bool
3595 {
3596 size_t ii=0;
3597 size_t pp=0;
3598
3599 ii = subst.find('<');
3600 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
3601 if (ii!=DString::npos && prefix.length()>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
3602 {
3603 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
3604 }
3605
3606 while ((ii=subst.find(nameArg,pp))!=DString::npos)
3607 {
3608 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
3609 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
3610 if (beforeNonWord && afterNonWord)
3611 {
3612 return true; // if nameArg=='A' then subst=='A::Z' or 'S<A>' or 'Z::A' should return true, but 'AA::ZZ' or 'BAH' should not match
3613 }
3614 pp=ii+nameArg.length();
3615 }
3616 return false;
3617 };
3618 // replace formal argument with the actual argument of the instance
3619 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
3620 if (!hasRecursion(result,n,actArg.type))
3621 // the scope guard is to prevent recursive lockup for
3622 // template<class A> class C : public<A::T>,
3623 // where A::T would become A::T::T here,
3624 // since n==A and actArg->type==A::T
3625 // see bug595833 for an example
3626 //
3627 // Also prevent recursive substitution if n is part of actArg.type, i.e.
3628 // n='A' in argType='S< A >' would produce 'S< S< A > >'
3629 {
3630 if (actArg.name.empty())
3631 {
3632 result += actArg.type;
3633 }
3634 else
3635 // for case where the actual arg is something like "unsigned int"
3636 // the "int" part is in actArg->name.
3637 {
3638 result += actArg.type+" "+actArg.name;
3639 }
3640 found=true;
3641 }
3642 }
3643 else if (formArg.name==n &&
3644 (actualArgs==nullptr || actIt==actualArgs->end()) &&
3645 !formArg.defval.empty() &&
3646 formArg.defval!=nm /* to prevent recursion */
3647 )
3648 {
3649 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
3650 found=true;
3651 }
3652 }
3653 else if (formArg.name==n &&
3654 (actualArgs==nullptr || actIt==actualArgs->end()) &&
3655 !formArg.defval.empty() &&
3656 formArg.defval!=nm /* to prevent recursion */
3657 )
3658 {
3659 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
3660 found=true;
3661 }
3662 if (actualArgs && actIt!=actualArgs->end())
3663 {
3664 actIt++;
3665 }
3666 }
3667 if (!found)
3668 {
3669 result += n;
3670 }
3671 p=i+l;
3672 }
3673 result+=name.substr(p);
3674 result=result.simplifyWhiteSpace();
3675 AUTO_TRACE_EXIT("result={}",result);
3676 return result.stripWhiteSpace();
3677}
typename Vec::const_iterator const_iterator
Definition arguments.h:70
DString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple internal white...
Definition dstring.cpp:127
DString substituteTemplateArgumentsInString(const DString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:3525

References argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, ArgumentList::begin(), Argument::defval, ArgumentList::empty(), DString::empty(), ArgumentList::end(), end(), isId(), DString::left(), DString::mid(), Argument::name, DString::npos, prefix, DString::simplifyWhiteSpace(), DString::startsWith(), DString::str(), DString::stripWhiteSpace(), substituteTemplateArgumentsInString(), DString::substr(), and Argument::type.

Referenced by computeTemplateClassRelations(), MemberDefImpl::createTemplateInstanceMember(), findBaseClassesForClass(), findUsedClassesForClass(), SymbolResolver::Private::getResolvedSymbol(), SymbolResolver::Private::newResolveTypedef(), and substituteTemplateArgumentsInString().

◆ tempArgListToString()

DString tempArgListToString ( const ArgumentList & al,
SrcLangExt lang,
bool includeDefaults = true )

Returns a string representation of the template parameter list al. The lang parameter is used to determine the correct syntax for the template parameters. If includeDefaults is true then default values are included in the string representation.

Definition at line 903 of file util.cpp.

904{
905 DString result;
906 if (al.empty()) return result;
907 result="<";
908 bool first=true;
909 for (const auto &a : al)
910 {
911 if (a.defval.empty() || includeDefault)
912 {
913 if (!first) result+=", ";
914 if (!a.name.empty()) // add template argument name
915 {
916 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
917 {
918 result+=a.type+" ";
919 }
920 result+=a.name;
921 }
922 else // extract name from type
923 {
924 int i = static_cast<int>(a.type.length())-1;
925 while (i>=0 && isId(a.type.at(i))) i--;
926 if (i>0)
927 {
928 result+=a.type.right(a.type.length()-i-1);
929 if (a.type.find("...")!=DString::npos)
930 {
931 result+="...";
932 }
933 }
934 else // nothing found -> take whole name
935 {
936 result+=a.type;
937 }
938 }
939 if (!a.typeConstraint.empty() && lang==SrcLangExt::Java)
940 {
941 result+=" extends "; // TODO: now Java specific, C# has where...
942 result+=a.typeConstraint;
943 }
944 first=false;
945 }
946 }
947 result+=">";
948 return removeRedundantWhiteSpace(result);
949}

References ArgumentList::empty(), isId(), DString::npos, removeRedundantWhiteSpace(), and DString::right().

Referenced by addMemberFunction(), ClassDefImpl::className(), findTemplateInstanceRelation(), makeQualifiedNameWithTemplateParameters(), searchTemplateSpecs(), and writeDefArgumentList().

◆ unescapeCharsInString()

DString unescapeCharsInString ( const DString & s)

Definition at line 2776 of file util.cpp.

2777{
2778 if (s.empty()) return s;
2779 bool caseSenseNames = useCaseSenseNames();
2780 DString result;
2781 result.reserve(s.length());
2782 const char *p = s.data();
2783 if (p)
2784 {
2785 char c = 0;
2786 while ((c=*p++))
2787 {
2788 if (c=='_') // 2 or 3 character escape
2789 {
2790 switch (*p)
2791 {
2792 case '_': result+=c; p++; break; // __ -> '_'
2793 case '1': result+=':'; p++; break; // _1 -> ':'
2794 case '2': result+='/'; p++; break; // _2 -> '/'
2795 case '3': result+='<'; p++; break; // _3 -> '<'
2796 case '4': result+='>'; p++; break; // _4 -> '>'
2797 case '5': result+='*'; p++; break; // _5 -> '*'
2798 case '6': result+='&'; p++; break; // _6 -> '&'
2799 case '7': result+='|'; p++; break; // _7 -> '|'
2800 case '8': result+='.'; p++; break; // _8 -> '.'
2801 case '9': result+='!'; p++; break; // _9 -> '!'
2802 case '0': // 3 character escape
2803 switch (*(p+1))
2804 {
2805 case '0': result+=','; p+=2; break; // _00 -> ','
2806 case '1': result+=' '; p+=2; break; // _01 -> ' '
2807 case '2': result+='{'; p+=2; break; // _02 -> '{'
2808 case '3': result+='}'; p+=2; break; // _03 -> '}'
2809 case '4': result+='?'; p+=2; break; // _04 -> '?'
2810 case '5': result+='^'; p+=2; break; // _05 -> '^'
2811 case '6': result+='%'; p+=2; break; // _06 -> '%'
2812 case '7': result+='('; p+=2; break; // _07 -> '('
2813 case '8': result+=')'; p+=2; break; // _08 -> ')'
2814 case '9': result+='+'; p+=2; break; // _09 -> '+'
2815 case 'a': result+='='; p+=2; break; // _0a -> '='
2816 case 'b': result+='$'; p+=2; break; // _0b -> '$'
2817 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
2818 case 'd': result+='@'; p+=2; break; // _0d -> '@'
2819 case 'e': result+=']'; p+=2; break; // _0e -> ']'
2820 case 'f': result+='['; p+=2; break; // _0f -> '['
2821 case 'g': result+='#'; p+=2; break; // _0g -> '#'
2822 case 'h': result+='"'; p+=2; break; // _0h -> '"'
2823 case 'i': result+='~'; p+=2; break; // _0i -> '~'
2824 case 'j': result+='\''; p+=2; break;// _0j -> '\'
2825 case 'k': result+=';'; p+=2; break; // _0k -> ';'
2826 case 'l': result+='`'; p+=2; break; // _0l -> '`'
2827 default: // unknown escape, just pass underscore character as-is
2828 result+=c;
2829 break;
2830 }
2831 break;
2832 default:
2833 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
2834 {
2835 result+=static_cast<char>(toupper(*p));
2836 p++;
2837 }
2838 else // unknown escape, pass underscore character as-is
2839 {
2840 result+=c;
2841 }
2842 break;
2843 }
2844 }
2845 else // normal character; pass as is
2846 {
2847 result+=c;
2848 }
2849 }
2850 }
2851 return result;
2852}

References DString::data(), DString::empty(), DString::length(), DString::reserve(), and useCaseSenseNames().

◆ updateLanguageMapping()

bool updateLanguageMapping ( const DString & extension,
const DString & parser )

Definition at line 4064 of file util.cpp.

4065{
4066 DString langName = language.lower();
4067 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
4068 [&langName](const auto &info) { return info.langName==langName; });
4069 if (it1 == g_lang2extMap.end()) return false;
4070
4071 // found the language
4072 SrcLangExt parserId = it1->parserId;
4073 DString extName = extension.lower();
4074 if (extName.empty()) return false;
4075 if (extName.at(0)!='.') extName.prepend(".");
4076 auto it2 = g_extLookup.find(extName.str());
4077 if (it2!=g_extLookup.end())
4078 {
4079 g_extLookup.erase(it2); // language was already register for this ext
4080 }
4081 //printf("registering extension %s\n",qPrint(extName));
4082 g_extLookup.emplace(extName.str(),parserId);
4083 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
4084 {
4085 err("Failed to assign extension {} to parser {} for language {}\n",
4086 extName.data(),it1->parserName,language);
4087 }
4088 else
4089 {
4090 //msg("Registered extension {} to language parser {}...\n",
4091 // extName,language);
4092 }
4093 return true;
4094}
static ParserManager * parserManager
Definition doxygen.h:122
SrcLangExt
Definition types.h:207

References DString::at(), DString::data(), DString::empty(), err, g_extLookup, g_lang2extMap, DString::lower(), Doxygen::parserManager, DString::prepend(), and DString::str().

Referenced by addCodeOnlyMappings(), adjustConfiguration(), and initDefaultExtensionMapping().

◆ useCaseSenseNames()

bool useCaseSenseNames ( )

Returns true if the names of the symbols can be case sensitive.

Definition at line 2680 of file util.cpp.

2681{
2682 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
2683
2684 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
2685 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
2687}
#define Config_getEnum(name)
Definition config.h:35
bool fileSystemIsCaseSensitive()
Definition portable.cpp:486

References Config_getEnum, and Portable::fileSystemIsCaseSensitive().

Referenced by checkAndOpenFile(), escapeCharsInString(), getEncoding(), readDir(), FileNameFn::searchKey(), and unescapeCharsInString().

◆ writeExamples()

void writeExamples ( OutputList & ol,
const ExampleList & el )

Definition at line 804 of file util.cpp.

805{
806 auto replaceFunc = [&list,&ol](size_t entryIndex)
807 {
808 const auto &e = list[entryIndex];
813 // link for Html / man
814 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
815 ol.writeObjectLink(DString(),e.file,e.anchor,e.name);
817
821 // link for Latex / pdf with anchor because the sources
822 // are not hyperlinked (not possible with a verbatim environment).
823 ol.writeObjectLink(DString(),e.file,DString(),e.name);
825 };
826
827 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
828
829 ol.writeString(".");
830}
void disable(OutputType o)
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:435
void writeString(const DString &text)
Definition outputlist.h:407
void pushGeneratorState()
void popGeneratorState()
virtual DString trWriteList(int numEntries)=0
Translator * theTranslator
Definition language.cpp:76
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
Definition util.cpp:753

References OutputList::disable(), Docbook, Html, Latex, Man, OutputList::popGeneratorState(), OutputList::pushGeneratorState(), RTF, DString::str(), theTranslator, Translator::trWriteList(), writeMarkerList(), OutputList::writeObjectLink(), and OutputList::writeString().

Referenced by MemberDefImpl::_writeExamples(), and ClassDefImpl::writeDetailedDocumentationBody().

◆ writeInlineGraph()

DString writeInlineGraph ( const DString & baseName,
const DString & extension,
const DString & content,
bool & exists )

Thread-safe function to write a string representing an inline graph to a file. The contents will be used to create a hash that will be used to make the name unique.

Parameters
[in]baseNamethe base name of the file to write including path.
[in]extensionthe file extension to use.
[in]contentthe data to write to the file
[out]existsis set to true if the file was already written before.
Returns
the name of the file written or an empty string in case of an error.

Definition at line 5374 of file util.cpp.

5375{
5376 DString fileName = baseName + md5str(content.view()) + extension;
5377 { // ==== start atomic section
5378 std::lock_guard lock(writeFileContents_lock);
5379 auto it=writeFileContents_set.find(fileName.str());
5380 exists = it!=writeFileContents_set.end();
5381 if (!exists)
5382 {
5383 writeFileContents_set.insert(fileName.str());
5384 if (auto file = Portable::openOutputStream(fileName); file.is_open())
5385 {
5386 file.write( content.data(), content.length() );
5387 file.close();
5388 }
5389 else
5390 {
5391 err("Could not open file {} for writing\n",fileName);
5392 return DString();
5393 }
5394 }
5395 } // ==== end atomic section
5396 return fileName;
5397}
static std::mutex writeFileContents_lock
Definition util.cpp:5371

References DString::data(), err, DString::length(), md5str(), Portable::openOutputStream(), DString::str(), DString::view(), writeFileContents_lock, and writeFileContents_set.

Referenced by DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), and RTFDocVisitor::operator()().

◆ writeMarkerList() [1/2]

DString writeMarkerList ( const std::string & markerText,
size_t numMarkers,
std::function< DString(size_t)> replaceFunc )

Definition at line 776 of file util.cpp.

778{
779 DString result;
780 static const reg::Ex marker(R"(@(\d+))");
781 reg::Iterator it(markerText,marker);
783 size_t index=0;
784 for ( ; it!=end ; ++it)
785 {
786 const auto &match = *it;
787 size_t newIndex = match.position();
788 size_t matchLen = match.length();
789 result += markerText.substr(index,newIndex-index);
790 unsigned long entryIndex = std::stoul(match[1].str());
791 if (entryIndex<static_cast<unsigned long>(numMarkers))
792 {
793 result+=replaceFunc(entryIndex);
794 }
795 index=newIndex+matchLen;
796 }
797 if (index<markerText.size())
798 {
799 result += markerText.substr(index);
800 }
801 return result;
802}

References end(), and DString::substr().

◆ writeMarkerList() [2/2]

void writeMarkerList ( OutputList & ol,
const std::string & markerText,
size_t numMarkers,
std::function< void(size_t)> replaceFunc )

Definition at line 753 of file util.cpp.

755{
756 static const reg::Ex marker(R"(@(\d+))");
757 reg::Iterator it(markerText,marker);
759 size_t index=0;
760 for ( ; it!=end ; ++it)
761 {
762 const auto &match = *it;
763 size_t newIndex = match.position();
764 size_t matchLen = match.length();
765 ol.parseText(markerText.substr(index,newIndex-index));
766 unsigned long entryIndex = std::stoul(match[1].str());
767 if (entryIndex<static_cast<unsigned long>(numMarkers))
768 {
769 replaceFunc(entryIndex);
770 }
771 index=newIndex+matchLen;
772 }
773 ol.parseText(markerText.substr(index));
774}
void parseText(const DString &textStr)

References end(), and OutputList::parseText().

Referenced by MemberDefImpl::_writeReimplementedBy(), DefinitionImpl::_writeSourceRefList(), RequirementManager::generatePage(), writeExamples(), ClassDefImpl::writeInheritanceGraph(), and DefinitionImpl::writeRequirementRefs().

◆ writeTypeConstraints()

void writeTypeConstraints ( OutputList & ol,
const Definition * d,
const ArgumentList & al )

Definition at line 4284 of file util.cpp.

4285{
4286 if (al.empty()) return;
4288 for (const Argument &a : al)
4289 {
4291 ol.parseText(a.name);
4292 ol.endConstraintParam();
4294 linkifyText(TextGeneratorOLImpl(ol),a.type,LinkifyTextOptions().setScope(d));
4295 ol.endConstraintType();
4297 ol.generateDoc(d->docFile(),
4298 d->docLine(),
4299 d,
4300 nullptr,
4301 a.docs,
4302 DocOptions()
4303 .setIndexWords(true));
4304 ol.endConstraintDocs();
4305 }
4306 ol.endConstraintList();
4307}
virtual int docLine() const =0
virtual DString docFile() const =0
void endConstraintType()
Definition outputlist.h:710
void endConstraintList()
Definition outputlist.h:716
void startConstraintList(const DString &header)
Definition outputlist.h:702
void startConstraintParam()
Definition outputlist.h:704
void startConstraintDocs()
Definition outputlist.h:712
void startConstraintType()
Definition outputlist.h:708
void endConstraintDocs()
Definition outputlist.h:714
void endConstraintParam()
Definition outputlist.h:706
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition outputlist.h:786
virtual DString trTypeConstraints()=0
void linkifyText(const TextGeneratorIntf &out, const DString &text, const LinkifyTextOptions &options)
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24

References Definition::docFile(), Definition::docLine(), ArgumentList::empty(), OutputList::endConstraintDocs(), OutputList::endConstraintList(), OutputList::endConstraintParam(), OutputList::endConstraintType(), OutputList::generateDoc(), linkifyText(), OutputList::parseText(), OutputList::startConstraintDocs(), OutputList::startConstraintList(), OutputList::startConstraintParam(), OutputList::startConstraintType(), theTranslator, and Translator::trTypeConstraints().

Referenced by MemberDefImpl::_writeTypeConstraints(), and ClassDefImpl::writeDetailedDocumentationBody().