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())
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 265 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 213 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 4162 of file util.cpp.

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

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 3931 of file util.cpp.

3932{
3933 if (fName.empty()) return;
3934 size_t i_fs = fName.rfind('/');
3935 size_t i_bs = fName.rfind('\\');
3936 size_t p = i_fs!=DString::npos && i_bs!=DString::npos ? std::max(i_fs, i_bs) :
3937 i_fs!=DString::npos ? i_fs : i_bs!=DString::npos ? i_bs : 0;
3938 size_t i = fName.find('.',p); // search for . after path part
3939 if (i==DString::npos)
3940 {
3942 }
3943}
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 5129 of file util.cpp.

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

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 3926 of file util.cpp.

3927{
3928 return fName.right(ext.length())==ext;
3929}
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 4271 of file util.cpp.

4272{
4273 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
4274
4275 if (bestMatch && bestMatch->isTypedef())
4276 return true; // closest matching symbol is a typedef
4277 else
4278 return false;
4279}
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:4219

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

Referenced by isVarWithConstructor().

◆ cleanupInlineGraphs()

void cleanupInlineGraphs ( )

Deletes all graph files written with writeInlineGraph()

Definition at line 5398 of file util.cpp.

5399{
5400 if (Config_getBool(DOT_CLEANUP))
5401 {
5402 for (const auto& fileName: writeFileContents_set)
5403 {
5404 Dir().remove(qPrint(fileName));
5405 }
5406 }
5407}
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:5371

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

Referenced by generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 2996 of file util.cpp.

2997{
2998 if (Config_getBool(CREATE_SUBDIRS))
2999 {
3000 // remove empty subdirectories
3001 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3002 for (int l1=0;l1<16;l1++)
3003 {
3004 DString subdir;
3005 subdir.sprintf("d%x",l1);
3006 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3007 {
3008 DString subsubdir;
3009 subsubdir.sprintf("d%x/d%02x",l1,l2);
3010 if (d.exists(subsubdir.str()) && d.empty(subsubdir.str()))
3011 {
3012 d.rmdir(subsubdir.str());
3013 }
3014 }
3015 if (d.exists(subdir.str()) && d.empty(subdir.str()))
3016 {
3017 d.rmdir(subdir.str());
3018 }
3019 }
3020 }
3021}
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 5293 of file util.cpp.

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

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 2863 of file util.cpp.

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

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 4904 of file util.cpp.

4910{
4911 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4912
4913 // default representing 1-1 mapping
4914 *outListType1=inListType;
4915 *outListType2=MemberListType::Invalid();
4916
4917 if (inProt==Protection::Public)
4918 {
4919 if (inListType.isPrivate())
4920 {
4921 *outListType1=MemberListType::Invalid();
4922 }
4923 }
4924 else if (inProt==Protection::Protected)
4925 {
4926 if (inListType.isPrivate() || inListType.isPublic())
4927 {
4928 *outListType1=MemberListType::Invalid();
4929 }
4930 else if (inListType.isProtected())
4931 {
4932 *outListType2=inListType.toPublic();
4933 }
4934 }
4935 else if (inProt==Protection::Private)
4936 {
4937 if (inListType.isPublic() || inListType.isProtected())
4938 {
4939 *outListType1=MemberListType::Invalid();
4940 }
4941 else if (inListType.isPrivate())
4942 {
4943 if (extractPrivate)
4944 {
4945 *outListType1=inListType.toPublic();
4946 *outListType2=inListType.toProtected();
4947 }
4948 else
4949 {
4950 *outListType1=MemberListType::Invalid();
4951 }
4952 }
4953 }
4954
4955 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
4956 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
4957}
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 3291 of file util.cpp.

