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

A bunch of utility functions. More...

#include <memory>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <fstream>
#include <variant>
#include <string_view>
#include <ctype.h>
#include "types.h"
#include "docparser.h"
#include "containers.h"
#include "outputgen.h"
#include "regex.h"
#include "conceptdef.h"
#include "construct.h"
#include "htmlentity.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)
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 removeRedundantWhiteSpace (const DString &s)
DString stripAnonymousNamespaceScope (const DString &s)
DString stripFromPath (const DString &path)
DString stripFromIncludePath (const DString &path)
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)
int getPrefixIndex (const DString &name)
DString convertNameToFile (const DString &name, bool allowDots=false, bool allowUnderscore=false)
DString removeAnonymousScopes (const DString &s)
DString replaceAnonymousScopes (const DString &s, const DString &replacement=DString())
DString insertTemplateSpecifierInScope (const DString &scope, const DString &templ)
DString stripScope (const DString &name)
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)
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)
PageDefaddRelatedPage (const DString &name, const DString &ptitle, const DString &doc, const DString &fileName, int docLine, int startLine, const RefItemVector &sli=RefItemVector(), GroupDef *gd=nullptr, const TagInfo *tagInfo=nullptr, bool xref=false, SrcLangExt lang=SrcLangExt::Unknown)
bool useCaseSenseNames ()
 Returns true if the names of the symbols can be case sensitive.
DString escapeCharsInString (const DString &name, bool allowDots, bool allowUnderscore=false)
DString unescapeCharsInString (const DString &s)
void addGroupListToTitle (OutputList &ol, const Definition *d)
DString linkToText (SrcLangExt lang, const DString &link, bool ignoreDots)
bool checkExtension (const DString &fName, const DString &ext)
void addHtmlExtensionIfMissing (DString &fName)
DString stripExtensionGeneral (const DString &fName, const DString &ext)
DString stripExtension (const DString &fName)
DString makeBaseName (const DString &name, const DString &ext)
int computeQualifiedIndex (const DString &name)
 Return the index of the last :: in the string name that is still before the first <.
void addDirPrefix (DString &fileName)
DString relativePathToRoot (const DString &name)
DString determineAbsoluteIncludeName (const DString &curFile, const DString &incFileName)
void createSubDirs (const Dir &d)
void clearSubDirs (const Dir &d)
DString removeLongPathMarker (const DString &path)
DString stripPath (const DString &s)
bool findAndRemoveWord (DString &s, const char *word)
 removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple sequences of spaces.
DString stripLeadingAndTrailingEmptyLines (const DString &s, int &docLine)
 Special version of DString::stripWhiteSpace() that only strips completely blank lines.
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 ()
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const DString &n)
DString parseCommentAsText (const Definition *scope, const MemberDef *member, const DString &doc, const DString &fileName, int lineNr)
DString parseCommentAsHtml (const Definition *scope, const MemberDef *member, const DString &doc, const DString &fileName, int lineNr)
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
DString recodeString (const DString &str, const char *fromEncoding, const char *toEncoding)
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
void stackTrace ()
DString filterTitle (const DString &title)
bool patternMatch (const FileInfo &fi, const StringVector &patList)
DString externalLinkTarget (const bool parent=false)
DString createHtmlUrl (const DString &relPath, const DString &ref, bool href, bool islocalFile, const DString &targetFileName, const DString &anchor)
DString externalRef (const DString &relPath, const DString &ref, bool href)
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.
bool copyFile (const DString &src, const DString &dest)
 Copies the contents of file with name src to the newly created file with name dest.
int lineBlock (const DString &text, const DString &marker)
 Returns the line number of the line following the line with the marker.
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 processMarkup (const DString &s)
bool protectionLevelVisible (Protection prot)
DString stripIndentation (const DString &s, bool skipFirstLine=false)
void stripIndentationVerbatim (DString &doc, size_t indentationLevel, bool skipFirstLine=true)
DString getDotImageExtension ()
bool fileVisibleInIndex (const FileDef *fd, bool &genSourceFile)
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.
bool mainPageHasTitle ()
bool openOutputFile (const DString &outFile, std::ofstream &f)
bool recognizeFixedForm (const DString &contents, FortranFormat format)
FortranFormat convertFileNameFortranParserCode (DString fn)
DString getEncoding (const FileInfo &fi)
DString detab (const DString &s, size_t &refIndent)
DString getProjectId ()
DString projectLogoFile ()
DString projectLogoSize ()
DString showDate (const DString &fmt)
void mergeMemberOverrideOptions (MemberDefMutable *md1, MemberDefMutable *md2)
size_t updateColumnCount (const char *s, size_t col)
DString mangleCSharpGenericName (const DString &name)
DString demangleCSharpGenericName (const DString &name, const DString &templArgs)
DString extractBeginRawStringDelimiter (const char *rawStart)
DString extractEndRawStringDelimiter (const char *rawEnd)

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Typedef Documentation

◆ KeywordSubstitutionList

Definition at line 263 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 220 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 4398 of file util.cpp.

4399{
4400 updateLanguageMapping(".xml", "xml");
4401 updateLanguageMapping(".sql", "sql");
4402}
bool updateLanguageMapping(const DString &extension, const DString &language)
Definition util.cpp:4299

References addCodeOnlyMappings(), and updateLanguageMapping().

Referenced by addCodeOnlyMappings(), addDirPrefix(), and generateOutput().

◆ addDirPrefix()

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( DString & fName)

Definition at line 4128 of file util.cpp.

4129{
4130 if (fName.empty()) return;
4131 size_t i_fs = fName.rfind('/');
4132 size_t i_bs = fName.rfind('\\');
4133 size_t p = i_fs!=DString::npos && i_bs!=DString::npos ? std::max(i_fs, i_bs) :
4134 i_fs!=DString::npos ? i_fs : i_bs!=DString::npos ? i_bs : 0;
4135 size_t i = fName.find('.',p); // search for . after path part
4136 if (i==DString::npos)
4137 {
4139 }
4140}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:89
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:249
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:153
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:183
size_t find(char c, size_t pos=0) const
Definition dstring.h:244
static DString htmlFileExtension
Definition doxygen.h:122

References addHtmlExtensionIfMissing(), 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(), addHtmlExtensionIfMissing(), 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().

◆ addRelatedPage()

PageDef * addRelatedPage ( const DString & name,
const DString & ptitle,
const DString & doc,
const DString & fileName,
int docLine,
int startLine,
const RefItemVector & sli = RefItemVector(),
GroupDef * gd = nullptr,
const TagInfo * tagInfo = nullptr,
bool xref = false,
SrcLangExt lang = SrcLangExt::Unknown )

Definition at line 3920 of file util.cpp.

3931{
3932 PageDef *pd=nullptr;
3933 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
3934 DString title=ptitle.stripWhiteSpace();
3935 bool newPage = true;
3936 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
3937 {
3938 if (!xref && !title.empty() && pd->title()!=pd->name() && pd->title()!=title)
3939 {
3940 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
3941 name,pd->docFile(),pd->getStartBodyLine());
3942 }
3943 if (!title.empty() && pd->title()==pd->name()) // pd has no real title yet
3944 {
3945 pd->setTitle(title);
3947 if (si)
3948 {
3949 si->setTitle(title);
3950 }
3951 }
3952 // append documentation block to the page.
3953 pd->setDocumentation(doc,fileName,docLine);
3954 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
3955 // append (x)refitems to the page.
3956 pd->setRefItems(sli);
3957 newPage = false;
3958 }
3959
3960 if (newPage) // new page
3961 {
3962 DString baseName=name;
3963 if (baseName.endsWith(".tex"))
3964 baseName=baseName.left(baseName.length()-4);
3966 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
3967
3968 //printf("Appending page '%s'\n",qPrint(baseName));
3969 if (pd) // replace existing page
3970 {
3971 pd->setDocumentation(doc,fileName,docLine);
3972 pd->setFileName(::convertNameToFile(baseName,false,true));
3973 pd->setShowLineNo(false);
3974 pd->setNestingLevel(0);
3975 pd->setPageScope(nullptr);
3976 pd->setTitle(title);
3977 pd->setReference(DString());
3978 }
3979 else // newPage
3980 {
3981 pd = Doxygen::pageLinkedMap->add(baseName,
3982 createPageDef(fileName,docLine,baseName,doc,title));
3983 }
3984 pd->setBodySegment(startLine,startLine,-1);
3985
3986 pd->setRefItems(sli);
3987 pd->setLanguage(lang);
3988
3989 if (tagInfo)
3990 {
3991 pd->setReference(tagInfo->tagName);
3992 pd->setFileName(tagInfo->fileName);
3993 }
3994
3995 if (gd) gd->addPage(pd);
3996
3997 if (pd->hasTitle())
3998 {
3999 //outputList->writeTitle(pi->name,pi->title);
4000
4001 // a page name is a label as well!
4002 DString file;
4003 DString orgFile;
4004 int line = -1;
4005 if (gd)
4006 {
4007 file=gd->getOutputFileBase();
4008 orgFile=gd->getOutputFileBase();
4009 }
4010 else
4011 {
4012 file=pd->getOutputFileBase();
4013 orgFile=pd->docFile();
4014 line = pd->getStartBodyLine();
4015 }
4016 const SectionInfo *si = SectionManager::instance().find(pd->name());
4017 if (si)
4018 {
4019 if (!si->ref().empty()) // we are from a tag file
4020 {
4022 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4023 }
4024 else if (si->lineNr() != -1)
4025 {
4026 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
4027 }
4028 else
4029 {
4030 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
4031 }
4032 }
4033 else
4034 {
4036 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4037 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
4038 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
4039 // qPrint(si->fileName));
4040 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
4041 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
4042 }
4043 }
4044 }
4045 return pd;
4046}
DString()=default
DString right(size_t len) const
Definition dstring.h:316
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:342
DString left(size_t len) const
Definition dstring.h:311
bool endsWith(const char *s) const
Definition dstring.h:606
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:156
virtual const DString & name() const =0
virtual DString getReference() const =0
virtual DString docFile() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual DString getOutputFileBase() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setReference(const DString &r)=0
virtual void setDocumentation(const DString &d, const DString &docFile, int docLine, bool stripWhiteSpace=true)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setRefItems(const RefItemVector &sli)=0
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
virtual void addPage(PageDef *def)=0
T * add(const char *k, Args &&... args)
Definition linkedmap.h:90
const T * find(const std::string &key) const
Definition linkedmap.h:47
A model of a page symbol.
Definition pagedef.h:26
virtual void setTitle(const DString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const DString &name)=0
virtual void setShowLineNo(bool)=0
virtual DString title() const =0
virtual void setPageScope(Definition *)=0
class that provide information about a section.
Definition section.h:58
void setTitle(const DString &t)
Definition section.h:84
DString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
DString ref() const
Definition section.h:72
SectionInfo * replace(const DString &label, const DString &fileName, int lineNr, const DString &title, SectionType type, int level, const DString &ref=DString())
Definition section.h:157
SectionInfo * add(const SectionInfo &si)
Definition section.h:139
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
static constexpr int Page
Definition section.h:31
#define warn(file, line, fmt,...)
Definition message.h:97
std::unique_ptr< PageDef > createPageDef(const DString &f, int l, const DString &n, const DString &d, const DString &t)
Definition pagedef.cpp:84
DString tagName
Definition entry.h:105
DString fileName
Definition entry.h:106
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2930

References LinkedMap< T, Hash, KeyEqual, Map >::add(), SectionManager::add(), GroupDef::addPage(), addRelatedPage(), convertNameToFile(), createPageDef(), Definition::docFile(), DString::DString(), DString::empty(), DString::endsWith(), SectionInfo::fileName(), TagInfo::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Definition::getOutputFileBase(), Definition::getReference(), Definition::getStartBodyLine(), PageDef::hasTitle(), Doxygen::htmlFileExtension, SectionManager::instance(), Definition::isReference(), DString::left(), DString::length(), SectionInfo::lineNr(), Definition::name(), SectionType::Page, Doxygen::pageLinkedMap, SectionInfo::ref(), SectionManager::replace(), DString::right(), DefinitionMutable::setBodySegment(), DefinitionMutable::setDocumentation(), PageDef::setFileName(), DefinitionMutable::setLanguage(), PageDef::setNestingLevel(), PageDef::setPageScope(), DefinitionMutable::setReference(), DefinitionMutable::setRefItems(), PageDef::setShowLineNo(), PageDef::setTitle(), SectionInfo::setTitle(), DString::stripWhiteSpace(), TagInfo::tagName, PageDef::title(), and warn.

Referenced by RequirementManager::addRequirement(), CitationManager::generatePage(), and RefList::generatePage().

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

892{
893 DString result;
894 if (!al.hasParameters()) return result;
895 result+="(";
896 for (auto it = al.begin() ; it!=al.end() ;)
897 {
898 Argument a = *it;
899 DString type1 = useCanonicalType && !a.canType.empty() ? a.canType : a.type;
900 DString type2;
901 if (size_t i=type1.find(")("); i!=DString::npos) // hack to deal with function pointers
902 {
903 type2=type1.mid(i);
904 type1=type1.left(i);
905 }
906 if (!a.attrib.empty())
907 {
908 result+=a.attrib+" ";
909 }
910 if (!a.name.empty() || !a.array.empty())
911 {
912 result+= type1+" "+a.name+type2+a.array;
913 }
914 else
915 {
916 result+= type1+type2;
917 }
918 if (!a.defval.empty() && showDefVals)
919 {
920 result+="="+a.defval;
921 }
922 ++it;
923 if (it!=al.end()) result+=", ";
924 }
925 result+=")";
926 if (al.constSpecifier()) result+=" const";
927 if (al.volatileSpecifier()) result+=" volatile";
928 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
929 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
930 if (!al.trailingReturnType().empty()) result+=al.trailingReturnType();
931 if (al.pureSpecifier()) result+=" =0";
932 return removeRedundantWhiteSpace(result);
933}
RefQualifierType refQualifier() const
Definition arguments.h:116
bool pureSpecifier() const
Definition arguments.h:113
iterator end()
Definition arguments.h:94
bool hasParameters() const
Definition arguments.h:76
DString trailingReturnType() const
Definition arguments.h:114
bool constSpecifier() const
Definition arguments.h:111
iterator begin()
Definition arguments.h:93
bool volatileSpecifier() const
Definition arguments.h:112
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:323
This class contains the information about the argument of a function or template.
Definition arguments.h:27
DString attrib
Definition arguments.h:41
DString defval
Definition arguments.h:46
DString array
Definition arguments.h:45
DString name
Definition arguments.h:44
DString type
Definition arguments.h:42
DString canType
Definition arguments.h:43
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:458

References argListToString(), 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(), argListToString(), 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 5731 of file util.cpp.