3292{
3293 if (s.empty()) return s;
3294 DString result;
3295 result.reserve(s.length()+32);
3296 const char *p=s.data();
3297 char c = 0;
3298 while ((c=*p++))
3299 {
3300 switch (c)
3301 {
3302 case '<': result+="&lt;"; break;
3303 case '>': result+="&gt;"; break;
3304 case '&': if (keepEntities)
3305 {
3306 const char *e=p;
3307 char ce = 0;
3308 while ((ce=*e++))
3309 {
3310 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3311 }
3312 if (ce==';') // found end of an entity
3313 {
3314 // copy entry verbatim
3315 result+=c;
3316 while (p<e) result+=*p++;
3317 }
3318 else
3319 {
3320 result+="&amp;";
3321 }
3322 }
3323 else
3324 {
3325 result+="&amp;";
3326 }
3327 break;
3328 case '\'': result+="&#39;"; break;
3329 case '"': result+="&quot;"; break;
3330 default:
3331 {
3332 uint8_t uc = static_cast<uint8_t>(c);
3333 if (uc<32 && !isspace(c))
3334 {
3335 result+="&#x24";
3336 result+=hex[uc>>4];
3337 result+=hex[uc&0xF];
3338 result+=';';
3339 }
3340 else
3341 {
3342 result+=c;
3343 }
3344 }
3345 break;
3346 }
3347 }
3348 return result;
3349}
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

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 3202 of file util.cpp.

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

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 3351 of file util.cpp.

3352{
3353 if (s.empty()) return s;
3354 DString result;
3355 result.reserve(s.length()+32);
3356 const char *p=s.data();
3357 char c = 0;
3358 while ((c=*p++))
3359 {
3360 switch (c)
3361 {
3362 case '"': if (!singleQuotes) result+="\\\""; else result+=c;
3363 break;
3364 case '\'': if (singleQuotes) result+="\\\'"; else result+=c;
3365 break;
3366 case '\\': if (*p=='u' && *(p+1)=='{') result+="\\"; // keep \u{..} unicode escapes
3367 else result+="\\\\";
3368 break;
3369 default: result+=c; break;
3370 }
3371 }
3372 return keepEntities ? result : HtmlEntityMapper::instance().convertCharEntitiesToUTF8(result);
3373}
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 3232 of file util.cpp.

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

4620{
4621 if (!Dir().copy(src.str(),dest.str()))
4622 {
4623 err("could not copy file {} to {}\n",src,dest);
4624 return false;
4625 }
4626 return true;
4627}
#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 4659 of file util.cpp.

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

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 4502 of file util.cpp.

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

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 2969 of file util.cpp.

2970{
2971 if (Config_getBool(CREATE_SUBDIRS))
2972 {
2973 // create up to 4096 subdirectories
2974 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
2975 for (int l1=0; l1<16; l1++)
2976 {
2977 DString subdir;
2978 subdir.sprintf("d%x",l1);
2979 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
2980 {
2981 term("Failed to create output directory '{}'\n",subdir);
2982 }
2983 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
2984 {
2985 DString subsubdir;
2986 subsubdir.sprintf("d%x/d%02x",l1,l2);
2987 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
2988 {
2989 term("Failed to create output directory '{}'\n",subsubdir);
2990 }
2991 }
2992 }
2993 }
2994}
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 5343 of file util.cpp.

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

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 5194 of file util.cpp.

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

2930{
2931 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
2932 DString absIncFileName = incFileName;
2933 FileInfo fi(curFile.str());
2934 if (fi.exists())
2935 {
2936 DString absName = fi.dirPath(true)+"/"+incFileName;
2937 FileInfo fi2(absName.str());
2938 if (fi2.exists())
2939 {
2940 absIncFileName=fi2.absFilePath();
2941 }
2942 else if (searchIncludes) // search in INCLUDE_PATH as well
2943 {
2944 StringVector includePath = Config_getList(INCLUDE_PATH);
2945 for (const auto &incPath : includePath)
2946 {
2947 FileInfo fi3(incPath);
2948 if (fi3.exists() && fi3.isDir())
2949 {
2950 absName = fi3.absFilePath()+"/"+incFileName;
2951 //printf("trying absName=%s\n",qPrint(absName));
2952 FileInfo fi4(absName.str());
2953 if (fi4.exists())
2954 {
2955 absIncFileName=fi4.absFilePath();
2956 break;
2957 }
2958 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
2959 }
2960 }
2961 }
2962 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
2963 }
2964 return absIncFileName;
2965}
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 2688 of file util.cpp.

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

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 4491 of file util.cpp.

4492{
4493 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
4494 if (extLinksInWindow)
4495 return "target=\"_blank\" ";
4496 else if (parent)
4497 return "target=\"_parent\" ";
4498 else
4499 return "";
4500}
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 4538 of file util.cpp.

4539{
4540 DString result;
4541 if (!ref.empty())
4542 {
4543 auto it = Doxygen::tagDestinationMap.find(ref.str());
4545 {
4546 result = it->second;
4547 size_t l = result.length();
4548 if (!relPath.empty() && l>0 && result.at(0)=='.')
4549 { // relative path -> prepend relPath.
4550 result.prepend(relPath);
4551 l+=relPath.length();
4552 }
4553 if (l>0 && result.at(l-1)!='/') result+='/';
4554 }
4555 }
4556 else
4557 {
4558 result = relPath;
4559 }
4560 return result;
4561}
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 5354 of file util.cpp.

5355{
5356 DString text=rawStart;
5357 size_t i = text.find('"');
5359 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
5360}
#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 3380 of file util.cpp.

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

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

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 3026 of file util.cpp.

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

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 4454 of file util.cpp.

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

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 2451 of file util.cpp.

2452{
2453 ambig=false;
2454 DString result;
2455 bool found=false;
2456 if (!found)
2457 {
2458 FileInfo fi(file.str());
2459 if (fi.exists())
2460 {
2461 result=fi.absFilePath();
2462 found=true;
2463 }
2464 }
2465 if (!found)
2466 {
2467 StringVector examplePathList = Config_getList(EXAMPLE_PATH);
2468 for (const auto &s : examplePathList)
2469 {
2470 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2471 FileInfo fi(absFileName);
2472 if (fi.exists())
2473 {
2474 result=fi.absFilePath();
2475 found=true;
2476 }
2477 }
2478 }
2479
2480 if (!found)
2481 {
2482 // as a fallback we also look in the exampleNameDict
2484 if (fd && !ambig)
2485 {
2486 result=fd->absFilePath();
2487 }
2488 }
2489 return result;
2490}
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 4964 of file util.cpp.

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

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 4968 of file util.cpp.

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

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

◆ getDotImageExtensionGenerated()

DString getDotImageExtensionGenerated ( const DString & format)

Definition at line 4974 of file util.cpp.

4975{
4976 StringVector splitExt = split(format.str(),":");
4977 DString extGen;
4978 for (size_t i = splitExt.size(); i > 0; )
4979 {
4980 --i;
4981 extGen += splitExt[i] + (i!=0 ? "." : "");
4982 }
4983 return extGen;
4984}
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 4477 of file util.cpp.

4478{
4479 InputFileEncoding elem;
4480 auto getter = [](const InputFileEncoding &e) { return e.pattern.str(); };
4481 if (fi.match(Doxygen::inputFileEncodingList,useCaseSenseNames(),&elem,getter)) // check for file specific encoding
4482 {
4483 return elem.encoding;
4484 }
4485 else // fall back to default encoding
4486 {
4487 return Config_getString(INPUT_ENCODING);
4488 }
4489}
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 4186 of file util.cpp.

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

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 4168 of file util.cpp.

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

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 4629 of file util.cpp.

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

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 2651 of file util.cpp.

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

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 5285 of file util.cpp.

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

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 3798 of file util.cpp.

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

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

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

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 4095 of file util.cpp.

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

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 4865 of file util.cpp.

4866{
4867 DString paramDocs;
4868 if (al.hasDocumentation(true))
4869 {
4870 for (const Argument &a : al)
4871 {
4872 if (a.hasDocumentation(true))
4873 {
4874 DString docsWithoutDir = a.docs;
4875 DString direction = extractDirection(docsWithoutDir);
4876 DString name = a.name;
4877 if (name.empty())
4878 {
4879 name = "-";
4880 }
4881 paramDocs+=" \\ilinebr @param"+direction+" "+name+" "+docsWithoutDir;
4882 }
4883 }
4884 }
4885 return paramDocs;
4886}
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:4829

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 3076 of file util.cpp.