5732{
5733 if (s.empty()) return;
5734
5735 const char *p = s.data();
5736 char c = 0;
5737 while ((c=*p))
5738 {
5739 if (c==markerInfo.markerChar) // potential start of marker
5740 {
5741 if (dstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
5742 {
5743 size_t len = markerInfo.beginLen;
5744 bool negate = *(p+len)=='!';
5745 if (negate) len++;
5746 p += len;
5747 DString marker;
5748 while (*p)
5749 {
5750 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
5751 {
5752 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
5753 break;
5754 }
5755 else if (markerInfo.closeLen!= 0 && dstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5756 {
5757 p += markerInfo.closeLen;
5758 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
5759 break;
5760 }
5761 marker += *p;
5762 p++;
5763 }
5764 }
5765 else if (dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
5766 {
5767 size_t len = markerInfo.endLen;
5768 bool negate = *(p+len)=='!';
5769 if (negate) len++;
5770 p += len;
5771 DString marker;
5772 while (*p)
5773 {
5774 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
5775 {
5776 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
5777 break;
5778 }
5779 else if (markerInfo.closeLen!= 0 && dstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5780 {
5781 p += markerInfo.closeLen;
5782 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
5783 break;
5784 }
5785 marker += *p;
5786 p++;
5787 }
5788 }
5789 }
5790 p++;
5791 }
5792}
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:162
int dstrncmp(const char *str1, const char *str2, size_t len)
Definition dstring.h:61
size_t beginLen
Definition util.h:226
const char * closeStr
Definition util.h:229
const char * beginStr
Definition util.h:225
size_t closeLen
Definition util.h:230
const char * endStr
Definition util.h:227

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

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

◆ checkExtension()

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

Definition at line 4123 of file util.cpp.

4124{
4125 return fName.right(ext.length())==ext;
4126}

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

Referenced by checkExtension(), 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 4507 of file util.cpp.

4508{
4509 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
4510
4511 if (bestMatch && bestMatch->isTypedef())
4512 return true; // closest matching symbol is a typedef
4513 else
4514 return false;
4515}
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual bool isTypedef() const =0
static MemberDef * getMemberFromSymbol(const Definition *scope, const FileDef *fileScope, const DString &n)
Definition util.cpp:4455

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

Referenced by addDirPrefix(), checkIfTypedef(), and isVarWithConstructor().

◆ cleanupInlineGraphs()

void cleanupInlineGraphs ( )

Deletes all graph files written with writeInlineGraph()

Definition at line 6048 of file util.cpp.

6049{
6050 if (Config_getBool(DOT_CLEANUP))
6051 {
6052 for (const auto& fileName: writeFileContents_set)
6053 {
6054 Dir().remove(qPrint(fileName));
6055 }
6056 }
6057}
Dir()
Definition dir.cpp:189
#define Config_getBool(name)
Definition config.h:33
const char * qPrint(const char *s)
Definition dstring.h:772
static StringUnorderedSet writeFileContents_set
Definition util.cpp:6021

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

Referenced by cleanupInlineGraphs(), and generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3063 of file util.cpp.

3064{
3065 if (Config_getBool(CREATE_SUBDIRS))
3066 {
3067 // remove empty subdirectories
3068 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3069 for (int l1=0;l1<16;l1++)
3070 {
3071 DString subdir;
3072 subdir.sprintf("d%x",l1);
3073 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3074 {
3075 DString subsubdir;
3076 subsubdir.sprintf("d%x/d%02x",l1,l2);
3077 if (d.exists(subsubdir.str()) && d.empty(subsubdir.str()))
3078 {
3079 d.rmdir(subsubdir.str());
3080 }
3081 }
3082 if (d.exists(subdir.str()) && d.empty(subdir.str()))
3083 {
3084 d.rmdir(subdir.str());
3085 }
3086 }
3087 }
3088}
DString & sprintf(const char *format,...)
Definition dstring.cpp:29
const std::string & str() const
Definition dstring.h:634
bool empty(const std::string &subdir) const
Definition dir.cpp:263
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:309
bool exists() const
Definition dir.cpp:257
#define Config_getInt(name)
Definition config.h:34

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

Referenced by addDirPrefix(), DocbookGenerator::cleanup(), HtmlGenerator::cleanup(), LatexGenerator::cleanup(), ManGenerator::cleanup(), RTFGenerator::cleanup(), clearSubDirs(), 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 5895 of file util.cpp.

5896{
5897 int l = static_cast<int>(name.length());
5898 int lastSepPos = -1;
5899 const char *p = name.data();
5900 int i=l-2;
5901 int sharpCount=0;
5902 // --- begin optimized version of ts=name.findRev(">::");
5903 int ts = -1;
5904 while (i>=0)
5905 {
5906 if (p[i]=='>')
5907 {
5908 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
5909 {
5910 ts=i;
5911 break;
5912 }
5913 sharpCount++;
5914 }
5915 else if (p[i]=='<')
5916 {
5917 sharpCount--;
5918 }
5919 i--;
5920 }
5921 // --- end optimized version
5922 if (ts==-1) ts=0; else p+=++ts;
5923 for (i=ts;i<l-1;i++)
5924 {
5925 char c=*p++;
5926 if (c==':' && *p==':') lastSepPos=i;
5927 if (c=='<') break;
5928 }
5929 return lastSepPos;
5930}

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

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( DString fn)

Definition at line 5605 of file util.cpp.

5606{
5607 DString ext = getFileNameExtension(fn);
5608 DString parserName = Doxygen::parserManager->getParserName(ext);
5609
5610 if (parserName == "fortranfixed") return FortranFormat::Fixed;
5611 else if (parserName == "fortranfree") return FortranFormat::Free;
5612
5614}
static ParserManager * parserManager
Definition doxygen.h:129
DString getParserName(const DString &extension)
Gets the name of the parser associated with given extension.
Definition parserintf.h:269
DString getFileNameExtension(const DString &fn)
Definition util.cpp:4446

References convertFileNameFortranParserCode(), Fixed, Free, getFileNameExtension(), ParserManager::getParserName(), Doxygen::parserManager, and Unknown.

Referenced by convertCppComments(), convertFileNameFortranParserCode(), processMarkup(), and setFileName().

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

2931{
2932 if (name.empty()) return name;
2933 bool shortNames = Config_getBool(SHORT_NAMES);
2934 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
2935 DString result;
2936 if (shortNames) // use short names only
2937 {
2938 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
2939 auto kv = g_usedNames.find(name.str());
2940 uint32_t num=0;
2941 if (kv!=g_usedNames.end())
2942 {
2943 num = kv->second;
2944 }
2945 else
2946 {
2947 num = g_usedNamesCount;
2948 g_usedNames.emplace(name.str(),g_usedNamesCount++);
2949 }
2950 result.sprintf("a%05d",num);
2951 }
2952 else // long names
2953 {
2954 result=escapeCharsInString(name,allowDots,allowUnderscore);
2955 size_t resultLen = result.length();
2956 if (resultLen>=128) // prevent names that cannot be created!
2957 {
2958 // third algorithm based on MD5 hash
2959 result=result.left(128-32)+md5str(result.view());
2960 }
2961 }
2962 if (createSubdirs)
2963 {
2964 int l1Dir=0,l2Dir=0;
2965 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
2966 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
2967
2968 // compute md5 hash to determine sub directory to use
2969 auto md5_sig = md5hash(result.view());
2970 l1Dir = md5_sig[14] & 0xf;
2971 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
2972
2973 result.prepend(DString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
2974 }
2975 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
2976 return result;
2977}
std::string_view view() const
Definition dstring.h:167
DString & prepend(const char *s)
Definition dstring.h:504
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:2922
DString escapeCharsInString(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2755
static std::mutex g_usedNamesMutex
Definition util.cpp:2921
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:2920

References Config_getBool, Config_getInt, convertNameToFile(), DString::DString(), 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(), convertNameToFile(), 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 5438 of file util.cpp.

5444{
5445 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5446
5447 // default representing 1-1 mapping
5448 *outListType1=inListType;
5449 *outListType2=MemberListType::Invalid();
5450
5451 if (inProt==Protection::Public)
5452 {
5453 if (inListType.isPrivate())
5454 {
5455 *outListType1=MemberListType::Invalid();
5456 }
5457 }
5458 else if (inProt==Protection::Protected)
5459 {
5460 if (inListType.isPrivate() || inListType.isPublic())
5461 {
5462 *outListType1=MemberListType::Invalid();
5463 }
5464 else if (inListType.isProtected())
5465 {
5466 *outListType2=inListType.toPublic();
5467 }
5468 }
5469 else if (inProt==Protection::Private)
5470 {
5471 if (inListType.isPublic() || inListType.isProtected())
5472 {
5473 *outListType1=MemberListType::Invalid();
5474 }
5475 else if (inListType.isPrivate())
5476 {
5477 if (extractPrivate)
5478 {
5479 *outListType1=inListType.toPublic();
5480 *outListType2=inListType.toProtected();
5481 }
5482 else
5483 {
5484 *outListType1=MemberListType::Invalid();
5485 }
5486 }
5487 }
5488
5489 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
5490 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
5491}
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, convertProtectionLevel(), MemberListType::Invalid(), MemberListType::isPrivate(), MemberListType::isProtected(), MemberListType::isPublic(), MemberListType::toProtected(), and MemberListType::toPublic().

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

◆ convertToHtml()

DString convertToHtml ( const DString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 3358 of file util.cpp.

3359{
3360 if (s.empty()) return s;
3361 DString result;
3362 result.reserve(s.length()+32);
3363 const char *p=s.data();
3364 char c = 0;
3365 while ((c=*p++))
3366 {
3367 switch (c)
3368 {
3369 case '<': result+="&lt;"; break;
3370 case '>': result+="&gt;"; break;
3371 case '&': if (keepEntities)
3372 {
3373 const char *e=p;
3374 char ce = 0;
3375 while ((ce=*e++))
3376 {
3377 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3378 }
3379 if (ce==';') // found end of an entity
3380 {
3381 // copy entry verbatim
3382 result+=c;
3383 while (p<e) result+=*p++;
3384 }
3385 else
3386 {
3387 result+="&amp;";
3388 }
3389 }
3390 else
3391 {
3392 result+="&amp;";
3393 }
3394 break;
3395 case '\'': result+="&#39;"; break;
3396 case '"': result+="&quot;"; break;
3397 default:
3398 {
3399 uint8_t uc = static_cast<uint8_t>(c);
3400 if (uc<32 && !isspace(c))
3401 {
3402 result+="&#x24";
3403 result+=hex[uc>>4];
3404 result+=hex[uc&0xF];
3405 result+=';';
3406 }
3407 else
3408 {
3409 result+=c;
3410 }
3411 }
3412 break;
3413 }
3414 }
3415 return result;
3416}
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition dstring.h:222
bool isId(int c)
Returns true if c is a valid character for an identifier.
Definition dstring.h:884
static const char * hex
Definition util.cpp:96

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

Referenced by HtmlCodeGenerator::_writeCodeLink(), HtmlHelp::addContentsItem(), addMembersToIndex(), convertToHtml(), 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 3269 of file util.cpp.

3270{
3271 if (s.empty()) return s;
3272 DString result;
3273 result.reserve(s.length()+8);
3274 const char *p = s.data();
3275 char c = 0;
3276 bool first = true;
3277 while ((c=*p++))
3278 {
3279 char encChar[4];
3280 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3281 { // any permissive character except _
3282 if (first && c>='0' && c<='9') result+='a'; // don't start with a digit
3283 result+=c;
3284 }
3285 else
3286 {
3287 encChar[0]='_';
3288 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3289 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3290 encChar[3]=0;
3291 result+=encChar;
3292 }
3293 first=false;
3294 }
3295 return result;
3296}

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

Referenced by convertToId(), HtmlGenerator::endClassDiagram(), HtmlGenerator::endMemberTemplateParams(), renderQuickLinksAsJs(), 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 3418 of file util.cpp.

3419{
3420 if (s.empty()) return s;
3421 DString result;
3422 result.reserve(s.length()+32);
3423 const char *p=s.data();
3424 char c = 0;
3425 while ((c=*p++))
3426 {
3427 switch (c)
3428 {
3429 case '"': if (!singleQuotes) result+="\\\""; else result+=c;
3430 break;
3431 case '\'': if (singleQuotes) result+="\\\'"; else result+=c;
3432 break;
3433 case '\\': if (*p=='u' && *(p+1)=='{') result+="\\"; // keep \u{..} unicode escapes
3434 else result+="\\\\";
3435 break;
3436 default: result+=c; break;
3437 }
3438 }
3439 return keepEntities ? result : HtmlEntityMapper::instance().convertCharEntitiesToUTF8(result);
3440}
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
DString convertCharEntitiesToUTF8(const DString &s) const

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

Referenced by convertToJSString(), generateJSLink(), generateJSNavTree(), renderQuickLinksAsJs(), 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 3299 of file util.cpp.

3300{
3301 if (s.empty()) return s;
3302 DString result;
3303 result.reserve(s.length()+32);
3304 const char *p = s.data();
3305 char c = 0;
3306 while ((c=*p++))
3307 {
3308 switch (c)
3309 {
3310 case '<': result+="&lt;"; break;
3311 case '>': result+="&gt;"; break;
3312 case '&': if (keepEntities)
3313 {
3314 const char *e=p;
3315 char ce = 0;
3316 while ((ce=*e++))
3317 {
3318 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3319 }
3320 if (ce==';') // found end of an entity
3321 {
3322 // copy entry verbatim
3323 result+=c;
3324 while (p<e) result+=*p++;
3325 }
3326 else
3327 {
3328 result+="&amp;";
3329 }
3330 }
3331 else if (citeEntry)
3332 {
3334 result,
3335 p-1,
3336 [](HtmlEntityMapper::SymType symType) { return HtmlEntityMapper::instance().xml(symType); },
3337 "&amp;");
3338 }
3339 else
3340 {
3341 result+="&amp;";
3342 }
3343 break;
3344 case '\'': result+="&apos;"; break;
3345 case '"': result+="&quot;"; break;
3346 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
3347 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
3348 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
3349 case 27: case 28: case 29: case 30: case 31:
3350 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
3351 default: result+=c; break;
3352 }
3353 }
3354 return result;
3355}
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 convertToXML(), 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(), convertToXML(), 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()

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

5111{
5112 DString result = url;
5113 if (!relPath.empty() && !isURL(url))
5114 {
5115 result.prepend(relPath);
5116 }
5117 return result;
5118}
bool isURL(const DString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:5097

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

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

◆ createHtmlUrl()

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

Definition at line 4928 of file util.cpp.

4934{
4935 DString url;
4936 if (!ref.empty())
4937 {
4938 url = externalRef(relPath,ref,href);
4939 }
4940 if (!targetFileName.empty())
4941 {
4942 DString fn = targetFileName;
4943 if (ref.empty())
4944 {
4945 if (!anchor.empty() && isLocalFile)
4946 {
4947 fn=""; // omit file name for local links
4948 }
4949 else
4950 {
4951 url = relPath;
4952 }
4953 }
4954 url+=fn;
4955 }
4956 if (!anchor.empty())
4957 {
4958 if (!url.endsWith("=")) url+="#";
4959 url+=anchor;
4960 }
4961 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
4962 return url;
4963}
DString externalRef(const DString &relPath, const DString &ref, bool href)
Definition util.cpp:4965

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

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

◆ createSubDirs()

void createSubDirs ( const Dir & d)

Definition at line 3036 of file util.cpp.

3037{
3038 if (Config_getBool(CREATE_SUBDIRS))
3039 {
3040 // create up to 4096 subdirectories
3041 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3042 for (int l1=0; l1<16; l1++)
3043 {
3044 DString subdir;
3045 subdir.sprintf("d%x",l1);
3046 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
3047 {
3048 term("Failed to create output directory '{}'\n",subdir);
3049 }
3050 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
3051 {
3052 DString subsubdir;
3053 subsubdir.sprintf("d%x/d%02x",l1,l2);
3054 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
3055 {
3056 term("Failed to create output directory '{}'\n",subsubdir);
3057 }
3058 }
3059 }
3060 }
3061}
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
#define term(fmt,...)
Definition message.h:137

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

Referenced by addDirPrefix(), createSubDirs(), 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 5993 of file util.cpp.

5994{
5995 DString result=name;
5996 if (result.endsWith("-g"))
5997 {
5998 size_t idx = result.find('-');
5999 result = result.left(idx)+templArgs;
6000 }
6001 return result;
6002}

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

Referenced by ClassDefImpl::className(), demangleCSharpGenericName(), and processMarkup().

◆ detab()

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

Definition at line 5796 of file util.cpp.

5797{
5798 int tabSize = Config_getInt(TAB_SIZE);
5799 size_t size = s.length();
5800 DString result;
5801 result.reserve(size+256);
5802 const char *data = s.data();
5803 size_t i=0;
5804 int col=0;
5805 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
5806 const int maxIndent=1000000; // value representing infinity
5807 int minIndent=maxIndent;
5808 bool skip = false;
5809 while (i<size)
5810 {
5811 char c = data[i++];
5812 switch(c)
5813 {
5814 case '\t': // expand tab
5815 {
5816 int stop = tabSize - (col%tabSize);
5817 //printf("expand at %d stop=%d\n",col,stop);
5818 col+=stop;
5819 while (stop--) result+=' ';
5820 }
5821 break;
5822 case '\\':
5823 if (data[i] == '\\') // escaped command -> ignore
5824 {
5825 result+=c;
5826 result+=data[i++];
5827 col+=2;
5828 }
5829 else if (i+5<size && literal_at(data+i,"iskip")) // command
5830 {
5831 i+=5;
5832 skip = true;
5833 }
5834 else if (i+8<size && literal_at(data+i,"endiskip")) // command
5835 {
5836 i+=8;
5837 skip = false;
5838 }
5839 else // some other command
5840 {
5841 result+=c;
5842 col++;
5843 }
5844 break;
5845 case '\n': // reset column counter
5846 result+=c;
5847 col=0;
5848 break;
5849 case ' ': // increment column counter
5850 result+=c;
5851 col++;
5852 break;
5853 default: // non-whitespace => update minIndent
5854 if (c<0 && i<size) // multibyte sequence
5855 {
5856 // special handling of the UTF-8 nbsp character 0xC2 0xA0
5857 int nb = isUTF8NonBreakableSpace(data);
5858 if (nb>0)
5859 {
5860 result+=doxy_nbsp;
5861 i+=nb-1;
5862 }
5863 else
5864 {
5865 int bytes = getUTF8CharNumBytes(c);
5866 for (int j=0;j<bytes-1 && c;j++)
5867 {
5868 result+=c;
5869 c = data[i++];
5870 }
5871 result+=c;
5872 }
5873 }
5874 else
5875 {
5876 result+=c;
5877 }
5878 if (!skip && col<minIndent) minIndent=col;
5879 col++;
5880 }
5881 }
5882 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
5883 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
5884 return result;
5885}
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:228
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:23

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

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

◆ determineAbsoluteIncludeName()

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

Definition at line 2996 of file util.cpp.

2997{
2998 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
2999 DString absIncFileName = incFileName;
3000 FileInfo fi(curFile.str());
3001 if (fi.exists())
3002 {
3003 DString absName = fi.dirPath(true)+"/"+incFileName;
3004 FileInfo fi2(absName.str());
3005 if (fi2.exists())
3006 {
3007 absIncFileName=fi2.absFilePath();
3008 }
3009 else if (searchIncludes) // search in INCLUDE_PATH as well
3010 {
3011 StringVector includePath = Config_getList(INCLUDE_PATH);
3012 for (const auto &incPath : includePath)
3013 {
3014 FileInfo fi3(incPath);
3015 if (fi3.exists() && fi3.isDir())
3016 {
3017 absName = fi3.absFilePath()+"/"+incFileName;
3018 //printf("trying absName=%s\n",qPrint(absName));
3019 FileInfo fi4(absName.str());
3020 if (fi4.exists())
3021 {
3022 absIncFileName=fi4.absFilePath();
3023 break;
3024 }
3025 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3026 }
3027 }
3028 }
3029 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3030 }
3031 return absIncFileName;
3032}
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
#define Config_getList(name)
Definition config.h:38
std::vector< std::string > StringVector
Definition containers.h:33

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

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

◆ escapeCharsInString()

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

Definition at line 2755 of file util.cpp.

2756{
2757 if (name.empty()) return name;
2758 bool caseSenseNames = useCaseSenseNames();
2759 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
2760 DString result;
2761 result.reserve(name.length()+8);
2762 signed char c = 0;
2763 const char *p=name.data();
2764 while ((c=*p++)!=0)
2765 {
2766 switch(c)
2767 {
2768 case '_': if (allowUnderscore) result+='_'; else result+="__"; break;
2769 case '-': result+='-'; break;
2770 case ':': result+="_1"; break;
2771 case '/': result+="_2"; break;
2772 case '<': result+="_3"; break;
2773 case '>': result+="_4"; break;
2774 case '*': result+="_5"; break;
2775 case '&': result+="_6"; break;
2776 case '|': result+="_7"; break;
2777 case '.': if (allowDots) result+='.'; else result+="_8"; break;
2778 case '!': result+="_9"; break;
2779 case ',': result+="_00"; break;
2780 case ' ': result+="_01"; break;
2781 case '{': result+="_02"; break;
2782 case '}': result+="_03"; break;
2783 case '?': result+="_04"; break;
2784 case '^': result+="_05"; break;
2785 case '%': result+="_06"; break;
2786 case '(': result+="_07"; break;
2787 case ')': result+="_08"; break;
2788 case '+': result+="_09"; break;
2789 case '=': result+="_0a"; break;
2790 case '$': result+="_0b"; break;
2791 case '\\': result+="_0c"; break;
2792 case '@': result+="_0d"; break;
2793 case ']': result+="_0e"; break;
2794 case '[': result+="_0f"; break;
2795 case '#': result+="_0g"; break;
2796 case '"': result+="_0h"; break;
2797 case '~': result+="_0i"; break;
2798 case '\'': result+="_0j"; break;
2799 case ';': result+="_0k"; break;
2800 case '`': result+="_0l"; break;
2801 default:
2802 if (c<0)
2803 {
2804 bool doEscape = true;
2805 if (allowUnicodeNames)
2806 {
2807 int charLen = getUTF8CharNumBytes(c);
2808 if (charLen>0)
2809 {
2810 result+=DString(p-1,charLen);
2811 p+=charLen;
2812 doEscape = false;
2813 }
2814 }
2815 if (doEscape) // not a valid unicode char or escaping needed
2816 {
2817 char ids[5];
2818 unsigned char id = static_cast<unsigned char>(c);
2819 ids[0]='_';
2820 ids[1]='x';
2821 ids[2]=hex[id>>4];
2822 ids[3]=hex[id&0xF];
2823 ids[4]=0;
2824 result+=ids;
2825 }
2826 }
2827 else if (caseSenseNames || !isupper(c))
2828 {
2829 result+=c;
2830 }
2831 else
2832 {
2833 result+='_';
2834 result+=static_cast<char>(tolower(c));
2835 }
2836 break;
2837 }
2838 }
2839 return result;
2840}
bool useCaseSenseNames()
Returns true if the names of the symbols can be case sensitive.
Definition util.cpp:2746

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

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

◆ externalLinkTarget()

DString externalLinkTarget ( const bool parent = false)

Definition at line 4917 of file util.cpp.

4918{
4919 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
4920 if (extLinksInWindow)
4921 return "target=\"_blank\" ";
4922 else if (parent)
4923 return "target=\"_parent\" ";
4924 else
4925 return "";
4926}
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, externalLinkTarget(), and parent().

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

◆ externalRef()

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

Definition at line 4965 of file util.cpp.

4966{
4967 DString result;
4968 if (!ref.empty())
4969 {
4970 auto it = Doxygen::tagDestinationMap.find(ref.str());
4972 {
4973 result = it->second;
4974 size_t l = result.length();
4975 if (!relPath.empty() && l>0 && result.at(0)=='.')
4976 { // relative path -> prepend relPath.
4977 result.prepend(relPath);
4978 l+=relPath.length();
4979 }
4980 if (l>0 && result.at(l-1)!='/') result+='/';
4981 if (!href) result.append("\" ");
4982 }
4983 }
4984 else
4985 {
4986 result = relPath;
4987 }
4988 return result;
4989}
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:675
DString & append(char c)
Definition dstring.h:478
static StringMap tagDestinationMap
Definition doxygen.h:116
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175

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

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

◆ extractBeginRawStringDelimiter()

DString extractBeginRawStringDelimiter ( const char * rawStart)

Definition at line 6004 of file util.cpp.

6005{
6006 DString text=rawStart;
6007 size_t i = text.find('"');
6008 assert(i!=DString::npos);
6009 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
6010}

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

Referenced by extractBeginRawStringDelimiter(), and processMarkup().

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

3448{
3449 AUTO_TRACE("type='{}' pos={} name='{}' lang={}",type,pos,name,lang);
3450 static const reg::Ex re_norm(R"(\a[\w:]*)");
3451 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
3452 const reg::Ex *re = &re_norm;
3453
3454 name.clear();
3455 templSpec.clear();
3456 if (type.empty())
3457 {
3458 AUTO_TRACE_EXIT("empty type");
3459 return -1;
3460 }
3461 size_t typeLen=type.length();
3462 if (typeLen>0)
3463 {
3464 if (lang == SrcLangExt::Fortran)
3465 {
3466 if (type[pos]==',')
3467 {
3468 AUTO_TRACE_EXIT("comma");
3469 return -1;
3470 }
3471 if (!type.lower().startsWith("type"))
3472 {
3473 re = &re_fortran;
3474 }
3475 }
3476 std::string s = type.str();
3477 reg::Iterator it(s,*re,static_cast<int>(pos));
3479
3480 if (it!=end)
3481 {
3482 const auto &match = *it;
3483 size_t i = match.position();
3484 size_t l = match.length();
3485 size_t ts = i+l;
3486 size_t te = ts;
3487 size_t tl = 0;
3488
3489 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') { ts++; tl++; } // skip any whitespace
3490 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
3491 {
3492 // locate end of template
3493 te=ts+1;
3494 int brCount=1;
3495 while (te<typeLen && brCount!=0)
3496 {
3497 if (type[static_cast<uint32_t>(te)]=='<')
3498 {
3499 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
3500 }
3501 if (type[static_cast<uint32_t>(te)]=='>')
3502 {
3503 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
3504 }
3505 te++;
3506 }
3507 }
3508 name = match.str();
3509 if (te>ts)
3510 {
3511 templSpec = DString(type).mid(ts,te-ts);
3512 tl+=te-ts;
3513 pos=static_cast<int>(i+l+tl);
3514 }
3515 else // no template part
3516 {
3517 pos=static_cast<int>(i+l);
3518 }
3519 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=true i=%d\n",
3520 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
3521 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
3522 return static_cast<int>(i);
3523 }
3524 }
3525 pos = static_cast<int>(typeLen);
3526 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=false\n",
3527 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
3528 AUTO_TRACE_EXIT("not found");
3529 return -1;
3530}
void clear()
Definition dstring.h:219
DString lower() const
Definition dstring.h:331
bool startsWith(const char *s) const
Definition dstring.h:589
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:239
#define AUTO_TRACE(...)
Definition docnode.cpp:50
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:52
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:858

References AUTO_TRACE, AUTO_TRACE_EXIT, DString::clear(), DString::DString(), DString::empty(), end(), extractClassNameFromType(), DString::length(), DString::lower(), DString::mid(), DString::startsWith(), and DString::str().

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

◆ extractEndRawStringDelimiter()

DString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6012 of file util.cpp.

6013{
6014 DString text=rawEnd;
6015 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6016}

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

Referenced by extractEndRawStringDelimiter(), and processMarkup().

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

3096{
3097 DString clName=scopeName;
3098 NamespaceDef *nd = nullptr;
3099 size_t i=0;
3100 int p=0;
3101 if (!clName.empty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
3102 { // the whole name is a namespace (and not a class)
3103 namespaceName=nd->name();
3104 className.clear();
3105 goto done;
3106 }
3107 p=static_cast<int>(clName.length())-2;
3108 while (p>=0 && (i=clName.rfind("::",p))!=DString::npos)
3109 // see if the first part is a namespace (and not a class)
3110 {
3111 //printf("Trying %s\n",qPrint(clName.left(i)));
3112 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
3113 {
3114 //printf("found!\n");
3115 namespaceName=nd->name();
3116 className=clName.mid(i+2);
3117 goto done;
3118 }
3119 p=static_cast<int>(i)-2; // try a smaller piece of the scope
3120 }
3121 //printf("not found!\n");
3122
3123 // not found, so we just have to guess.
3124 className=scopeName;
3125 namespaceName.clear();
3126
3127done:
3128 if (className.empty() && !namespaceName.empty() && !allowEmptyClass)
3129 {
3130 // class and namespace with the same name, correct to return the class.
3131 className=namespaceName;
3132 namespaceName.clear();
3133 }
3134 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
3135 // qPrint(className),qPrint(namespaceName));
3136 if (className.endsWith("-p"))
3137 {
3138 className = className.left(className.length()-2);
3139 }
3140 return;
3141}
An abstract interface of a namespace symbol.
ClassDef * getClass(const DString &n)
NamespaceDef * getResolvedNamespace(const DString &name)

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

Referenced by addClassToContext(), addConceptToContext(), extractNamespaceName(), 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 1120 of file util.cpp.

1121{
1122 if (name.empty()) return DString();
1123 bool fileOpened=false;
1124 if (name[0]=='-' && name[1]==0) // read from stdin
1125 {
1126 std::string contents;
1127 std::string line;
1128 while (getline(std::cin,line))
1129 {
1130 contents+=line+'\n';
1131 }
1132 return contents;
1133 }
1134 else // read from file
1135 {
1136 FileInfo fi(name.str());
1137 if (!fi.exists() || !fi.isFile())
1138 {
1139 err("file '{}' not found\n",name);
1140 return "";
1141 }
1142 std::string buf;
1143 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1144 if (fileOpened)
1145 {
1146 addTerminalCharIfMissing(buf,'\n');
1147 return buf;
1148 }
1149 }
1150 if (!fileOpened)
1151 {
1152 err("cannot open file '{}' for reading\n",name);
1153 }
1154 return "";
1155}
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:4742

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

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

◆ fileVisibleInIndex()

bool fileVisibleInIndex ( const FileDef * fd,
bool & genSourceFile )

Definition at line 5274 of file util.cpp.

5275{
5276 bool allExternals = Config_getBool(ALLEXTERNALS);
5277 bool isDocFile = fd->isDocumentationFile();
5278 genSourceFile = !isDocFile && fd->generateSourceFile();
5279 return ( ((allExternals && fd->isLinkable()) ||
5281 ) &&
5282 !isDocFile
5283 );
5284}
virtual bool isLinkable() const =0
virtual bool isLinkableInProject() const =0
virtual bool generateSourceFile() const =0
virtual bool isDocumentationFile() const =0

References Config_getBool, fileVisibleInIndex(), FileDef::generateSourceFile(), FileDef::isDocumentationFile(), Definition::isLinkable(), and Definition::isLinkableInProject().

Referenced by countFiles(), dirHasVisibleChildren(), fileVisibleInIndex(), generateJSTree(), processMarkup(), writeDirHierarchy(), writeDirTreeNode(), and DirDefImpl::writeFileList().

◆ filterTitle()

DString filterTitle ( const DString & title)

Definition at line 4822 of file util.cpp.

4823{
4824 std::string tf;
4825 std::string t = title.str();
4826 static const reg::Ex re(R"(%[a-z_A-Z]+)");
4827 reg::Iterator it(t,re);
4829 size_t p = 0;
4830 for (; it!=end ; ++it)
4831 {
4832 const auto &match = *it;
4833 size_t i = match.position();
4834 size_t l = match.length();
4835 if (i>p) tf+=t.substr(p,i-p);
4836 tf+=match.str().substr(1); // skip %
4837 p=i+l;
4838 }
4839 tf+=t.substr(p);
4840 return tf;
4841}

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

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

◆ findAndRemoveWord()

bool findAndRemoveWord ( DString & sentence,
const char * word )

removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple sequences of spaces.

Example: sentence= cat+ catfish cat cat concat cat, word=cat returns: + catfish concat

Definition at line 4180 of file util.cpp.

4181{
4182 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4183 std::string s = sentence.str();
4184 reg::Iterator it(s,re);
4186 std::string result;
4187 bool found=false;
4188 size_t p=0;
4189 for ( ; it!=end ; ++it)
4190 {
4191 const auto match = *it;
4192 std::string part = match[1].str();
4193 if (part!=word)
4194 {
4195 size_t i = match.position();
4196 size_t l = match.length();
4197 result+=s.substr(p,i-p);
4198 result+=match.str();
4199 p=i+l;
4200 }
4201 else
4202 {
4203 found=true;
4204 size_t i = match[1].position();
4205 size_t l = match[1].length();
4206 result+=s.substr(p,i-p);
4207 p=i+l;
4208 }
4209 }
4210 result+=s.substr(p);
4211 sentence = DString(result).simplifyWhiteSpace();
4212 return found;
4213}
DString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition dstring.cpp:122

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

Referenced by addDirPrefix(), findAndRemoveWord(), and isVarWithConstructor().

◆ findExampleFilePath()

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

Definition at line 2518 of file util.cpp.

2519{
2520 ambig=false;
2521 DString result;
2522 bool found=false;
2523 if (!found)
2524 {
2525 FileInfo fi(file.str());
2526 if (fi.exists())
2527 {
2528 result=fi.absFilePath();
2529 found=true;
2530 }
2531 }
2532 if (!found)
2533 {
2534 StringVector examplePathList = Config_getList(EXAMPLE_PATH);
2535 for (const auto &s : examplePathList)
2536 {
2537 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2538 FileInfo fi(absFileName);
2539 if (fi.exists())
2540 {
2541 result=fi.absFilePath();
2542 found=true;
2543 }
2544 }
2545 }
2546
2547 if (!found)
2548 {
2549 // as a fallback we also look in the exampleNameDict
2551 if (fd && !ambig)
2552 {
2553 result=fd->absFilePath();
2554 }
2555 }
2556 return result;
2557}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
A model of a file symbol.
Definition filedef.h:99
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:36
DString pathSeparator()
Definition portable.cpp:374

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

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

◆ getDefs()

GetDefResult getDefs ( const GetDefInput & input)

Definition at line 1933 of file util.cpp.

1934{
1935 GetDefResult result;
1936 if (input.memberName.empty()) return result;
1937 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
1938 input.scopeName,input.memberName,input.forceEmptyScope);
1939
1940 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
1941 const Definition *scope = Doxygen::globalScope;
1942 SymbolResolver resolver;
1943 if (input.currentFile) resolver.setFileScope(input.currentFile);
1944 if (!input.scopeName.empty() && !input.forceEmptyScope)
1945 {
1946 scope = resolver.resolveSymbol(scope,input.scopeName);
1947 }
1948 if (scope==Doxygen::globalScope)
1949 {
1950 scope = input.currentFile;
1951 }
1952 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
1953 //
1954 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
1955 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():DString()));
1956 if (symbol && symbol->definitionType()==Definition::TypeMember)
1957 {
1958 result.md = toMemberDef(symbol);
1959 result.cd = result.md->getClassDef();
1960 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
1961 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
1962 result.gd = result.md->getGroupDef();
1963 result.found = true;
1964 }
1965 else if (symbol && symbol->definitionType()==Definition::TypeClass)
1966 {
1967 result.cd = toClassDef(symbol);
1968 result.found = true;
1969 }
1970 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
1971 {
1972 result.nd = toNamespaceDef(symbol);
1973 result.found = true;
1974 }
1975 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
1976 {
1977 result.cnd = toConceptDef(symbol);
1978 result.found = true;
1979 }
1980 else if (symbol && symbol->definitionType()==Definition::TypeModule)
1981 {
1982 result.modd = toModuleDef(symbol);
1983 result.found = true;
1984 }
1985 return result;
1986}
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:121
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:98
const FileDef * currentFile
Definition util.h:99
bool insideCode
Definition util.h:101
DString args
Definition util.h:97
DString memberName
Definition util.h:96
bool checkCV
Definition util.h:100
DString scopeName
Definition util.h:95
const MemberDef * md
Definition util.h:108
const ConceptDef * cnd
Definition util.h:113
const FileDef * fd
Definition util.h:110
const ModuleDef * modd
Definition util.h:114
const GroupDef * gd
Definition util.h:112
bool found
Definition util.h:107
const ClassDef * cd
Definition util.h:109
const NamespaceDef * nd
Definition util.h:111

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(), getDefs(), 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(), getDefs(), getLinkInScope(), getLinkInScope(), linkifyText(), and resolveRef().

◆ getDotImageExtension()

DString getDotImageExtension ( )

Definition at line 5498 of file util.cpp.

5499{
5500 DString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
5501 size_t i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
5502 return i==DString::npos ? imgExt : imgExt.left(i);
5503}
#define Config_getEnumAsString(name)
Definition config.h:36

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

Referenced by MermaidManager::convertToImageFormat(), RTFGenerator::endCallGraph(), RTFGenerator::endDirDepGraph(), RTFGenerator::endDotGraph(), RTFGenerator::endInclDepGraph(), DotGraph::generateCode(), getDotImageExtension(), DotGraph::imgName(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), processMarkup(), 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().

◆ getEncoding()

DString getEncoding ( const FileInfo & fi)

Definition at line 4903 of file util.cpp.

4904{
4905 InputFileEncoding elem;
4906 auto getter = [](const InputFileEncoding &e) -> DString { return e.pattern; };
4907 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
4908 {
4909 return elem.encoding;
4910 }
4911 else // fall back to default encoding
4912 {
4913 return Config_getString(INPUT_ENCODING);
4914 }
4915}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:138
#define Config_getString(name)
Definition config.h:32
DString encoding
Definition doxygen.h:70
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
Definition util.cpp:4846

References Config_getString, InputFileEncoding::encoding, genericPatternMatch(), getEncoding(), and Doxygen::inputFileEncodingList.

Referenced by getEncoding(), processMarkup(), 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 1052 of file util.cpp.

1053{
1054 // sanity check
1055 if (name.empty()) return "";
1056
1057 StringVector filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1058 StringVector filterList = Config_getList(FILTER_PATTERNS);
1059
1060 DString filterName;
1061 bool found=false;
1062 if (isSourceCode && !filterSrcList.empty())
1063 { // first look for source filter pattern list
1064 filterName = getFilterFromList(name,filterSrcList,found);
1065 }
1066 if (!found && filterName.empty())
1067 { // then look for filter pattern list
1068 filterName = getFilterFromList(name,filterList,found);
1069 }
1070 if (!found)
1071 { // then use the generic input filter
1072 return Config_getString(INPUT_FILTER);
1073 }
1074 else
1075 {
1076 /* remove surrounding double quotes */
1077 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1078 {
1079 filterName = filterName.mid(1,filterName.length()-2);
1080 }
1081 return filterName;
1082 }
1083}
static DString getFilterFromList(const DString &name, const StringVector &filterList, bool &found)
Definition util.cpp:1017

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

Referenced by FilterCache::getFileContents(), getFileFilter(), 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 4422 of file util.cpp.

4423{
4424 // try the extension
4425 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
4426 if (lang == SrcLangExt::Unknown)
4427 {
4428 // try the language names
4429 DString langName = fileName.lower();
4430 if (langName.at(0)=='.') langName = langName.mid(1);
4431 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
4432 [&langName](const auto &info) { return info.langName==langName; });
4433 if (it != g_lang2extMap.end())
4434 {
4435 lang = it->parserId;
4436 fileName = it->defExt;
4437 }
4438 else // default to C++
4439 {
4440 return SrcLangExt::Cpp;
4441 }
4442 }
4443 return lang;
4444}
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
Definition util.cpp:4404
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:4275

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

Referenced by addDirPrefix(), getLanguageFromCodeLang(), 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 4404 of file util.cpp.

4405{
4406 FileInfo fi(fileName.str());
4407 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
4408 DString extName = DString(fi.extension(false)).lower();
4409 if (extName.empty()) extName=".no_extension";
4410 if (extName.at(0)!='.') extName.prepend(".");
4411 auto it = g_extLookup.find(extName.str());
4412 if (it!=g_extLookup.end()) // listed extension
4413 {
4414 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
4415 return it->second;
4416 }
4417 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
4418 return defLang; // not listed => assume C-ish language.
4419}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:4265

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

Referenced by MemberDefImpl::_writeMultiLineInitializer(), addDirPrefix(), ClassDefImpl::ClassDefImpl(), convertCppComments(), DocRef::DocRef(), FileDefImpl::FileDefImpl(), generateExampleDocs(), getLanguageFromCodeLang(), getLanguageFromFileName(), 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 )

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

2719{
2720 if (name.empty()) return 0;
2721 int result=0;
2722 StringVector sl = Config_getList(IGNORE_PREFIX);
2723 for (const auto &s : sl)
2724 {
2725 const char *ps=s.c_str();
2726 const char *pd=name.data();
2727 int i=0;
2728 while (*ps!=0 && *pd!=0 && *ps==*pd)
2729 {
2730 ps++;
2731 pd++;
2732 i++;
2733 }
2734 if (*ps==0 && *pd!=0)
2735 {
2736 result=i;
2737 break;
2738 }
2739 }
2740 if (result<static_cast<int>(name.length())-1 && name.at(result)=='[') result++; // for e.g. [union] return u
2741 return result;
2742}

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

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

◆ getProjectId()

DString getProjectId ( )

Definition at line 5887 of file util.cpp.

5888{
5889 DString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
5890 if (projectCookie.empty()) return DString();
5891 return md5str(projectCookie.view())+"_";
5892}

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

Referenced by generateJSNavTree(), getProjectId(), HtmlGenerator::init(), processMarkup(), 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 3865 of file util.cpp.

3866{
3867 int sl=static_cast<int>(s.length());
3868 int sp=p;
3869 int count=0;
3870 bool done=false;
3871 if (sp>=sl) return -1;
3872 while (sp<sl)
3873 {
3874 char c=s.at(sp);
3875 if (c==':')
3876 {
3877 sp++;
3878 p++;
3879 }
3880 else
3881 {
3882 break;
3883 }
3884 }
3885 while (sp<sl)
3886 {
3887 char c=s.at(sp);
3888 switch (c)
3889 {
3890 case ':': // found next part
3891 goto found;
3892 case '<': // skip template specifier
3893 count=1;sp++;
3894 done=false;
3895 while (sp<sl && !done)
3896 {
3897 // TODO: deal with << and >> operators!
3898 c=s.at(sp++);
3899 switch(c)
3900 {
3901 case '<': count++; break;
3902 case '>': count--; if (count==0) done=true; break;
3903 default: break;
3904 }
3905 }
3906 break;
3907 default:
3908 sp++;
3909 break;
3910 }
3911 }
3912found:
3913 *l=sp-p;
3914 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
3915 return p;
3916}

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

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

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 4331 of file util.cpp.

4332{
4333 // NOTE: when adding an extension, also add the extension in config.xml
4334 // extension parser id
4335 updateLanguageMapping(".dox", "c");
4336 updateLanguageMapping(".txt", "c"); // see bug 760836
4337 updateLanguageMapping(".doc", "c");
4338 updateLanguageMapping(".c", "c");
4339 updateLanguageMapping(".C", "c");
4340 updateLanguageMapping(".cc", "c");
4341 updateLanguageMapping(".CC", "c");
4342 updateLanguageMapping(".cxx", "c");
4343 updateLanguageMapping(".cpp", "c");
4344 updateLanguageMapping(".c++", "c");
4345 updateLanguageMapping(".cxxm", "c"); // C++20 modules
4346 updateLanguageMapping(".cppm", "c"); // C++20 modules
4347 updateLanguageMapping(".ccm", "c"); // C++20 modules
4348 updateLanguageMapping(".c++m", "c"); // C++20 modules
4349 updateLanguageMapping(".ii", "c");
4350 updateLanguageMapping(".ixx", "c");
4351 updateLanguageMapping(".ipp", "c");
4352 updateLanguageMapping(".i++", "c");
4353 updateLanguageMapping(".inl", "c");
4354 updateLanguageMapping(".h", "c");
4355 updateLanguageMapping(".H", "c");
4356 updateLanguageMapping(".hh", "c");
4357 updateLanguageMapping(".HH", "c");
4358 updateLanguageMapping(".hxx", "c");
4359 updateLanguageMapping(".hpp", "c");
4360 updateLanguageMapping(".h++", "c");
4361 updateLanguageMapping(".idl", "idl");
4362 updateLanguageMapping(".ddl", "idl");
4363 updateLanguageMapping(".odl", "idl");
4364 updateLanguageMapping(".java", "java");
4365 //updateLanguageMapping(".as", "javascript"); // not officially supported
4366 //updateLanguageMapping(".js", "javascript"); // not officially supported
4367 updateLanguageMapping(".cs", "csharp");
4368 updateLanguageMapping(".d", "d");
4369 updateLanguageMapping(".php", "php");
4370 updateLanguageMapping(".php4", "php");
4371 updateLanguageMapping(".php5", "php");
4372 updateLanguageMapping(".inc", "php");
4373 updateLanguageMapping(".phtml", "php");
4374 updateLanguageMapping(".m", "objective-c");
4375 updateLanguageMapping(".M", "objective-c");
4376 updateLanguageMapping(".mm", "c"); // see bug746361
4377 updateLanguageMapping(".py", "python");
4378 updateLanguageMapping(".pyw", "python");
4379 updateLanguageMapping(".f", "fortran");
4380 updateLanguageMapping(".for", "fortran");
4381 updateLanguageMapping(".f90", "fortran");
4382 updateLanguageMapping(".f95", "fortran");
4383 updateLanguageMapping(".f03", "fortran");
4384 updateLanguageMapping(".f08", "fortran");
4385 updateLanguageMapping(".f18", "fortran");
4386 updateLanguageMapping(".vhd", "vhdl");
4387 updateLanguageMapping(".vhdl", "vhdl");
4388 updateLanguageMapping(".ucf", "vhdl");
4389 updateLanguageMapping(".qsf", "vhdl");
4390 updateLanguageMapping(".md", "md");
4391 updateLanguageMapping(".markdown", "md");
4392 updateLanguageMapping(".ice", "slice");
4393 updateLanguageMapping(".l", "lex");
4394 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
4395 // in the lex scanning to cpp
4396}

References initDefaultExtensionMapping(), and updateLanguageMapping().

Referenced by addDirPrefix(), initDefaultExtensionMapping(), and 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 5399 of file util.cpp.

5400{
5401 DString paramDocs;
5402 if (al.hasDocumentation(true))
5403 {
5404 for (const Argument &a : al)
5405 {
5406 if (a.hasDocumentation(true))
5407 {
5408 DString docsWithoutDir = a.docs;
5409 DString direction = extractDirection(docsWithoutDir);
5410 DString name = a.name;
5411 if (name.empty())
5412 {
5413 name = "-";
5414 }
5415 paramDocs+=" \\ilinebr @param"+direction+" "+name+" "+docsWithoutDir;
5416 }
5417 }
5418 }
5419 return paramDocs;
5420}
bool hasDocumentation(bool allowEmptyNames=false) const
Definition arguments.cpp:22
static DString extractDirection(DString &docs)
Strip the direction part from docs and return it as a string in canonical form.
Definition util.cpp:5363

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

Referenced by inlineArgListToDoc(), 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 864 of file util.cpp.

865{
866 DString paramDocs;
868 {
869 for (const Argument &a : al)
870 {
871 if (!a.docs.empty())
872 {
873 if (!a.name.empty())
874 {
875 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
876 }
877 else if (!a.type.empty())
878 {
879 DString type = a.type;
880 type.stripPrefix("class ");
881 type.stripPrefix("typename ");
882 type = type.stripWhiteSpace();
883 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
884 }
885 }
886 }
887 }
888 return paramDocs;
889}
bool hasTemplateDocumentation() const
Definition arguments.cpp:30
bool stripPrefix(const DString &prefix)
Definition dstring.h:295

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

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

◆ insertTemplateSpecifierInScope()

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

Definition at line 3143 of file util.cpp.

3144{
3145 DString result=scope;
3146 if (!templ.empty() && scope.find('<')==DString::npos)
3147 {
3148 size_t si=0, pi=0;
3149 ClassDef *cd=nullptr;
3150 while (
3151 (si=scope.find("::",pi))!=DString::npos && !getClass(scope.left(si)+templ) &&
3152 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3153 )
3154 {
3155 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3156 pi=si+2;
3157 }
3158 if (si==DString::npos) // not nested => append template specifier
3159 {
3160 result+=templ;
3161 }
3162 else // nested => insert template specifier before after first class name
3163 {
3164 result=scope.left(si) + templ + scope.mid(si);
3165 }
3166 }
3167 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3168 // qPrint(scope),qPrint(templ),qPrint(result));
3169 return result;
3170}
bool empty() const
Definition arguments.h:99
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.

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

Referenced by DotClassGraph::addClass(), generateXMLForClass(), insertTemplateSpecifierInScope(), 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 5097 of file util.cpp.

5098{
5099 static const std::unordered_set<std::string> schemes = {
5100 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
5101 };
5102 DString loc_url = url.stripWhiteSpace();
5103 size_t colonPos = loc_url.find(':');
5104 return colonPos!=DString::npos && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
5105}

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

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

◆ leftScopeMatch()

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

Definition at line 772 of file util.cpp.

773{
774 size_t sl=scope.length();
775 size_t nl=name.length();
776 return (name==scope || // equal
777 (name.left(sl)==scope && // substring
778 nl>sl+1 && name.at(sl)==':' && name.at(sl+1)==':' // scope
779 )
780 );
781}

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

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

◆ lineBlock()

int lineBlock ( const DString & text,
const DString & marker )

Returns the line number of the line following the line with the marker.

See also
routine extractBlock

Definition at line 5060 of file util.cpp.

5061{
5062 int result = 1;
5063
5064 // find the character positions of the first marker
5065 size_t m1 = text.find(marker);
5066 if (m1==DString::npos) return result;
5067
5068 // find start line positions for the markers
5069 bool found=false;
5070 size_t p=0, i=0;
5071 while (!found && (i=text.find('\n',p))!=DString::npos)
5072 {
5073 found = (p<=m1 && m1<i); // found the line with the start marker
5074 p=i+1;
5075 result++;
5076 }
5077 return result;
5078}

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

Referenced by lineBlock(), readIncludeFile(), and recodeString().

◆ linkToText()

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

Definition at line 2332 of file util.cpp.

2333{
2334 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2335 DString result=link;
2336 if (!result.empty())
2337 {
2338 // replace # by ::
2339 result=substitute(result,"#","::");
2340 // replace . by ::
2341 if (!ignoreDots && result.find('<')==DString::npos) result=substitute(result,".","::",3);
2342 // strip leading :: prefix if present
2343 if (result.at(0)==':' && result.at(1)==':')
2344 {
2345 result=result.mid(2);
2346 }
2348 if (sep!="::")
2349 {
2350 result=substitute(result,"::",sep);
2351 }
2352 }
2353 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2354 return result;
2355}
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:480
DString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Definition util.cpp:5080

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

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

◆ mainPageHasTitle()

bool mainPageHasTitle ( )

Definition at line 5493 of file util.cpp.

5494{
5495 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
5496}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100

References Doxygen::mainPage, and mainPageHasTitle().

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

◆ makeBaseName()

◆ mangleCSharpGenericName()

DString mangleCSharpGenericName ( const DString & name)

Definition at line 5984 of file util.cpp.

5985{
5986 if (size_t idx = name.find('<'); idx!=DString::npos)
5987 {
5988 return name.left(idx)+"-"+DString().setNum(name.contains(",")+1)+"-g";
5989 }
5990 return name;
5991}
DString & setNum(short n)
Definition dstring.h:541
int contains(char c, bool cs=true) const
Definition dstring.cpp:80

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

Referenced by addClassToContext(), addEnumValuesToEnums(), addVariable(), buildFunctionList(), extractClassName(), findClassRelation(), findEnums(), mangleCSharpGenericName(), processMarkup(), 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 1656 of file util.cpp.

1659{
1660 ASSERT(srcScope!=nullptr && dstScope!=nullptr);
1661
1662 AUTO_TRACE("srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
1663 srcScope->name(),dstScope->name(),srcAl?argListToString(*srcAl):"",dstAl?argListToString(*dstAl):"",checkCV,lang);
1664
1665 if (srcAl==nullptr || dstAl==nullptr)
1666 {
1667 bool match = srcAl==dstAl;
1668 if (match)
1669 {
1670 MATCH
1671 return true;
1672 }
1673 else
1674 {
1675 NOMATCH
1676 return false;
1677 }
1678 }
1679
1680 // handle special case with void argument
1681 if ( srcAl->empty() && dstAl->size()==1 && dstAl->front().type=="void" )
1682 { // special case for finding match between func() and func(void)
1683 Argument a;
1684 a.type = "void";
1685 const_cast<ArgumentList*>(srcAl)->push_back(a);
1686 MATCH
1687 return true;
1688 }
1689 if ( dstAl->empty() && srcAl->size()==1 && srcAl->front().type=="void" )
1690 { // special case for finding match between func(void) and func()
1691 Argument a;
1692 a.type = "void";
1693 const_cast<ArgumentList*>(dstAl)->push_back(a);
1694 MATCH
1695 return true;
1696 }
1697
1698 if (srcAl->size() != dstAl->size())
1699 {
1700 NOMATCH
1701 return false; // different number of arguments -> no match
1702 }
1703
1704 if (checkCV)
1705 {
1706 if (srcAl->constSpecifier() != dstAl->constSpecifier())
1707 {
1708 NOMATCH
1709 return false; // one member is const, the other not -> no match
1710 }
1711 if (srcAl->volatileSpecifier() != dstAl->volatileSpecifier())
1712 {
1713 NOMATCH
1714 return false; // one member is volatile, the other not -> no match
1715 }
1716 }
1717
1718 if (srcAl->refQualifier() != dstAl->refQualifier())
1719 {
1720 NOMATCH
1721 return false; // one member is has a different ref-qualifier than the other
1722 }
1723
1724 if (srcReturnType=="auto" && dstReturnType=="auto" && srcAl->trailingReturnType()!=dstAl->trailingReturnType())
1725 {
1726 NOMATCH
1727 return false; // one member is has a different return type than the other
1728 }
1729
1730 // so far the argument list could match, so we need to compare the types of
1731 // all arguments.
1732 auto srcIt = srcAl->begin();
1733 auto dstIt = dstAl->begin();
1734 for (;srcIt!=srcAl->end() && dstIt!=dstAl->end();++srcIt,++dstIt)
1735 {
1736 Argument &srcA = const_cast<Argument&>(*srcIt);
1737 Argument &dstA = const_cast<Argument&>(*dstIt);
1738 if (!matchArgument2(srcScope,srcFileScope,srcA,
1739 dstScope,dstFileScope,dstA,
1740 lang)
1741 )
1742 {
1743 NOMATCH
1744 return false;
1745 }
1746 }
1747 MATCH
1748 return true; // all arguments match
1749}
This class represents an function or template argument list.
Definition arguments.h:65
Argument & front()
Definition arguments.h:105
size_t size() const
Definition arguments.h:100
#define ASSERT(x)
Definition dstring.h:29
#define MATCH
Definition util.cpp:1555
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:891
#define NOMATCH
Definition util.cpp:1556
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
Definition util.cpp:1590

References argListToString(), ASSERT, AUTO_TRACE, ArgumentList::begin(), ArgumentList::constSpecifier(), ArgumentList::empty(), ArgumentList::end(), ArgumentList::front(), MATCH, matchArgument2(), matchArguments2(), 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(), matchArguments2(), 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 1900 of file util.cpp.

1901{
1902 AUTO_TRACE("srcAl={} dstAl={}",argListToString(srcAl),argListToString(dstAl));
1903 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
1904 {
1905 AUTO_TRACE_EXIT("different number of parameters");
1906 return false;
1907 }
1908 auto isUnconstraintTemplate = [](const DString &type)
1909 {
1910 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
1911 };
1912 auto srcIt = srcAl.begin();
1913 auto dstIt = dstAl.begin();
1914 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
1915 {
1916 const Argument &srcA = *srcIt;
1917 const Argument &dstA = *dstIt;
1918 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
1919 {
1920 AUTO_TRACE_EXIT("different constraints");
1921 return false;
1922 }
1923 ++srcIt;
1924 ++dstIt;
1925 }
1926 AUTO_TRACE_EXIT("same");
1927 // no overload with respect to the template parameters
1928 return true;
1929}

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

Referenced by buildFunctionList(), and matchTemplateArguments().

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

1757{
1758 AUTO_TRACE("srcAl='{}',dstAl='{}',forceNameOverwrite={}",
1759 qPrint(argListToString(srcAl)),qPrint(argListToString(dstAl)),forceNameOverwrite);
1760
1761 if (srcAl.size()!=dstAl.size())
1762 {
1763 return; // invalid argument lists -> do not merge
1764 }
1765
1766 auto srcIt=srcAl.begin();
1767 auto dstIt=dstAl.begin();
1768 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
1769 {
1770 Argument &srcA = *srcIt;
1771 Argument &dstA = *dstIt;
1772
1773 AUTO_TRACE_ADD("before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1774 srcA.type,srcA.name,srcA.defval,
1775 dstA.type,dstA.name,dstA.defval);
1776 if (srcA.defval.empty() && !dstA.defval.empty())
1777 {
1778 //printf("Defval changing '%s'->'%s'\n",qPrint(srcA.defval),qPrint(dstA.defval));
1779 srcA.defval=dstA.defval;
1780 }
1781 else if (!srcA.defval.empty() && dstA.defval.empty())
1782 {
1783 //printf("Defval changing '%s'->'%s'\n",qPrint(dstA.defval),qPrint(srcA.defval));
1784 dstA.defval=srcA.defval;
1785 }
1786
1787 // fix wrongly detected const or volatile specifiers before merging.
1788 // example: "const A *const" is detected as type="const A *" name="const"
1789 if (srcA.name=="const" || srcA.name=="volatile")
1790 {
1791 srcA.type+=" "+srcA.name;
1792 srcA.name.clear();
1793 }
1794 if (dstA.name=="const" || dstA.name=="volatile")
1795 {
1796 dstA.type+=" "+dstA.name;
1797 dstA.name.clear();
1798 }
1799
1800 if (srcA.type==dstA.type)
1801 {
1802 //printf("1. merging %s:%s <-> %s:%s\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
1803 if (srcA.name.empty() && !dstA.name.empty())
1804 {
1805 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
1806 //printf("name: '%s':='%s'\n",qPrint(srcA.name),qPrint(dstA.name));
1807 srcA.type = dstA.type;
1808 srcA.name = dstA.name;
1809 }
1810 else if (!srcA.name.empty() && dstA.name.empty())
1811 {
1812 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
1813 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1814 dstA.type = srcA.type;
1815 dstA.name = srcA.name;
1816 }
1817 else if (!srcA.name.empty() && !dstA.name.empty())
1818 {
1819 //printf("srcA.name=%s dstA.name=%s\n",qPrint(srcA.name),qPrint(dstA.name));
1820 if (forceNameOverwrite)
1821 {
1822 srcA.name = dstA.name;
1823 }
1824 else
1825 {
1826 if (srcA.docs.empty() && !dstA.docs.empty())
1827 {
1828 srcA.name = dstA.name;
1829 }
1830 else if (!srcA.docs.empty() && dstA.docs.empty())
1831 {
1832 dstA.name = srcA.name;
1833 }
1834 }
1835 }
1836 }
1837 else
1838 {
1839 //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
1840 srcA.type=srcA.type.stripWhiteSpace();
1841 dstA.type=dstA.type.stripWhiteSpace();
1842 if (srcA.type+" "+srcA.name==dstA.type) // "unsigned long:int" <-> "unsigned long int:bla"
1843 {
1844 srcA.type+=" "+srcA.name;
1845 srcA.name=dstA.name;
1846 }
1847 else if (dstA.type+" "+dstA.name==srcA.type) // "unsigned long int bla" <-> "unsigned long int"
1848 {
1849 dstA.type+=" "+dstA.name;
1850 dstA.name=srcA.name;
1851 }
1852 else if (srcA.name.empty() && !dstA.name.empty())
1853 {
1854 srcA.name = dstA.name;
1855 }
1856 else if (dstA.name.empty() && !srcA.name.empty())
1857 {
1858 dstA.name = srcA.name;
1859 }
1860 }
1861 size_t i1=srcA.type.find("::"),
1862 i2=dstA.type.find("::"),
1863 j1=srcA.type.length()-i1-2,
1864 j2=dstA.type.length()-i2-2;
1865 if (i1!=DString::npos && i2==DString::npos && srcA.type.right(j1)==dstA.type)
1866 {
1867 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
1868 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1869 dstA.type = srcA.type.left(i1+2)+dstA.type;
1870 dstA.name = srcA.name;
1871 }
1872 else if (i1==DString::npos && i2!=DString::npos && dstA.type.right(j2)==srcA.type)
1873 {
1874 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
1875 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
1876 srcA.type = dstA.type.left(i2+2)+srcA.type;
1877 srcA.name = dstA.name;
1878 }
1879 if (srcA.docs.empty() && !dstA.docs.empty())
1880 {
1881 srcA.docs = dstA.docs;
1882 }
1883 else if (dstA.docs.empty() && !srcA.docs.empty())
1884 {
1885 dstA.docs = srcA.docs;
1886 }
1887 //printf("Merge argument '%s|%s' '%s|%s'\n",
1888 // qPrint(srcA.type), qPrint(srcA.name),
1889 // qPrint(dstA.type), qPrint(dstA.name));
1890 ++srcIt;
1891 ++dstIt;
1892 AUTO_TRACE_ADD("after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1893 srcA.type,srcA.name,srcA.defval,
1894 dstA.type,dstA.name,dstA.defval);
1895 }
1896}
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:51
DString docs
Definition arguments.h:47

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(), mergeArguments(), Argument::name, DString::npos, qPrint(), DString::right(), ArgumentList::size(), DString::stripWhiteSpace(), and Argument::type.

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

◆ mergeMemberOverrideOptions()

void mergeMemberOverrideOptions ( MemberDefMutable * md1,
MemberDefMutable * md2 )

Definition at line 5932 of file util.cpp.

5933{
5934 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
5935 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
5936 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
5937 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
5938
5939 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
5940 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
5941
5942 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
5943 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
5944 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
5945 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
5946
5947 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
5948 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
5949}
virtual bool hasReferencesRelation() const =0
virtual bool hasCallGraph() const =0
virtual bool hasInlineSource() const =0
virtual bool hasEnumValues() const =0
virtual bool hasCallerGraph() const =0
virtual bool hasReferencedByRelation() const =0
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

References Config_getBool, MemberDef::hasCallerGraph(), MemberDef::hasCallGraph(), MemberDef::hasEnumValues(), MemberDef::hasInlineSource(), MemberDef::hasReferencedByRelation(), MemberDef::hasReferencesRelation(), mergeMemberOverrideOptions(), MemberDefMutable::overrideCallerGraph(), MemberDefMutable::overrideCallGraph(), MemberDefMutable::overrideEnumValues(), MemberDefMutable::overrideInlineSource(), MemberDefMutable::overrideReferencedByRelation(), and MemberDefMutable::overrideReferencesRelation().

Referenced by combineDeclarationAndDefinition(), findFriends(), mergeMemberOverrideOptions(), and processMarkup().

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

3821{
3822 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
3823 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
3824 if (leftScopeMatch(leftScope,rightScope))
3825 {
3826 AUTO_TRACE_EXIT("case1={}",rightScope);
3827 return rightScope;
3828 }
3829 DString result;
3830 size_t i=0,p=leftScope.length();
3831
3832 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
3833 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
3834 bool found=false;
3835 while ((i=leftScope.rfind("::",p))!=DString::npos && i>0)
3836 {
3837 if (leftScopeMatch(rightScope,leftScope.mid(i+2)))
3838 {
3839 result = leftScope.left(i+2)+rightScope;
3840 found=true;
3841 }
3842 p=i-1;
3843 }
3844 if (found)
3845 {
3846 AUTO_TRACE_EXIT("case2={}",result);
3847 return result;
3848 }
3849
3850 // case leftScope=="A" rightScope=="B" => result = "A::B"
3851 result=leftScope;
3852 if (!result.empty() && !rightScope.empty()) result+="::";
3853 result+=rightScope;
3854 AUTO_TRACE_EXIT("case3={}",result);
3855 return result;
3856}
bool leftScopeMatch(const DString &scope, const DString &name)
Definition util.cpp:772

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

Referenced by addEnumValuesToEnums(), addVariable(), findEnums(), findMember(), mergeScopes(), 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 3532 of file util.cpp.

3536{
3537 // skip until <
3538 size_t p=name.find('<');
3539 if (p==DString::npos) return name;
3540 p++;
3541 DString result = name.left(p);
3542
3543 std::string s = name.mid(p).str();
3544 static const reg::Ex re(R"([\a:][\w:]*)");
3545 reg::Iterator it(s,re);
3547 size_t pi=0;
3548 // for each identifier in the template part (e.g. B<T> -> T)
3549 for (; it!=end ; ++it)
3550 {
3551 const auto &match = *it;
3552 size_t i = match.position();
3553 size_t l = match.length();
3554 result += s.substr(pi,i-pi);
3555 DString n(match.str());
3556 bool found=false;
3557 for (const Argument &formArg : formalArgs)
3558 {
3559 if (formArg.name == n)
3560 {
3561 found=true;
3562 break;
3563 }
3564 }
3565 if (!found)
3566 {
3567 // try to resolve the type
3568 SymbolResolver resolver;
3569 const ClassDef *cd = resolver.resolveClass(context,n);
3570 if (cd)
3571 {
3572 result+=cd->name();
3573 }
3574 else
3575 {
3576 result+=n;
3577 }
3578 }
3579 else
3580 {
3581 result+=n;
3582 }
3583 pi=i+l;
3584 }
3585 result+=s.substr(pi);
3586 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
3587 return removeRedundantWhiteSpace(result);
3588}
DString substr(size_t pos=0, size_t count=npos) const
Returns a substring of length count starting at pos.
Definition dstring.h:228
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(), normalizeNonTemplateArgumentsInString(), DString::npos, removeRedundantWhiteSpace(), SymbolResolver::resolveClass(), DString::str(), and DString::substr().

Referenced by findUsedClassesForClass(), and normalizeNonTemplateArgumentsInString().

◆ openOutputFile()

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

Definition at line 5505 of file util.cpp.

5506{
5507 assert(!f.is_open());
5508 bool fileOpened=false;
5509 bool writeToStdout=outFile=="-";
5510 if (writeToStdout) // write to stdout
5511 {
5512 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
5513 fileOpened = true;
5514 }
5515 else // write to file
5516 {
5517 FileInfo fi(outFile.str());
5518 if (fi.exists()) // create a backup
5519 {
5520 Dir dir;
5521 FileInfo backup(fi.filePath()+".bak");
5522 if (backup.exists()) // remove existing backup
5523 dir.remove(backup.filePath());
5524 dir.rename(fi.filePath(),fi.filePath()+".bak");
5525 }
5526 f = Portable::openOutputStream(outFile);
5527 fileOpened = f.is_open();
5528 }
5529 return fileOpened;
5530}
Class representing a directory in the file system.
Definition dir.h:75
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:648

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

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

◆ parseCommentAsHtml()

DString parseCommentAsHtml ( const Definition * scope,
const MemberDef * member,
const DString & doc,
const DString & fileName,
int lineNr )

Definition at line 4617 of file util.cpp.

4618{
4619 std::lock_guard lock(g_docCacheMutex);
4620 auto it = g_docCache.find(doc.str());
4621 if (it != g_docCache.end())
4622 {
4623 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
4624 return it->second;
4625 }
4626 auto parser { createDocParser() };
4627 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
4628 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
4629 DString result;
4630 if (astImpl)
4631 {
4632 TextStream t;
4633 OutputCodeList codeList;
4634 codeList.add<HtmlCodeGenerator>(&t);
4635 HtmlDocVisitor visitor(t,codeList,scope,fileName);
4636 std::visit(visitor,astImpl->root);
4637 result = t.str();
4638 }
4639 else // fallback, should not happen
4640 {
4641 result = filterTitle(doc);
4642 }
4643 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
4644 g_docCache.insert(std::make_pair(doc.str(),result));
4645 return result;
4646}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1471
Generator for HTML code fragments.
Definition htmlgen.h:26
Concrete visitor implementation for HTML output.
Class representing a list of different code generators.
Definition outputlist.h:166
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:196
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
IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf, const DString &fileName, int lineNr, const DString &input)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:56
DString filterTitle(const DString &title)
Definition util.cpp:4822
static std::unordered_map< std::string, DString > g_docCache
Definition util.cpp:4615
static std::mutex g_docCacheMutex
Definition util.cpp:4614

References OutputCodeList::add(), createDocParser(), filterTitle(), g_docCache, g_docCacheMutex, parseCommentAsHtml(), DString::str(), TextStream::str(), and validatingParseTitle().

Referenced by addDirPrefix(), PageDefImpl::addSectionsToIndex(), SearchTerm::makeTitle(), DefinitionImpl::navigationPathAsString(), parseCommentAsHtml(), and writeJavasScriptSearchDataPage().

◆ parseCommentAsText()

DString parseCommentAsText ( const Definition * scope,
const MemberDef * member,
const DString & doc,
const DString & fileName,
int lineNr )

Definition at line 4561 of file util.cpp.

4563{
4564 if (doc.empty()) return "";
4565 //printf("parseCommentAsText(%s)\n",qPrint(doc));
4566 TextStream t;
4567 auto parser { createDocParser() };
4568 auto ast { validatingParseDoc(*parser.get(),
4569 fileName,
4570 lineNr,
4571 scope,
4572 md,
4573 doc,
4574 DocOptions()
4575 .setAutolinkSupport(false))
4576 };
4577 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
4578 if (astImpl)
4579 {
4580 TextDocVisitor visitor(t);
4581 std::visit(visitor,astImpl->root);
4582 }
4584 int i=0;
4585 int charCnt=0;
4586 int l=static_cast<int>(result.length());
4587 while ((i=nextUTF8CharPosition(result,l,i))<l)
4588 {
4589 charCnt++;
4590 if (charCnt>=80) break;
4591 }
4592 if (charCnt>=80) // try to truncate the string
4593 {
4594 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
4595 {
4596 charCnt++;
4597 if (result.at(i)==',' ||
4598 result.at(i)=='.' ||
4599 result.at(i)=='!' ||
4600 result.at(i)=='?' ||
4601 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
4602 {
4603 i++; // we want to be "behind" last inspected character
4604 break;
4605 }
4606 }
4607 }
4608 if ( i < l) result=result.left(i)+"...";
4609 return result.data();
4610}
Concrete visitor implementation for TEXT output.
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &input, const DocOptions &options)
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
static int nextUTF8CharPosition(const DString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:4517

References DString::at(), HtmlEntityMapper::convertCharEntitiesToUTF8(), createDocParser(), DString::data(), DString::empty(), HtmlEntityMapper::instance(), DString::left(), DString::length(), nextUTF8CharPosition(), parseCommentAsText(), TextStream::str(), DString::stripWhiteSpace(), and validatingParseDoc().

Referenced by addDirPrefix(), RequirementManager::addRequirement(), PageDefImpl::addSectionsToIndex(), DefinitionImpl::computeTooltip(), parseCommentAsText(), GroupDefImpl::setGroupTitleLocal(), PageDefImpl::setTitle(), and RequirementManager::writeRef().

◆ patternMatch()

bool patternMatch ( const FileInfo & fi,
const StringVector & patList )

Definition at line 4896 of file util.cpp.

4897{
4898 std::string elem;
4899 auto getter = [](std::string s) -> DString { return s; };
4900 return genericPatternMatch(fi,patList,elem,getter);
4901}

References genericPatternMatch(), and patternMatch().

Referenced by checkAndOpenFile(), patternMatch(), readDir(), and recodeString().

◆ processMarkup()

◆ projectLogoFile()

DString projectLogoFile ( )

Definition at line 2647 of file util.cpp.

2648{
2649 DString projectLogo = Config_getString(PROJECT_LOGO);
2650 if (!projectLogo.empty())
2651 {
2652 // check for optional width= and height= specifier
2653 if (size_t wi = projectLogo.find(" width="); wi!=DString::npos) // and strip them
2654 {
2655 projectLogo = projectLogo.left(wi);
2656 }
2657 if (size_t hi = projectLogo.find(" height="); hi!=DString::npos)
2658 {
2659 projectLogo = projectLogo.left(hi);
2660 }
2661 }
2662 //printf("projectlogo='%s'\n",qPrint(projectLogo));
2663 return projectLogo;
2664}

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

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

◆ projectLogoSize()

DString projectLogoSize ( )

Definition at line 2666 of file util.cpp.

2667{
2668 DString sizeVal;
2669 DString projectLogo = Config_getString(PROJECT_LOGO);
2670 if (!projectLogo.empty())
2671 {
2672 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> DString
2673 {
2674 DString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
2675 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
2676 {
2677 result="\""+result+"\"";
2678 }
2679 result.prepend(startMarker);
2680 return result;
2681 };
2682 // check for optional width= and height= specifier
2683 size_t wi = projectLogo.find(" width=");
2684 size_t hi = projectLogo.find(" height=");
2685 if (wi!=DString::npos && hi!=DString::npos)
2686 {
2687 if (wi<hi) // "... width=x height=y..."
2688 {
2689 sizeVal = extractDimension(" width=", wi+7, hi) + " "
2690 + extractDimension(" height=", hi+8, projectLogo.length());
2691 }
2692 else // "... height=y width=x..."
2693 {
2694 sizeVal = extractDimension(" height=", hi+8, wi) + " "
2695 + extractDimension(" width=", wi+7, projectLogo.length());
2696 }
2697 }
2698 else if (wi!=DString::npos) // ... width=x..."
2699 {
2700 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
2701 }
2702 else if (hi!=DString::npos) // ... height=x..."
2703 {
2704 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
2705 }
2706 }
2707 //printf("projectsize='%s'\n",qPrint(sizeVal));
2708 return sizeVal;
2709}
DString quoted() const
Definition dstring.h:357

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

Referenced by processMarkup(), projectLogoSize(), substituteHtmlKeywords(), and substituteLatexKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 5122 of file util.cpp.

5123{
5124 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5125 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
5126
5127 return (prot!=Protection::Private && prot!=Protection::Package) ||
5128 (prot==Protection::Private && extractPrivate) ||
5129 (prot==Protection::Package && extractPackage);
5130}

References Config_getBool, and protectionLevelVisible().

Referenced by MemberDefImpl::_computeLinkableInProject(), addClassAndNestedClasses(), computeClassRelations(), MemberDefImpl::hasDetailedDescription(), ClassDefImpl::internalInsertMember(), MemberDefImpl::isBriefSectionVisible(), ClassDefImpl::isLinkableInProject(), ClassDefImpl::isVisibleInHierarchy(), processMarkup(), protectionLevelVisible(), 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 4742 of file util.cpp.

4743{
4744 // try to open file
4745 FileInfo fi(fileName.str());
4746 if (!fi.exists()) return false;
4747 DString filterName = getFileFilter(fileName,isSourceCode);
4748 if (filterName.empty() || !filter)
4749 {
4750 std::ifstream f = Portable::openInputStream(fileName,true);
4751 if (!f.is_open())
4752 {
4753 err("could not open file {}\n",fileName);
4754 return false;
4755 }
4756 // read the file
4757 auto fileSize = fi.size();
4758 contents.resize(fileSize);
4759 f.read(contents.data(),fileSize);
4760 if (f.fail())
4761 {
4762 err("problems while reading file {}\n",fileName);
4763 return false;
4764 }
4765 }
4766 else
4767 {
4768 DString cmd=filterName+" \""+fileName+"\"";
4769 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
4770 FILE *f=Portable::popen(cmd,"r");
4771 if (!f)
4772 {
4773 err("could not execute filter {}\n",filterName);
4774 return false;
4775 }
4776 const int bufSize=4096;
4777 char buf[bufSize];
4778 int numRead = 0;
4779 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
4780 {
4781 //printf(">>>>>>>>Reading %d bytes\n",numRead);
4782 contents.append(buf,numRead);
4783 }
4785 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
4786 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
4787 }
4788
4789 if (contents.size()>=2 &&
4790 static_cast<uint8_t>(contents[0])==0xFF &&
4791 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
4792 ) // UCS-2LE encoded file
4793 {
4794 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
4795 }
4796 else if (contents.size()>=2 &&
4797 static_cast<uint8_t>(contents[0])==0xFE &&
4798 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
4799 ) // UCS-2BE encoded file
4800 {
4801 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
4802 }
4803 else if (contents.size()>=3 &&
4804 static_cast<uint8_t>(contents[0])==0xEF &&
4805 static_cast<uint8_t>(contents[1])==0xBB &&
4806 static_cast<uint8_t>(contents[2])==0xBF
4807 ) // UTF-8 encoded file
4808 {
4809 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
4810 }
4811 else // transcode according to the INPUT_ENCODING setting
4812 {
4813 // do character transcoding if needed.
4814 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
4815 }
4816
4817 filterCRLF(contents);
4818 return true;
4819}
@ FilterOutput
Definition debug.h:38
@ ExtCmd
Definition debug.h:36
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:77
FILE * popen(const DString &name, const DString &type)
Definition portable.cpp:479
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:659
int pclose(FILE *stream)
Definition portable.cpp:488
static void filterCRLF(std::string &contents)
Definition util.cpp:991
DString getFileFilter(const DString &name, bool isSourceCode)
Definition util.cpp:1052
static void transcodeCharacterBuffer(const DString &fileName, std::string &contents, const DString &inputEncoding, const DString &outputEncoding)
Definition util.cpp:4706
DString getEncoding(const FileInfo &fi)
Definition util.cpp:4903

References DString::empty(), err, FileInfo::exists(), Debug::ExtCmd, filterCRLF(), Debug::FilterOutput, getEncoding(), getFileFilter(), Portable::openInputStream(), Portable::pclose(), Portable::popen(), Debug::print(), readInputFile(), 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(), readInputFile(), DocbookDocVisitor::startMermaidFile(), LatexDocVisitor::startMermaidFile(), DocbookDocVisitor::startPlantUmlFile(), and LatexDocVisitor::startPlantUmlFile().

◆ recodeString()

◆ recognizeFixedForm()

bool recognizeFixedForm ( const DString & contents,
FortranFormat format )

Definition at line 5552 of file util.cpp.

5553{
5554 int column=0;
5555 bool skipLine=false;
5556
5557 if (format == FortranFormat::Fixed) return true;
5558 if (format == FortranFormat::Free) return false;
5559
5560 int tabSize=Config_getInt(TAB_SIZE);
5561 size_t sizCont = contents.length();
5562 for (size_t i=0;i<sizCont;i++)
5563 {
5564 column++;
5565
5566 switch(contents.at(i))
5567 {
5568 case '\n':
5569 column=0;
5570 skipLine=false;
5571 break;
5572 case '\t':
5573 column += tabSize-1;
5574 break;
5575 case ' ':
5576 break;
5577 case '\000':
5578 return false;
5579 case '#':
5580 skipLine=true;
5581 break;
5582 case 'C':
5583 case 'c':
5584 if (column==1)
5585 {
5586 return !keyWordsFortranC(contents.data()+i);
5587 }
5588 // fallthrough
5589 case '*':
5590 if (column==1) return true;
5591 if (skipLine) break;
5592 return false;
5593 case '!':
5594 if (column!=6) skipLine=true;
5595 break;
5596 default:
5597 if (skipLine) break;
5598 if (column>=7) return true;
5599 return false;
5600 }
5601 }
5602 return false;
5603}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:5532

References DString::at(), Config_getInt, DString::data(), Fixed, Free, keyWordsFortranC(), DString::length(), and recognizeFixedForm().

Referenced by convertCppComments(), FortranCodeParser::parseCode(), parseMain(), processMarkup(), recognizeFixedForm(), and setFileName().

◆ relativePathToRoot()

DString relativePathToRoot ( const DString & name)

Definition at line 2979 of file util.cpp.

2980{
2981 DString result;
2982 if (Config_getBool(CREATE_SUBDIRS))
2983 {
2984 if (name.empty())
2985 {
2986 return REL_PATH_TO_ROOT;
2987 }
2988 else if (size_t i = name.rfind('/'); i!=DString::npos)
2989 {
2990 result=REL_PATH_TO_ROOT;
2991 }
2992 }
2993 return result;
2994}
#define REL_PATH_TO_ROOT
Definition util.cpp:94

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

Referenced by addDirPrefix(), generateBriefDoc(), relativePathToRoot(), 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 114 of file util.cpp.

115{
116 std::string result;
117 if (str.empty()) return result;
118
119 // helper to check if the found delimiter starts with a colon
120 auto startsWithColon = [](const std::string &del)
121 {
122 for (size_t i=0;i<del.size();i++)
123 {
124 if (del[i]=='@') return false;
125 else if (del[i]==':') return true;
126 }
127 return false;
128 };
129
130 // helper to check if the found delimiter ends with a colon
131 auto endsWithColon = [](const std::string &del)
132 {
133 for (int i=static_cast<int>(del.size())-1;i>=0;i--)
134 {
135 if (del[i]=='@') return false;
136 else if (del[i]==':') return true;
137 }
138 return false;
139 };
140
141 static const reg::Ex re(R"([\s:]*@\d+[\s:]*)");
142 std::string s = str.str();
143 reg::Iterator iter(s,re);
145 size_t p=0;
146 size_t sl=s.length();
147 bool needsSeparator=false;
148 for ( ; iter!=end ; ++iter)
149 {
150 const auto &match = *iter;
151 size_t i = match.position();
152 if (i>p) // add non-matching prefix
153 {
154 if (needsSeparator) result+="::";
155 needsSeparator=false;
156 result+=s.substr(p,i-p);
157 }
158 std::string delim = match.str();
159 needsSeparator = needsSeparator || (startsWithColon(delim) && endsWithColon(delim));
160 p = match.position()+match.length();
161 }
162 if (p<sl) // add trailing remainder
163 {
164 if (needsSeparator) result+="::";
165 result+=s.substr(p);
166 }
167 return result;
168}

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

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

◆ removeLongPathMarker()

DString removeLongPathMarker ( const DString & path)

Definition at line 212 of file util.cpp.

213{
214 DString result;
215#if defined(_WIN32)
216 if (path.startsWith("//?/")) // strip leading "\\?\" part from path
217 {
218 result = path.mid(4);
219 }
220 else
221#endif
222 {
223 result = path;
224 }
225 return result;
226}

References DString::mid(), removeLongPathMarker(), and DString::startsWith().

Referenced by addDirPrefix(), computeCommonDirPrefix(), FileDefImpl::FileDefImpl(), FileNameLinkedMap::findFileDef(), DirDefImpl::mergeDirectoryInTree(), removeLongPathMarker(), FileNameLinkedMap::showFileDefMatches(), and stripFromPath().

◆ removeRedundantWhiteSpace()

DString removeRedundantWhiteSpace ( const DString & s)

Definition at line 458 of file util.cpp.

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

References CharAroundSpace::CharElem::after, CharAroundSpace::CharElem::before, CharAroundSpace::charMap, Config_getBool, constScope, DString::data(), disspace(), DString::empty(), g_charAroundSpace, isId(), DString::length(), operatorScope, removeRedundantWhiteSpace(), 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(), removeRedundantWhiteSpace(), resolveRef(), tempArgListToString(), and writeExceptionListImpl().

◆ replaceAnonymousScopes()

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

Definition at line 171 of file util.cpp.

172{
173 if (s.empty()) return s;
174 static const reg::Ex marker(R"(@\d+)");
175 std::string result = reg::replace(s.str(),marker,
176 !replacement.empty() ? replacement.data() : "__anonymous__");
177 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
178 return result;
179}
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:869

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

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

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

4997{
4998 if (str.empty()) return DString();
4999 std::string result;
5000 std::string s=str.str();
5001 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
5002 reg::Iterator it(s,re);
5004 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5005 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5006 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5007 size_t sl=s.length();
5008 size_t p=0;
5009 for (; it!=end ; ++it)
5010 {
5011 const auto &match = *it;
5012 size_t i = match.position();
5013 size_t l = match.length();
5014 if (i>p) result+=s.substr(p,i-p);
5015 std::string lumStr = match.str().substr(2);
5016#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5017 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5018 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5019
5020 double r = 0,g = 0,b = 0;
5021 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
5022 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
5023 pow(level/255.0,gamma/100.0),&r,&g,&b);
5024 int red = static_cast<int>(r*255.0);
5025 int green = static_cast<int>(g*255.0);
5026 int blue = static_cast<int>(b*255.0);
5027 char colStr[8];
5028 colStr[0]='#';
5029 colStr[1]=hex[red>>4];
5030 colStr[2]=hex[red&0xf];
5031 colStr[3]=hex[green>>4];
5032 colStr[4]=hex[green&0xf];
5033 colStr[5]=hex[blue>>4];
5034 colStr[6]=hex[blue&0xf];
5035 colStr[7]=0;
5036 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
5037 result+=colStr;
5038 p=i+l;
5039 }
5040 if (p<sl) result+=s.substr(p);
5041 return result;
5042}
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
Definition image.cpp:368
#define HEXTONUM(x)

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

Referenced by ResourceMgr::copyResourceAs(), fillColorStyleMaps(), HtmlGenerator::init(), recodeString(), replaceColorMarkers(), 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 2375 of file util.cpp.

2383{
2384 *resContext=nullptr;
2385
2386 DString linkRef=lr;
2387 if (lang==SrcLangExt::CSharp)
2388 {
2389 linkRef = mangleCSharpGenericName(linkRef);
2390 }
2391 DString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,false);
2392 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2393 const FileDef *fd = nullptr;
2394 const GroupDef *gd = nullptr;
2395 const PageDef *pd = nullptr;
2396 const ClassDef *cd = nullptr;
2397 const DirDef *dir = nullptr;
2398 const ConceptDef *cnd = nullptr;
2399 const ModuleDef *modd = nullptr;
2400 const NamespaceDef *nd = nullptr;
2401 const SectionInfo *si = nullptr;
2402 bool ambig = false;
2403 if (linkRef.empty()) // no reference name!
2404 {
2405 AUTO_TRACE_EXIT("no_ref");
2406 return false;
2407 }
2408 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2409 {
2410 gd = pd->getGroupDef();
2411 if (gd)
2412 {
2413 if (!pd->name().empty()) si=SectionManager::instance().find(pd->name());
2414 *resContext=gd;
2415 if (si) resAnchor = si->label();
2416 }
2417 else
2418 {
2419 *resContext=pd;
2420 }
2421 AUTO_TRACE_EXIT("page");
2422 return true;
2423 }
2424 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2425 {
2426 *resContext=si->definition();
2427 resAnchor = si->label();
2428 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2429 return true;
2430 }
2431 else if (!prefix.empty() && (si=SectionManager::instance().find(linkRef)))
2432 {
2433 *resContext=si->definition();
2434 resAnchor = si->label();
2435 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2436 return true;
2437 }
2438 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2439 {
2440 *resContext=pd;
2441 AUTO_TRACE_EXIT("example");
2442 return true;
2443 }
2444 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2445 {
2446 *resContext=gd;
2447 AUTO_TRACE_EXIT("group");
2448 return true;
2449 }
2450 else if ((fd=Doxygen::inputNameLinkedMap->findFileDef(linkRef,ambig)) // file link
2451 && fd->isLinkable())
2452 {
2453 *resContext=fd;
2454 AUTO_TRACE_EXIT("file");
2455 return true;
2456 }
2457 else if ((cd=getClass(linkRef))) // class link
2458 {
2459 *resContext=cd;
2460 resAnchor=cd->anchor();
2461 AUTO_TRACE_EXIT("class");
2462 return true;
2463 }
2464 else if (lang==SrcLangExt::Java &&
2465 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2466 {
2467 *resContext=cd;
2468 resAnchor=cd->anchor();
2469 AUTO_TRACE_EXIT("generic");
2470 return true;
2471 }
2472 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2473 {
2474 *resContext=cd;
2475 resAnchor=cd->anchor();
2476 AUTO_TRACE_EXIT("protocol");
2477 return true;
2478 }
2479 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2480 {
2481 *resContext=cnd;
2482 resAnchor=cnd->anchor();
2483 AUTO_TRACE_EXIT("concept");
2484 return true;
2485 }
2486 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2487 {
2488 *resContext=modd;
2489 resAnchor=modd->anchor();
2490 AUTO_TRACE_EXIT("module");
2491 return true;
2492 }
2493 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2494 {
2495 *resContext=nd;
2496 AUTO_TRACE_EXIT("namespace");
2497 return true;
2498 }
2499 else if ((dir=resolveDirLink(linkRef)) && dir->isLinkable())
2500 {
2501 *resContext=dir;
2502 AUTO_TRACE_EXIT("directory");
2503 return true;
2504 }
2505 else // probably a member reference
2506 {
2507 const MemberDef *md = nullptr;
2508 bool res = resolveRef(scName,lr,true,resContext,&md,lang);
2509 if (md) resAnchor=md->anchor();
2510 AUTO_TRACE_EXIT("member? res={}",res);
2511 return res;
2512 }
2513}
constexpr auto prefix
Definition anchor.cpp:44
virtual DString anchor() const =0
A model of a directory symbol.
Definition dirdef.h:110
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
A model of a group of symbols.
Definition groupdef.h:52
static ModuleManager & instance()
virtual const GroupDef * getGroupDef() const =0
Definition * definition() const
Definition section.h:77
DString label() const
Definition section.h:69
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:2075
DString stripTemplateSpecifiersFromScope(const DString &fullName, bool parentOnly, DString *pLastScopeStripped, DString scopeName, bool allowArtificial)
Definition util.cpp:3753
static const DirDef * resolveDirLink(const DString &linkRef)
Definition util.cpp:2357
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5984

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(), resolveLink(), resolveRef(), and stripTemplateSpecifiersFromScope().

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

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

2085{
2086 AUTO_TRACE("scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2087 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->name() : "", checkScope);
2088 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2089 DString tsName = name;
2090 //bool memberScopeFirst = tsName.find('#')!=-1;
2091 DString fullName = substitute(tsName,"#","::");
2092 if (fullName.find("anonymous_namespace{")==DString::npos)
2093 {
2094 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2095 }
2096 else
2097 {
2098 fullName = removeRedundantWhiteSpace(fullName);
2099 }
2100
2101 size_t templStartPos;
2102 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=DString::npos)
2103 {
2104 size_t templEndPos = fullName.rfind('>');
2105 if (templEndPos!=DString::npos)
2106 {
2107 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2108 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2109 }
2110 }
2111
2112 size_t bracePos = findParameterList(fullName);
2113 size_t endNamePos = bracePos!=DString::npos ? bracePos : fullName.length();
2114 size_t scopePos = fullName.rfind("::",endNamePos);
2115 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2116 ((scopePos!=DString::npos && scopePos>2) || // ::N::A
2117 tsName.startsWith("::") || // ::foo in local scope
2118 scName==nullptr // #foo in global scope
2119 );
2120 bool allowTypeOnly=false;
2121
2122 // default result values
2123 *resContext=nullptr;
2124 *resMember=nullptr;
2125
2126 if (bracePos==DString::npos) // simple name
2127 {
2128 // the following if() was commented out for releases in the range
2129 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2130 if (!inSeeBlock && scopePos==DString::npos && isLowerCase(tsName))
2131 { // link to lower case only name => do not try to autolink
2132 AUTO_TRACE_ADD("false");
2133 return false;
2134 }
2135
2136 ClassDef *cd=nullptr;
2137 NamespaceDef *nd=nullptr;
2138 ConceptDef *cnd=nullptr;
2139 ModuleDef *modd=nullptr;
2140
2141 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2142
2143 // check if this is a class or namespace reference
2144 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2145 {
2146 //printf("found scopeDef\n");
2147 if (cd) // scope matches that of a class
2148 {
2149 *resContext = cd;
2150 }
2151 else if (cnd)
2152 {
2153 *resContext = cnd;
2154 }
2155 else if (modd)
2156 {
2157 *resContext = modd;
2158 }
2159 else // scope matches that of a namespace
2160 {
2161 ASSERT(nd!=nullptr);
2162 *resContext = nd;
2163 }
2164 AUTO_TRACE_ADD("true");
2165 return true;
2166 }
2167 else if (scName==fullName || (!inSeeBlock && scopePos==DString::npos))
2168 // nothing to link => output plain text
2169 {
2170 //printf("found scName=%s fullName=%s scName==fullName=%d "
2171 // "inSeeBlock=%d scopePos=%d!\n",
2172 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
2173
2174 // at this point we have a bare word that is not a class or namespace
2175 // we should also allow typedefs or enums to be linked, but not for instance member
2176 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
2177 // 'Foo' class. So we use this flag as a filter.
2178 allowTypeOnly=true;
2179 }
2180
2181 // continue search...
2182 }
2183
2184 // extract userscope+name
2185 DString nameStr=fullName.left(endNamePos);
2186 if (explicitScope) nameStr=nameStr.mid(2);
2187
2188
2189 // extract arguments
2190 DString argsStr;
2191 if (bracePos!=DString::npos) argsStr=fullName.mid(bracePos);
2192
2193 // strip template specifier
2194 // TODO: match against the correct partial template instantiation
2195 size_t templPos = nameStr.find('<');
2196 bool tryUnspecializedVersion = false;
2197 if (templPos!=DString::npos && nameStr.find("operator")==DString::npos)
2198 {
2199 size_t endTemplPos=nameStr.rfind('>');
2200 if (endTemplPos!=DString::npos)
2201 {
2202 if (!lookForSpecialization)
2203 {
2204 nameStr=nameStr.left(templPos)+nameStr.mid(endTemplPos+1);
2205 }
2206 else
2207 {
2208 tryUnspecializedVersion = true;
2209 }
2210 }
2211 }
2212
2213 DString scopeStr=scName;
2214 if (!explicitScope && nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
2215 {
2216 nameStr=nameStr.mid(scopeStr.length()+2);
2217 }
2218
2219 const GroupDef *gd = nullptr;
2220 const ConceptDef *cnd = nullptr;
2221 const ModuleDef *modd = nullptr;
2222
2223 // check if nameStr is a member or global.
2224 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
2225 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
2226 GetDefInput input(scopeStr,nameStr,argsStr);
2227 input.forceEmptyScope = explicitScope;
2228 input.currentFile = currentFile;
2229 input.checkCV = true;
2230 GetDefResult result = getDefs(input);
2231 if (result.found)
2232 {
2233 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
2234 size_t np = nameStr.find("::");
2235 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
2236 !result.md->isStrongEnumValue() &&
2237 (!scopeStr.empty() || (np!=DString::npos && np>0)))
2238 {
2239 // we did find a member, but it is a global one while we were explicitly
2240 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
2241 // note we do need to support autolinking to "::symbol" hence the >0
2242 //printf("not global member!\n");
2243 *resContext=nullptr;
2244 *resMember=nullptr;
2245 AUTO_TRACE_ADD("false");
2246 return false;
2247 }
2248 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
2249 if (result.md)
2250 {
2251 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
2252 {
2253 *resMember=result.md;
2254 *resContext=result.md;
2255 }
2256 else // md is not a type, but we explicitly expect one
2257 {
2258 *resContext=nullptr;
2259 *resMember=nullptr;
2260 AUTO_TRACE_ADD("false");
2261 return false;
2262 }
2263 }
2264 else if (result.cd) *resContext=result.cd;
2265 else if (result.nd) *resContext=result.nd;
2266 else if (result.fd) *resContext=result.fd;
2267 else if (result.gd) *resContext=result.gd;
2268 else if (result.cnd) *resContext=result.cnd;
2269 else if (result.modd) *resContext=result.modd;
2270 else
2271 {
2272 *resContext=nullptr; *resMember=nullptr;
2273 AUTO_TRACE_ADD("false");
2274 return false;
2275 }
2276 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
2277 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
2278 AUTO_TRACE_ADD("true");
2279 return true;
2280 }
2281 else if (inSeeBlock && !nameStr.empty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
2282 { // group link
2283 *resContext=gd;
2284 AUTO_TRACE_ADD("true");
2285 return true;
2286 }
2287 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
2288 {
2289 *resContext=cnd;
2290 AUTO_TRACE_ADD("true");
2291 return true;
2292 }
2293 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
2294 {
2295 *resContext=modd;
2296 AUTO_TRACE_ADD("true");
2297 return true;
2298 }
2299 else if (tsName.find('.')!=DString::npos) // maybe a link to a file
2300 {
2301 bool ambig = false;
2302 const FileDef *fd=Doxygen::inputNameLinkedMap->findFileDef(tsName,ambig);
2303 if (fd && !ambig)
2304 {
2305 *resContext=fd;
2306 AUTO_TRACE_ADD("true");
2307 return true;
2308 }
2309 }
2310
2311 if (tryUnspecializedVersion)
2312 {
2313 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,false,nullptr,checkScope);
2314 AUTO_TRACE_ADD("{}",b);
2315 return b;
2316 }
2317 if (bracePos!=DString::npos) // Try without parameters as well, could be a constructor invocation
2318 {
2319 *resContext=getClass(fullName.left(bracePos));
2320 if (*resContext)
2321 {
2322 AUTO_TRACE_ADD("true");
2323 return true;
2324 }
2325 }
2326 //printf("resolveRef: %s not found!\n",qPrint(name));
2327
2328 AUTO_TRACE_ADD("false");
2329 return false;
2330}
virtual Definition * getOuterScope() const =0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:97
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:716
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:1933
static bool getScopeDefs(const DString &docScope, const DString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:2003
static bool isLowerCase(DString &s)
Definition util.cpp:2066

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

266{
267 AUTO_TRACE("context='{}' qualifiedName='{}'",context?context->name():"",qualifiedName);
268 DString result;
269 if (qualifiedName.empty())
270 {
271 AUTO_TRACE_EXIT("empty name");
272 return result;
273 }
274
275 const Definition *mContext=context;
276 if (typedefContext) *typedefContext=context;
277
278 // see if the qualified name has a scope part
279 if (qualifiedName.find('<')!=DString::npos)
280 {
281 AUTO_TRACE_EXIT("template");
282 return result;
283 }
284 size_t scopeIndex = qualifiedName.rfind("::");
285 DString resName=qualifiedName;
286 if (scopeIndex!=DString::npos) // strip scope part for the name
287 {
288 resName=qualifiedName.mid(scopeIndex+2);
289 if (resName.empty())
290 {
291 AUTO_TRACE_EXIT("invalid format");
292 return result;
293 }
294 }
295 const MemberDef *md=nullptr;
296 while (mContext && md==nullptr)
297 {
298 // step 1: get the right scope
299 const Definition *resScope=mContext;
300 if (scopeIndex!=DString::npos)
301 {
302 // split-off scope part
303 DString resScopeName = qualifiedName.left(scopeIndex);
304 //printf("resScopeName='%s'\n",qPrint(resScopeName));
305
306 // look-up scope in context
307 int is=0,ps=0,l=0;
308 while ((is=getScopeFragment(resScopeName,ps,&l))!=-1)
309 {
310 DString qualScopePart = resScopeName.mid(is,l);
311 DString tmp = resolveTypeDef(mContext,qualScopePart);
312 if (!tmp.empty()) qualScopePart=tmp;
313 resScope = resScope->findInnerCompound(qualScopePart);
314 //printf("qualScopePart='%s' resScope=%p\n",qPrint(qualScopePart),resScope);
315 if (resScope==nullptr) break;
316 ps=is+l;
317 }
318 }
319 AUTO_TRACE_ADD("resScope='{}' resName='{}'",resScope?resScope->name():"",resName);
320
321 // step 2: get the member
322 if (resScope) // no scope or scope found in the current context
323 {
324 //printf("scope found: %s, look for typedef %s\n",
325 // qPrint(resScope->qualifiedName()),qPrint(resName));
326 MemberNameLinkedMap *mnd=nullptr;
327 bool searchRelated=false;
328 bool mustBeRelated=false;
329 if (resScope->definitionType()==Definition::TypeClass)
330 {
332 }
333 else
334 {
336 searchRelated=true;
337 }
338 MemberName *mn=mnd->find(resName);
339 if (mn==0 && searchRelated)
340 {
342 mustBeRelated=true;
343 }
344 if (mn)
345 {
346 int minDist=-1;
347 for (const auto &tmd_p : *mn)
348 {
349 const MemberDef *tmd = tmd_p.get();
350 AUTO_TRACE_ADD("found candidate member '{}' isTypeDef={}' isRelated={} mustBeRelated={}",
351 tmd->name(),tmd->isTypedef(),tmd->isRelated(),mustBeRelated);
352 //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n",
353 // qPrint(tmd->name()),qPrint( resScope->name()),
354 // qPrint(tmd->getOuterScope()->name()), mContext);
355 if (tmd->isTypedef())
356 {
357 if (resScope==Doxygen::globalScope && tmd->isRelated() && mustBeRelated)
358 {
359 md = tmd;
360 }
361 else
362 {
363 SymbolResolver resolver;
364 int dist=resolver.isAccessibleFrom(resScope,tmd);
365 if (dist!=-1 && (md==nullptr || dist<minDist))
366 {
367 md = tmd;
368 minDist = dist;
369 }
370 }
371 }
372 }
373 }
374 }
375 mContext=mContext->getOuterScope();
376 }
377
378 AUTO_TRACE_ADD("md='{}'",md?md->name():"");
379 // step 3: get the member's type
380 if (md)
381 {
382 //printf(">>resolveTypeDef: Found typedef name '%s' in scope '%s' value='%s' args='%s'\n",
383 // qPrint(qualifiedName),qPrint(context->name()),qPrint(md->typeString()),qPrint(md->argsString())
384 // );
385 result=md->typeString();
386 DString args = md->argsString();
387 if (args.find(")(")!=DString::npos) // typedef of a function/member pointer
388 {
389 result+=args;
390 }
391 else if (args.find('[')!=DString::npos) // typedef of an array
392 {
393 result+=args;
394 }
395 if (typedefContext) *typedefContext=md->getOuterScope();
396 }
397 else
398 {
399 //printf(">>resolveTypeDef: Typedef '%s' not found in scope '%s'!\n",
400 // qPrint(qualifiedName),context ? qPrint(context->name()) : "<global>");
401 }
402 AUTO_TRACE_EXIT("result='{}'",result);
403 return result;
404}
virtual const Definition * findInnerCompound(const DString &name) const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
virtual DString argsString() const =0
virtual bool isRelated() const =0
virtual DString typeString() const =0
Ordered dictionary of MemberName objects.
Definition membername.h:63
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:264
int getScopeFragment(const DString &s, int p, int *l)
Definition util.cpp:3865

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

762{
763 size_t sl=scope.length();
764 size_t nl=name.length();
765 return (name==scope || // equal
766 (scope.right(nl)==name && // substring
767 sl>1+nl && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
768 )
769 );
770}

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

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

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

5619{
5620 if (s.empty()) return s;
5621
5622 // helper to find the end of a block
5623 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
5624 {
5625 char c = 0;
5626 while ((c=*p))
5627 {
5628 if (c==markerInfo.markerChar && dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
5629 {
5630 size_t len = markerInfo.endLen;
5631 bool negate = *(p+markerInfo.endLen)=='!';
5632 if (negate) len++;
5633 size_t blkNameLen = dstrlen(blk.name);
5634 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5635 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5636 {
5637 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5638 return p+len+blkNameLen+markerInfo.closeLen;
5639 }
5640 else // not the right marker id
5641 {
5642 p++;
5643 }
5644 }
5645 else // not and end marker
5646 {
5647 p++;
5648 }
5649 }
5650 return p;
5651 };
5652
5653 DString result;
5654 result.reserve(s.length());
5655 const char *p = s.data();
5656 char c = 0;
5657 while ((c=*p))
5658 {
5659 if (c==markerInfo.markerChar) // potential start of marker
5660 {
5661 if (dstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
5662 {
5663 bool found = false;
5664 size_t len = markerInfo.beginLen;
5665 bool negate = *(p+len)=='!';
5666 if (negate) len++;
5667 for (const auto &blk : blockList)
5668 {
5669 size_t blkNameLen = dstrlen(blk.name);
5670 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5671 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5672 {
5673 bool blockEnabled = blk.enabled!=negate;
5674 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5675 p+=len+blkNameLen+markerInfo.closeLen;
5676 if (!blockEnabled) // skip until the end of the block
5677 {
5678 //printf("skipping block\n");
5679 p=skipBlock(p,blk);
5680 }
5681 found=true;
5682 break;
5683 }
5684 }
5685 if (!found) // unknown marker id
5686 {
5687 result+=c;
5688 p++;
5689 }
5690 }
5691 else if (dstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
5692 {
5693 bool found = false;
5694 size_t len = markerInfo.endLen;
5695 bool negate = *(p+len)=='!';
5696 if (negate) len++;
5697 for (const auto &blk : blockList)
5698 {
5699 size_t blkNameLen = dstrlen(blk.name);
5700 if (dstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
5701 dstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
5702 {
5703 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
5704 p+=len+blkNameLen+markerInfo.closeLen;
5705 found=true;
5706 break;
5707 }
5708 }
5709 if (!found) // unknown marker id
5710 {
5711 result+=c;
5712 p++;
5713 }
5714 }
5715 else // not a start or end marker
5716 {
5717 result+=c;
5718 p++;
5719 }
5720 }
5721 else // not a marker character
5722 {
5723 result+=c;
5724 p++;
5725 }
5726 }
5727 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
5728 return result;
5729}
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:44

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

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

◆ showDate()

DString showDate ( const DString & fmt)

Definition at line 2634 of file util.cpp.

2635{
2636 // get the current date and time
2637 std::tm dat{};
2638 int specFormat=0;
2639 DString specDate = "";
2640 DString err = dateTimeFromString(specDate,dat,specFormat);
2641
2642 // do the conversion
2643 int usedFormat=0;
2644 return formatDateTime(fmt,dat,usedFormat);
2645}
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:174
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:133
Definition message.h:144

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

Referenced by processMarkup(), showDate(), substituteHtmlKeywords(), and substituteLatexKeywords().

◆ stackTrace()

void stackTrace ( )

Definition at line 4678 of file util.cpp.

4679{
4680#ifdef TRACINGSUPPORT
4681 void *backtraceFrames[128];
4682 int frameCount = backtrace(backtraceFrames, 128);
4683 const size_t cmdLen = 40960;
4684 static char cmd[cmdLen];
4685 char *p = cmd;
4686 p += snprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
4687 for (int x = 0; x < frameCount; x++)
4688 {
4689 p += snprintf(p,cmdLen,"%p ", backtraceFrames[x]);
4690 }
4691 fprintf(stderr,"========== STACKTRACE START ==============\n");
4692 if (FILE *fp = Portable::popen(cmd, "r"))
4693 {
4694 char resBuf[512];
4695 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
4696 {
4697 fwrite(resBuf, 1, len, stderr);
4698 }
4699 Portable::pclose(fp);
4700 }
4701 fprintf(stderr,"============ STACKTRACE END ==============\n");
4702 //fprintf(stderr,"%s\n", frameStrings[x]);
4703#endif
4704}

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

Referenced by recodeString(), and stackTrace().

◆ stripAnonymousNamespaceScope()

DString stripAnonymousNamespaceScope ( const DString & s)

Definition at line 183 of file util.cpp.

184{
185 int i=0,p=0,l=0;
186 DString newScope;
187 int sl = static_cast<int>(s.length());
188 while ((i=getScopeFragment(s,p,&l))!=-1)
189 {
190 //printf("Scope fragment %s\n",qPrint(s.mid(i,l)));
191 if (Doxygen::namespaceLinkedMap->find(s.left(i+l))!=nullptr)
192 {
193 if (s.at(i)!='@')
194 {
195 if (!newScope.empty()) newScope+="::";
196 newScope+=s.mid(i,l);
197 }
198 }
199 else if (i<sl)
200 {
201 if (!newScope.empty()) newScope+="::";
202 newScope+=s.right(sl-i);
203 goto done;
204 }
205 p=i+l;
206 }
207done:
208 //printf("stripAnonymousNamespaceScope('%s')='%s'\n",qPrint(s),qPrint(newScope));
209 return newScope;
210}

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

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

◆ stripExtension()

◆ stripExtensionGeneral()

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

260{
261 return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
262}
DString stripFromPath(const DString &path)
Definition util.cpp:251

References Config_getList, stripFromIncludePath(), and stripFromPath().

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

◆ stripFromPath()

◆ stripIndentation()

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

Definition at line 5134 of file util.cpp.

5135{
5136 if (s.empty()) return s; // empty string -> we're done
5137
5138 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
5139 // compute minimum indentation over all lines
5140 const char *p=s.data();
5141 char c=0;
5142 int indent=0;
5143 int minIndent=1000000; // "infinite"
5144 bool searchIndent=true;
5145 int tabSize=Config_getInt(TAB_SIZE);
5146 bool skipFirst = skipFirstLine;
5147 while ((c=*p++))
5148 {
5149 if (c=='\t') { indent+=tabSize - (indent%tabSize); }
5150 else if (c=='\n') { indent=0; searchIndent=true; skipFirst=false; }
5151 else if (c==' ') { indent++; }
5152 else if (searchIndent && !skipFirst)
5153 {
5154 searchIndent=false;
5155 if (indent<minIndent) minIndent=indent;
5156 }
5157 }
5158
5159 // no indent to remove -> we're done
5160 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
5161
5162 // remove minimum indentation for each line
5163 TextStream result;
5164 p=s.data();
5165 indent=0;
5166 skipFirst=skipFirstLine;
5167 while ((c=*p++))
5168 {
5169 if (c=='\n') // start of new line
5170 {
5171 indent=0;
5172 result << c;
5173 skipFirst=false;
5174 }
5175 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
5176 {
5177 if (c=='\t')
5178 {
5179 int newIndent = indent+tabSize-(indent%tabSize);
5180 int i=newIndent;
5181 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
5182 {
5183 result << ' ';
5184 i--;
5185 }
5186 indent=newIndent;
5187 }
5188 else // space
5189 {
5190 indent++;
5191 }
5192 }
5193 else if (c=='\\' && literal_at(p,"ilinebr "))
5194 // we also need to remove the indentation after a \ilinebr command at the end of a line
5195 {
5196 result << "\\ilinebr ";
5197 p+=8;
5198 int skipAmount=0;
5199 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
5200 if (skipAmount==minIndent)
5201 {
5202 p+=skipAmount; // remove the indent
5203 }
5204 }
5205 else if (c=='@' && literal_at(p,"ilinebr"))
5206 {
5207 result << "\\ilinebr";
5208 p+=7;
5209 }
5210 else // copy anything until the end of the line
5211 {
5212 result << c;
5213 }
5214 }
5215
5216 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
5217
5218 return result.str();
5219}

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

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

◆ stripIndentationVerbatim()

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

Definition at line 5223 of file util.cpp.

5224{
5225 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
5226 if (indentationLevel <= 0 || doc.empty()) return; // nothing to strip
5227
5228 // by stripping content the string will only become shorter so we write the results
5229 // back into the input string and then resize it at the end.
5230 char c = 0;
5231 const char *src = doc.data();
5232 char *dst = doc.rawData();
5233 bool insideIndent = !skipFirstLine; // skip the initial line from stripping
5234 size_t cnt = 0;
5235 if (!skipFirstLine) cnt = indentationLevel;
5236 while ((c=*src++))
5237 {
5238 // invariant: dst<=src
5239 switch(c)
5240 {
5241 case '\n':
5242 *dst++ = c;
5243 insideIndent = true;
5244 cnt = indentationLevel;
5245 break;
5246 case ' ':
5247 if (insideIndent)
5248 {
5249 if (cnt>0) // count down the spacing until the end of the indent
5250 {
5251 cnt--;
5252 }
5253 else // reached the end of the indent, start of the part of the line to keep
5254 {
5255 insideIndent = false;
5256 *dst++ = c;
5257 }
5258 }
5259 else // part after indent, copy to the output
5260 {
5261 *dst++ = c;
5262 }
5263 break;
5264 default:
5265 insideIndent = false;
5266 *dst++ = c;
5267 break;
5268 }
5269 }
5270 doc.resize(static_cast<uint32_t>(dst-doc.data()));
5271 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
5272}
void resize(size_t newlen)
Definition dstring.h:214
char * rawData()
Returns a writable pointer to the data.
Definition dstring.h:171

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

Referenced by processMarkup(), MemberDefImpl::setInitializer(), and stripIndentationVerbatim().

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

4224{
4225 if (s.empty()) return DString();
4226 const char *p = s.data();
4227
4228 // search for leading empty lines
4229 int i=0,li=-1,l=static_cast<int>(s.length());
4230 char c = 0;
4231 while ((c=*p))
4232 {
4233 if (c==' ' || c=='\t' || c=='\r') { i++; p++; }
4234 else if (c=='\\' && literal_at(p,"\\ilinebr")) { i+=8; li=i; p+=8; }
4235 else if (c=='\n') { i++; li=i; docLine++; p++; }
4236 else break;
4237 }
4238
4239 // search for trailing empty lines
4240 int b=l-1,bi=-1;
4241 p=s.data()+b;
4242 while (b>=0)
4243 {
4244 c=*p;
4245 if (c==' ' || c=='\t' || c=='\r') { b--; p--; }
4246 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
4247 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
4248 else if (c=='\n') { bi=b; b--; p--; }
4249 else break;
4250 }
4251
4252 // return whole string if no leading or trailing lines where found
4253 if (li==-1 && bi==-1) return s;
4254
4255 // return substring
4256 if (bi==-1) bi=l;
4257 if (li==-1) li=0;
4258 if (bi<=li) return DString(); // only empty lines
4259 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
4260 return s.mid(li,bi-li);
4261}

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

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

◆ stripPath()

DString stripPath ( const DString & s)

Definition at line 4157 of file util.cpp.

4158{
4159 DString result=s;
4160 if (size_t i=result.rfind('/'); i!=DString::npos)
4161 {
4162 result=result.mid(i+1);
4163 }
4164 if (size_t i=result.rfind('\\'); i!=DString::npos)
4165 {
4166 result=result.mid(i+1);
4167 }
4168 return result;
4169}

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

Referenced by addDirPrefix(), 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(), stripPath(), 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 3176 of file util.cpp.

3177{
3178 DString result = name;
3179 int l = static_cast<int>(result.length());
3180 int p = 0;
3181 bool done = false;
3182 bool skipBracket=false; // if brackets do not match properly, ignore them altogether
3183 int count=0;
3184 int round=0;
3185
3186 do
3187 {
3188 p=l-1; // start at the end of the string
3189 while (p>=0 && count>=0)
3190 {
3191 char c=result.at(p);
3192 switch (c)
3193 {
3194 case ':':
3195 // only exit in the case of ::
3196 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
3197 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
3198 {
3199 return result.right(l-p-1);
3200 }
3201 p--;
3202 break;
3203 case '>':
3204 if (skipBracket) // we don't care about brackets
3205 {
3206 p--;
3207 }
3208 else // count open/close brackets
3209 {
3210 if (p>0 && result.at(p-1)=='>') // skip >> operator
3211 {
3212 p-=2;
3213 break;
3214 }
3215 count=1;
3216 //printf("pos < = %d\n",p);
3217 p--;
3218 bool foundMatch=false;
3219 while (p>=0 && !foundMatch)
3220 {
3221 c=result.at(p--);
3222 switch (c)
3223 {
3224 case ')':
3225 round++;
3226 break;
3227 case '(':
3228 round--;
3229 break;
3230 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
3231 if (round==0) count++;
3232 break;
3233 case '<':
3234 if (round==0)
3235 {
3236 if (p>0)
3237 {
3238 if (result.at(p-1) == '<') // skip << operator
3239 {
3240 p--;
3241 break;
3242 }
3243 }
3244 count--;
3245 foundMatch = count==0;
3246 }
3247 break;
3248 default:
3249 //printf("c=%c count=%d\n",c,count);
3250 break;
3251 }
3252 }
3253 }
3254 //printf("pos > = %d\n",p+1);
3255 break;
3256 default:
3257 p--;
3258 }
3259 }
3260 done = count==0 || skipBracket; // reparse if brackets do not match
3261 skipBracket=true;
3262 }
3263 while (!done); // if < > unbalanced repeat ignoring them
3264 //printf("stripScope(%s)=%s\n",name,name);
3265 return name;
3266}

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

Referenced by DotClassGraph::addClass(), DocRef::DocRef(), getCanonicalTypeForIdentifier(), DefinitionImpl::Private::init(), DiagramItem::label(), stripScope(), 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 3753 of file util.cpp.

3758{
3759 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
3760 size_t i=fullName.find('<');
3761 if (i==DString::npos) return fullName;
3762 DString result;
3763 size_t p=0;
3764 size_t l=fullName.length();
3765 while (i!=DString::npos)
3766 {
3767 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
3768 size_t e=i+1;
3769 int count=1;
3770 int round=0;
3771 while (e<l && count>0)
3772 {
3773 char c=fullName.at(e++);
3774 switch (c)
3775 {
3776 case '(': round++; break;
3777 case ')': if (round>0) round--; break;
3778 case '<': if (round==0) count++; break;
3779 case '>': if (round==0) count--; break;
3780 default:
3781 break;
3782 }
3783 }
3784 size_t si = fullName.find("::",e);
3785
3786 if (parentOnly && si==DString::npos) break;
3787 // we only do the parent scope, so we stop here if needed
3788
3789 result+=fullName.mid(p,i-p);
3790 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
3791 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
3792 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
3793 {
3794 result+=fullName.mid(i,e-i);
3795 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
3796 }
3797 else if (pLastScopeStripped)
3798 {
3799 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
3800 *pLastScopeStripped=fullName.mid(i,e-i);
3801 }
3802 p=e;
3803 i=fullName.find('<',p);
3804 }
3805 result+=fullName.right(l-p);
3806 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
3807 //printf("end result=%s\n",qPrint(result));
3808 return result;
3809}
virtual bool isArtificial() const =0
DString mergeScopes(const DString &leftScope, const DString &rightScope)
Definition util.cpp:3820

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

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

◆ substituteKeywords()

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

Definition at line 2561 of file util.cpp.

2562{
2563 std::string substRes;
2564 int line = 1;
2565 const char *p = s.data();
2566 if (p)
2567 {
2568 // reserve some room for expansion
2569 substRes.reserve(s.length()+1024);
2570 char c = 0;
2571 while ((c=*p))
2572 {
2573 bool found = false;
2574 if (c=='$')
2575 {
2576 for (const auto &kw : keywords)
2577 {
2578 size_t keyLen = dstrlen(kw.keyword);
2579 if (dstrncmp(p,kw.keyword,keyLen)==0)
2580 {
2581 const char *startArg = p+keyLen;
2582 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2583 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
2584 if (expectParam && *startArg=='(') // $key(value)
2585 {
2586 size_t j=1;
2587 const char *endArg = nullptr;
2588 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
2589 if (c==')') endArg=startArg+j;
2590 if (endArg)
2591 {
2592 DString value = DString(startArg+1).left(endArg-startArg-1);
2593 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2594 substRes+=getValue(value).str();
2595 p=endArg+1;
2596 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
2597 }
2598 else
2599 {
2600 //printf("missing argument\n");
2601 warn(file,line,"Missing argument for '{}'",kw.keyword);
2602 p+=keyLen;
2603 }
2604 }
2605 else if (!expectParam) // $key
2606 {
2607 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
2608 substRes+=getValue().str();
2609 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
2610 p+=keyLen;
2611 }
2612 else
2613 {
2614 //printf("%s %d Expected arguments, none specified '%s'\n",qPrint(file), line, qPrint(kw.keyword));
2615 warn(file,line,"Expected arguments for '{}' but none were specified",kw.keyword);
2616 p+=keyLen;
2617 }
2618 found = true;
2619 break;
2620 }
2621 }
2622 }
2623 if (!found) // copy
2624 {
2625 if (c=='\n') line++;
2626 substRes+=c;
2627 p++;
2628 }
2629 }
2630 }
2631 return substRes;
2632}

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

Referenced by substituteHtmlKeywords(), substituteKeywords(), 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 3591 of file util.cpp.

3595{
3596 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : DString());
3597 if (formalArgs.empty()) return nm;
3598 DString result;
3599
3600 static const reg::Ex re(R"(\a\w*)");
3601 std::string name = nm.str();
3602 reg::Iterator it(name,re);
3604 size_t p=0;
3605
3606 for (; it!=end ; ++it)
3607 {
3608 const auto &match = *it;
3609 size_t i = match.position();
3610 size_t l = match.length();
3611 if (i>p) result += name.substr(p,i-p);
3612 DString n(match.str());
3614 if (actualArgs)
3615 {
3616 actIt = actualArgs->begin();
3617 }
3618 //printf(": name=%s\n",qPrint(name));
3619
3620 // if n is a template argument, then we substitute it
3621 // for its template instance argument.
3622 bool found=false;
3623 for (auto formIt = formalArgs.begin();
3624 formIt!=formalArgs.end() && !found;
3625 ++formIt
3626 )
3627 {
3628 Argument formArg = *formIt;
3629 Argument actArg;
3630 if (actualArgs && actIt!=actualArgs->end())
3631 {
3632 actArg = *actIt;
3633 }
3634 if (formArg.type.startsWith("class ") && formArg.name.empty())
3635 {
3636 formArg.name = formArg.type.mid(6);
3637 formArg.type = "class";
3638 }
3639 else if (formArg.type.startsWith("typename ") && formArg.name.empty())
3640 {
3641 formArg.name = formArg.type.mid(9);
3642 formArg.type = "typename";
3643 }
3644 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
3645 {
3646 formArg.name += "...";
3647 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
3648 }
3649 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
3650 {
3651 formArg.name += "...";
3652 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
3653 }
3654 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
3655 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
3656 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
3657 {
3658 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.empty()) // base class is a template argument
3659 {
3660 static constexpr auto hasRecursion = [](const DString &prefix,const DString &nameArg,const DString &subst) -> bool
3661 {
3662 size_t ii=0;
3663 size_t pp=0;
3664
3665 ii = subst.find('<');
3666 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
3667 if (ii!=DString::npos && prefix.length()>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
3668 {
3669 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
3670 }
3671
3672 while ((ii=subst.find(nameArg,pp))!=DString::npos)
3673 {
3674 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
3675 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
3676 if (beforeNonWord && afterNonWord)
3677 {
3678 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
3679 }
3680 pp=ii+nameArg.length();
3681 }
3682 return false;
3683 };
3684 // replace formal argument with the actual argument of the instance
3685 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
3686 if (!hasRecursion(result,n,actArg.type))
3687 // the scope guard is to prevent recursive lockup for
3688 // template<class A> class C : public<A::T>,
3689 // where A::T would become A::T::T here,
3690 // since n==A and actArg->type==A::T
3691 // see bug595833 for an example
3692 //
3693 // Also prevent recursive substitution if n is part of actArg.type, i.e.
3694 // n='A' in argType='S< A >' would produce 'S< S< A > >'
3695 {
3696 if (actArg.name.empty())
3697 {
3698 result += actArg.type;
3699 }
3700 else
3701 // for case where the actual arg is something like "unsigned int"
3702 // the "int" part is in actArg->name.
3703 {
3704 result += actArg.type+" "+actArg.name;
3705 }
3706 found=true;
3707 }
3708 }
3709 else if (formArg.name==n &&
3710 (actualArgs==nullptr || actIt==actualArgs->end()) &&
3711 !formArg.defval.empty() &&
3712 formArg.defval!=nm /* to prevent recursion */
3713 )
3714 {
3715 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
3716 found=true;
3717 }
3718 }
3719 else if (formArg.name==n &&
3720 (actualArgs==nullptr || actIt==actualArgs->end()) &&
3721 !formArg.defval.empty() &&
3722 formArg.defval!=nm /* to prevent recursion */
3723 )
3724 {
3725 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
3726 found=true;
3727 }
3728 if (actualArgs && actIt!=actualArgs->end())
3729 {
3730 actIt++;
3731 }
3732 }
3733 if (!found)
3734 {
3735 result += n;
3736 }
3737 p=i+l;
3738 }
3739 result+=name.substr(p);
3740 result=result.simplifyWhiteSpace();
3741 AUTO_TRACE_EXIT("result={}",result);
3742 return result.stripWhiteSpace();
3743}
typename Vec::const_iterator const_iterator
Definition arguments.h:69
DString substituteTemplateArgumentsInString(const DString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:3591

References argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, ArgumentList::begin(), Argument::defval, DString::DString(), 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 935 of file util.cpp.

936{
937 DString result;
938 if (al.empty()) return result;
939 result="<";
940 bool first=true;
941 for (const auto &a : al)
942 {
943 if (a.defval.empty() || includeDefault)
944 {
945 if (!first) result+=", ";
946 if (!a.name.empty()) // add template argument name
947 {
948 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
949 {
950 result+=a.type+" ";
951 }
952 result+=a.name;
953 }
954 else // extract name from type
955 {
956 int i = static_cast<int>(a.type.length())-1;
957 while (i>=0 && isId(a.type.at(i))) i--;
958 if (i>0)
959 {
960 result+=a.type.right(a.type.length()-i-1);
961 if (a.type.find("...")!=DString::npos)
962 {
963 result+="...";
964 }
965 }
966 else // nothing found -> take whole name
967 {
968 result+=a.type;
969 }
970 }
971 if (!a.typeConstraint.empty() && lang==SrcLangExt::Java)
972 {
973 result+=" extends "; // TODO: now Java specific, C# has where...
974 result+=a.typeConstraint;
975 }
976 first=false;
977 }
978 }
979 result+=">";
980 return removeRedundantWhiteSpace(result);
981}

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

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

◆ transcodeCharacterStringToUTF8()

bool transcodeCharacterStringToUTF8 ( std::string & input,
const char * inputEncoding )

Definition at line 1086 of file util.cpp.

1087{
1088 const char *outputEncoding = "UTF-8";
1089 if (inputEncoding==nullptr || dstricmp(inputEncoding,outputEncoding)==0) return true;
1090 size_t inputSize=input.length();
1091 size_t outputSize=inputSize*4;
1092 DString output(outputSize, DString::ExplicitSize);
1093 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1094 if (cd==reinterpret_cast<void *>(-1))
1095 {
1096 return false;
1097 }
1098 bool ok=true;
1099 size_t iLeft=inputSize;
1100 size_t oLeft=outputSize;
1101 const char *inputPtr = input.data();
1102 char *outputPtr = output.rawData();
1103 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1104 {
1105 outputSize-=static_cast<int>(oLeft);
1106 output.resize(outputSize);
1107 output.at(outputSize)='\0';
1108 // replace input
1109 input=output.str();
1110 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1111 }
1112 else
1113 {
1114 ok=false;
1115 }
1117 return ok;
1118}
@ ExplicitSize
Definition dstring.h:136
int dstricmp(const char *s1, const char *s2)
Definition dstring.cpp:439
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)

References DString::at(), dstricmp(), DString::ExplicitSize, portable_iconv(), portable_iconv_close(), portable_iconv_open(), DString::rawData(), DString::resize(), DString::str(), and transcodeCharacterStringToUTF8().

Referenced by addDirPrefix(), LayoutDocManager::parse(), readCodeFragment(), and transcodeCharacterStringToUTF8().

◆ unescapeCharsInString()

DString unescapeCharsInString ( const DString & s)

Definition at line 2842 of file util.cpp.

2843{
2844 if (s.empty()) return s;
2845 bool caseSenseNames = useCaseSenseNames();
2846 DString result;
2847 result.reserve(s.length());
2848 const char *p = s.data();
2849 if (p)
2850 {
2851 char c = 0;
2852 while ((c=*p++))
2853 {
2854 if (c=='_') // 2 or 3 character escape
2855 {
2856 switch (*p)
2857 {
2858 case '_': result+=c; p++; break; // __ -> '_'
2859 case '1': result+=':'; p++; break; // _1 -> ':'
2860 case '2': result+='/'; p++; break; // _2 -> '/'
2861 case '3': result+='<'; p++; break; // _3 -> '<'
2862 case '4': result+='>'; p++; break; // _4 -> '>'
2863 case '5': result+='*'; p++; break; // _5 -> '*'
2864 case '6': result+='&'; p++; break; // _6 -> '&'
2865 case '7': result+='|'; p++; break; // _7 -> '|'
2866 case '8': result+='.'; p++; break; // _8 -> '.'
2867 case '9': result+='!'; p++; break; // _9 -> '!'
2868 case '0': // 3 character escape
2869 switch (*(p+1))
2870 {
2871 case '0': result+=','; p+=2; break; // _00 -> ','
2872 case '1': result+=' '; p+=2; break; // _01 -> ' '
2873 case '2': result+='{'; p+=2; break; // _02 -> '{'
2874 case '3': result+='}'; p+=2; break; // _03 -> '}'
2875 case '4': result+='?'; p+=2; break; // _04 -> '?'
2876 case '5': result+='^'; p+=2; break; // _05 -> '^'
2877 case '6': result+='%'; p+=2; break; // _06 -> '%'
2878 case '7': result+='('; p+=2; break; // _07 -> '('
2879 case '8': result+=')'; p+=2; break; // _08 -> ')'
2880 case '9': result+='+'; p+=2; break; // _09 -> '+'
2881 case 'a': result+='='; p+=2; break; // _0a -> '='
2882 case 'b': result+='$'; p+=2; break; // _0b -> '$'
2883 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
2884 case 'd': result+='@'; p+=2; break; // _0d -> '@'
2885 case 'e': result+=']'; p+=2; break; // _0e -> ']'
2886 case 'f': result+='['; p+=2; break; // _0f -> '['
2887 case 'g': result+='#'; p+=2; break; // _0g -> '#'
2888 case 'h': result+='"'; p+=2; break; // _0h -> '"'
2889 case 'i': result+='~'; p+=2; break; // _0i -> '~'
2890 case 'j': result+='\''; p+=2; break;// _0j -> '\'
2891 case 'k': result+=';'; p+=2; break; // _0k -> ';'
2892 case 'l': result+='`'; p+=2; break; // _0l -> '`'
2893 default: // unknown escape, just pass underscore character as-is
2894 result+=c;
2895 break;
2896 }
2897 break;
2898 default:
2899 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
2900 {
2901 result+=static_cast<char>(toupper(*p));
2902 p++;
2903 }
2904 else // unknown escape, pass underscore character as-is
2905 {
2906 result+=c;
2907 }
2908 break;
2909 }
2910 }
2911 else // normal character; pass as is
2912 {
2913 result+=c;
2914 }
2915 }
2916 }
2917 return result;
2918}

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

Referenced by unescapeCharsInString().

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 5951 of file util.cpp.

5952{
5953 if (s)
5954 {
5955 const int tabSize = Config_getInt(TAB_SIZE);
5956 char c;
5957 while ((c=*s++))
5958 {
5959 switch(c)
5960 {
5961 case '\t': col+=tabSize - (col%tabSize);
5962 break;
5963 case '\n': col=0;
5964 break;
5965 default:
5966 col++;
5967 if (c<0) // multi-byte character
5968 {
5969 int numBytes = getUTF8CharNumBytes(c);
5970 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
5971 if (c==0) return col; // end of string half way a multibyte char
5972 }
5973 break;
5974 }
5975 }
5976 }
5977 return col;
5978}

References Config_getInt, getUTF8CharNumBytes(), and updateColumnCount().

Referenced by HtmlCodeGenerator::codify(), LatexCodeGenerator::codify(), ManCodeGenerator::codify(), RTFCodeGenerator::codify(), processMarkup(), updateColumnCount(), writeDocbookCodeString(), and writeXMLCodeString().

◆ updateLanguageMapping()

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

Definition at line 4299 of file util.cpp.

4300{
4301 DString langName = language.lower();
4302 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
4303 [&langName](const auto &info) { return info.langName==langName; });
4304 if (it1 == g_lang2extMap.end()) return false;
4305
4306 // found the language
4307 SrcLangExt parserId = it1->parserId;
4308 DString extName = extension.lower();
4309 if (extName.empty()) return false;
4310 if (extName.at(0)!='.') extName.prepend(".");
4311 auto it2 = g_extLookup.find(extName.str());
4312 if (it2!=g_extLookup.end())
4313 {
4314 g_extLookup.erase(it2); // language was already register for this ext
4315 }
4316 //printf("registering extension %s\n",qPrint(extName));
4317 g_extLookup.emplace(extName.str(),parserId);
4318 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
4319 {
4320 err("Failed to assign extension {} to parser {} for language {}\n",
4321 extName.data(),it1->parserName,language);
4322 }
4323 else
4324 {
4325 //msg("Registered extension {} to language parser {}...\n",
4326 // extName,language);
4327 }
4328 return true;
4329}
SrcLangExt
Definition types.h:207

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

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

◆ useCaseSenseNames()

bool useCaseSenseNames ( )

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

Definition at line 2746 of file util.cpp.

2747{
2748 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
2749
2750 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
2751 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
2753}
#define Config_getEnum(name)
Definition config.h:35
bool fileSystemIsCaseSensitive()
Definition portable.cpp:470

References Config_getEnum, Portable::fileSystemIsCaseSensitive(), and useCaseSenseNames().

Referenced by escapeCharsInString(), genericPatternMatch(), FileNameFn::searchKey(), unescapeCharsInString(), and useCaseSenseNames().

◆ writeExamples()

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

Definition at line 836 of file util.cpp.

837{
838 auto replaceFunc = [&list,&ol](size_t entryIndex)
839 {
840 const auto &e = list[entryIndex];
845 // link for Html / man
846 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
847 ol.writeObjectLink(DString(),e.file,e.anchor,e.name);
849
853 // link for Latex / pdf with anchor because the sources
854 // are not hyperlinked (not possible with a verbatim environment).
855 ol.writeObjectLink(DString(),e.file,DString(),e.name);
857 };
858
859 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
860
861 ol.writeString(".");
862}
void disable(OutputType o)
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:439
void writeString(const DString &text)
Definition outputlist.h:411
void pushGeneratorState()
void popGeneratorState()
virtual DString trWriteList(int numEntries)=0
Translator * theTranslator
Definition language.cpp:71
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
Definition util.cpp:785

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

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

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

6024{
6025 DString fileName = baseName + md5str(content.view()) + extension;
6026 { // ==== start atomic section
6027 std::lock_guard lock(writeFileContents_lock);
6028 auto it=writeFileContents_set.find(fileName.str());
6029 exists = it!=writeFileContents_set.end();
6030 if (!exists)
6031 {
6032 writeFileContents_set.insert(fileName.str());
6033 if (auto file = Portable::openOutputStream(fileName); file.is_open())
6034 {
6035 file.write( content.data(), content.length() );
6036 file.close();
6037 }
6038 else
6039 {
6040 err("Could not open file {} for writing\n",fileName);
6041 return DString();
6042 }
6043 }
6044 } // ==== end atomic section
6045 return fileName;
6046}
static std::mutex writeFileContents_lock
Definition util.cpp:6020

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

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()(), RTFDocVisitor::operator()(), and writeInlineGraph().

◆ writeMarkerList() [1/2]

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

Definition at line 808 of file util.cpp.

810{
811 DString result;
812 static const reg::Ex marker(R"(@(\d+))");
813 reg::Iterator it(markerText,marker);
815 size_t index=0;
816 for ( ; it!=end ; ++it)
817 {
818 const auto &match = *it;
819 size_t newIndex = match.position();
820 size_t matchLen = match.length();
821 result += markerText.substr(index,newIndex-index);
822 unsigned long entryIndex = std::stoul(match[1].str());
823 if (entryIndex<static_cast<unsigned long>(numMarkers))
824 {
825 result+=replaceFunc(entryIndex);
826 }
827 index=newIndex+matchLen;
828 }
829 if (index<markerText.size())
830 {
831 result += markerText.substr(index);
832 }
833 return result;
834}

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

◆ writeMarkerList() [2/2]

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

Definition at line 785 of file util.cpp.

787{
788 static const reg::Ex marker(R"(@(\d+))");
789 reg::Iterator it(markerText,marker);
791 size_t index=0;
792 for ( ; it!=end ; ++it)
793 {
794 const auto &match = *it;
795 size_t newIndex = match.position();
796 size_t matchLen = match.length();
797 ol.parseText(markerText.substr(index,newIndex-index));
798 unsigned long entryIndex = std::stoul(match[1].str());
799 if (entryIndex<static_cast<unsigned long>(numMarkers))
800 {
801 replaceFunc(entryIndex);
802 }
803 index=newIndex+matchLen;
804 }
805 ol.parseText(markerText.substr(index));
806}
void parseText(const DString &textStr)

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

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

◆ writeTypeConstraints()

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

Definition at line 4651 of file util.cpp.

4652{
4653 if (al.empty()) return;
4655 for (const Argument &a : al)
4656 {
4658 ol.parseText(a.name);
4659 ol.endConstraintParam();
4661 linkifyText(TextGeneratorOLImpl(ol),a.type,LinkifyTextOptions().setScope(d));
4662 ol.endConstraintType();
4664 ol.generateDoc(d->docFile(),
4665 d->docLine(),
4666 d,
4667 nullptr,
4668 a.docs,
4669 DocOptions()
4670 .setIndexWords(true));
4671 ol.endConstraintDocs();
4672 }
4673 ol.endConstraintList();
4674}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:714
void endConstraintList()
Definition outputlist.h:720
void startConstraintList(const DString &header)
Definition outputlist.h:706
void startConstraintParam()
Definition outputlist.h:708
void startConstraintDocs()
Definition outputlist.h:716
void startConstraintType()
Definition outputlist.h:712
void endConstraintDocs()
Definition outputlist.h:718
void endConstraintParam()
Definition outputlist.h:710
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
TextGeneratorOLImpl(OutputList &ol)
virtual DString trTypeConstraints()=0
void linkifyText(const TextGeneratorIntf &out, const DString &text, const LinkifyTextOptions &options)

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(), TextGeneratorOLImpl::TextGeneratorOLImpl(), theTranslator, Translator::trTypeConstraints(), and writeTypeConstraints().

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