3077{
3078 DString result=scope;
3079 if (!templ.empty() && scope.find('<')==DString::npos)
3080 {
3081 size_t si=0, pi=0;
3082 ClassDef *cd=nullptr;
3083 while (
3084 (si=scope.find("::",pi))!=DString::npos && !getClass(scope.left(si)+templ) &&
3085 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3086 )
3087 {
3088 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3089 pi=si+2;
3090 }
3091 if (si==DString::npos) // not nested => append template specifier
3092 {
3093 result+=templ;
3094 }
3095 else // nested => insert template specifier before after first class name
3096 {
3097 result=scope.left(si) + templ + scope.mid(si);
3098 }
3099 }
3100 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3101 // qPrint(scope),qPrint(templ),qPrint(result));
3102 return result;
3103}
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 4646 of file util.cpp.

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

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:4629

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 4959 of file util.cpp.

4960{
4961 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
4962}
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 5334 of file util.cpp.

5335{
5336 if (size_t idx = name.find('<'); idx!=DString::npos)
5337 {
5338 return name.left(idx)+"-"+DString().setNum(name.contains(",")+1)+"-g";
5339 }
5340 return name;
5341}
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 3753 of file util.cpp.

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

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

4987{
4988 ASSERT(!f.is_open());
4989 bool fileOpened=false;
4990 bool writeToStdout=outFile=="-";
4991 if (writeToStdout) // write to stdout
4992 {
4993 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
4994 fileOpened = true;
4995 }
4996 else // write to file
4997 {
4998 FileInfo fi(outFile.str());
4999 if (fi.exists()) // create a backup
5000 {
5001 Dir dir;
5002 FileInfo backup(fi.filePath()+".bak");
5003 if (backup.exists()) // remove existing backup
5004 dir.remove(backup.filePath());
5005 dir.rename(fi.filePath(),fi.filePath()+".bak");
5006 }
5007 f = Portable::openOutputStream(outFile);
5008 fileOpened = f.is_open();
5009 }
5010 return fileOpened;
5011}
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 2580 of file util.cpp.

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

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

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

◆ projectLogoSize()

DString projectLogoSize ( )

Definition at line 2599 of file util.cpp.

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

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

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 4374 of file util.cpp.

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

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 2912 of file util.cpp.

2913{
2914 DString result;
2915 if (Config_getBool(CREATE_SUBDIRS))
2916 {
2917 if (name.empty())
2918 {
2919 return REL_PATH_TO_ROOT;
2920 }
2921 else if (size_t i = name.rfind('/'); i!=DString::npos)
2922 {
2923 result=REL_PATH_TO_ROOT;
2924 }
2925 }
2926 return result;
2927}
#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 4568 of file util.cpp.

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

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.

2316{
2317 *resContext=nullptr;
2318
2319 DString linkRef=lr;
2320 if (lang==SrcLangExt::CSharp)
2321 {
2322 linkRef = mangleCSharpGenericName(linkRef);
2323 }
2324 DString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,false);
2325 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2326 const FileDef *fd = nullptr;
2327 const GroupDef *gd = nullptr;
2328 const PageDef *pd = nullptr;
2329 const ClassDef *cd = nullptr;
2330 const DirDef *dir = nullptr;
2331 const ConceptDef *cnd = nullptr;
2332 const ModuleDef *modd = nullptr;
2333 const NamespaceDef *nd = nullptr;
2334 const SectionInfo *si = nullptr;
2335 bool ambig = false;
2336 if (linkRef.empty()) // no reference name!
2337 {
2338 AUTO_TRACE_EXIT("no_ref");
2339 return false;
2340 }
2341 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2342 {
2343 gd = pd->getGroupDef();
2344 if (gd)
2345 {
2346 if (!pd->name().empty()) si=SectionManager::instance().find(pd->name());
2347 *resContext=gd;
2348 if (si) resAnchor = si->label();
2349 }
2350 else
2351 {
2352 *resContext=pd;
2353 }
2354 AUTO_TRACE_EXIT("page");
2355 return true;
2356 }
2357 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2358 {
2359 *resContext=si->definition();
2360 resAnchor = si->label();
2361 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2362 return true;
2363 }
2364 else if (!prefix.empty() && (si=SectionManager::instance().find(linkRef)))
2365 {
2366 *resContext=si->definition();
2367 resAnchor = si->label();
2368 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2369 return true;
2370 }
2371 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2372 {
2373 *resContext=pd;
2374 AUTO_TRACE_EXIT("example");
2375 return true;
2376 }
2377 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2378 {
2379 *resContext=gd;
2380 AUTO_TRACE_EXIT("group");
2381 return true;
2382 }
2383 else if ((fd=Doxygen::inputNameLinkedMap->findFileDef(linkRef,ambig)) // file link
2384 && fd->isLinkable())
2385 {
2386 *resContext=fd;
2387 AUTO_TRACE_EXIT("file");
2388 return true;
2389 }
2390 else if ((cd=getClass(linkRef))) // class link
2391 {
2392 *resContext=cd;
2393 resAnchor=cd->anchor();
2394 AUTO_TRACE_EXIT("class");
2395 return true;
2396 }
2397 else if (lang==SrcLangExt::Java &&
2398 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2399 {
2400 *resContext=cd;
2401 resAnchor=cd->anchor();
2402 AUTO_TRACE_EXIT("generic");
2403 return true;
2404 }
2405 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2406 {
2407 *resContext=cd;
2408 resAnchor=cd->anchor();
2409 AUTO_TRACE_EXIT("protocol");
2410 return true;
2411 }
2412 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2413 {
2414 *resContext=cnd;
2415 resAnchor=cnd->anchor();
2416 AUTO_TRACE_EXIT("concept");
2417 return true;
2418 }
2419 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2420 {
2421 *resContext=modd;
2422 resAnchor=modd->anchor();
2423 AUTO_TRACE_EXIT("module");
2424 return true;
2425 }
2426 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2427 {
2428 *resContext=nd;
2429 AUTO_TRACE_EXIT("namespace");
2430 return true;
2431 }
2432 else if ((dir=resolveDirLink(linkRef)) && dir->isLinkable())
2433 {
2434 *resContext=dir;
2435 AUTO_TRACE_EXIT("directory");
2436 return true;
2437 }
2438 else // probably a member reference
2439 {
2440 const MemberDef *md = nullptr;
2441 bool res = resolveRef(scName,lr,true,resContext,&md,lang);
2442 if (md) resAnchor=md->anchor();
2443 AUTO_TRACE_EXIT("member? res={}",res);
2444 return res;
2445 }
2446}
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:3686
static const DirDef * resolveDirLink(const DString &linkRef)
Definition util.cpp:2290
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5334

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:3798

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 5016 of file util.cpp.

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

2568{
2569 // get the current date and time
2570 std::tm dat{};
2571 int specFormat=0;
2572 DString specDate = "";
2573 DString err = dateTimeFromString(specDate,dat,specFormat);
2574
2575 // do the conversion
2576 int usedFormat=0;
2577 return formatDateTime(fmt,dat,usedFormat);
2578}
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 4310 of file util.cpp.

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

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 4683 of file util.cpp.

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

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

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

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 3960 of file util.cpp.

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

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 3109 of file util.cpp.

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

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 3686 of file util.cpp.

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

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 2494 of file util.cpp.

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

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 3524 of file util.cpp.

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

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 2775 of file util.cpp.

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

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

◆ updateLanguageMapping()

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

Definition at line 4063 of file util.cpp.

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

2680{
2681 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
2682
2683 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
2684 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
2686}
#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 5373 of file util.cpp.

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

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 4283 of file util.cpp.

4284{
4285 if (al.empty()) return;
4287 for (const Argument &a : al)
4288 {
4290 ol.parseText(a.name);
4291 ol.endConstraintParam();
4293 linkifyText(TextGeneratorOLImpl(ol),a.type,LinkifyTextOptions().setScope(d));
4294 ol.endConstraintType();
4296 ol.generateDoc(d->docFile(),
4297 d->docLine(),
4298 d,
4299 nullptr,
4300 a.docs,
4301 DocOptions()
4302 .setIndexWords(true));
4303 ol.endConstraintDocs();
4304 }
4305 ol.endConstraintList();
4306}
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().